Message ID | 20191007055939.17093-5-takahiro.akashi@linaro.org |
---|---|
State | Accepted, archived |
Commit | 867400677cda0fac4a411f1549fe3a61bb5ed172 |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | efi_loader: disk: install FILE_SYSTEM_PROTOCOL to whole disk | expand |
The patch commit 867400677cda0fac4a411f1549fe3a61bb5ed172 efi_loader: disk: install FILE_SYSTEM_PROTOCOL only if available breaks booting my Pine A64 LTS board via iPXE and GRUB. But I assume this is not at the base of the problem. My iSCSI drive is partitioned like this: Device Boot Start End Sectors Size Id Type pine-a64-lts1 2048 194559 192512 94M ef EFI vfat pine-a64-lts2 * 194560 2148351 1953792 954M 83 Linux ext2 pine-a64-lts3 2148352 25585663 23437312 11.2G 83 Linux ext4 pine-a64-lts4 25585664 67106815 41521152 19.8G 83 Linux ext4 Looking at the debug output below the following questions arise: Why is ext2 not recognized as a file system? Why is the system crashing when trying to read 1024 blocks from the ext4 partition? .config contains CONFIG_FS_EXT4=y EFI: efi_bl_bind: handle 00000000b9f94560, interface 00000000b8e9f7f8 EFI: efi_bl_read: read 'efiblk#0', from block 0, 1 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: 0 returned by io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: efi_bl_read: r = 0 EFI: efi_bl_bind: block device 'efiblk#0' created EFI: efi_bl_read: read 'efiblk#0', from block 2048, 1 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: 0 returned by io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: efi_bl_read: r = 0 lib/efi_loader/efi_disk.c(279) efi_fs_exists: 0 returned by fs_set_blk_dev_with_part(desc, 1) EFI: efi_bl_read: read 'efiblk#0', from block 194560, 1 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: 0 returned by io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: efi_bl_read: r = 0 EFI: efi_bl_read: read 'efiblk#0', from block 195584, 1024 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: 0 returned by io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: efi_bl_read: r = 0 ** Unrecognized filesystem type ** lib/efi_loader/efi_disk.c(279) efi_fs_exists: -1 returned by fs_set_blk_dev_with_part(desc, 2) EFI: efi_bl_read: read 'efiblk#0', from block 2148352, 1 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: 0 returned by io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) EFI: efi_bl_read: r = 0 EFI: efi_bl_read: read 'efiblk#0', from block 2149376, 1024 blocks EFI: Call: io->read_blocks( io, io->media->media_id, (u64)blknr, (efi_uintn_t)blkcnt * (efi_uintn_t)io->media->block_size, buffer) "Synchronous Abort" handler, esr 0x02000000 elr: ffffffff8c0a6028 lr : ffffffff8c0a6000 (reloc) elr: 0000000000000028 lr : 0000000000000000 x0 : 00000000b9f918f8 x1 : 00000000b9f31004 x2 : 00000000b9f918f8 x3 : 00000000b9f918f8 x4 : 00000000b9f918f8 x5 : 00000000b9f918f8 x6 : 00000000b9f918f8 x7 : 0000000000000000 x8 : 00000000b9f918f8 x9 : 00000000b8ea1038 x10: 0000000000000001 x11: 0000000019100bb0 x12: 0000000000000000 x13: 0000000000000001 x14: 0000000000000002 x15: 0000000000000003 x16: 00000000000000c8 x17: 00000000b9f918f8 x18: 00000000b9f31c30 x19: 00000000b9f918f8 x20: 00000000b8e9ddd0 x21: 00000000b8e99000 x22: 00000000b9f31008 x23: 00000000b9f3105a x24: 00000000b9f31068 x25: 00000000b9f31110 x26: 0000000000000000 x27: 0000000000000000 x28: 0000000000000000 x29: 00000000b9f31160 Code: ea000011 ea000000 ea000013 eafffffe (e3a00001) Looks like we jumped into nowhere land: All code ======== 0: ea000011 ands x17, x0, x0 4: ea000000 ands x0, x0, x0 8: ea000013 ands x19, x0, x0 c: eafffffe bics x30, xzr, xzr, ror #63 10:* e3a00001 .inst 0xe3a00001 ; undefined <-- trapping instruction Best regards Heinrich
On Tue, Oct 22, 2019 at 10:29:09PM +0200, Heinrich Schuchardt wrote: > The patch > > commit 867400677cda0fac4a411f1549fe3a61bb5ed172 > efi_loader: disk: install FILE_SYSTEM_PROTOCOL only if available > > breaks booting my Pine A64 LTS board via iPXE and GRUB. But I assume > this is not at the base of the problem. > > My iSCSI drive is partitioned like this: > > Device Boot Start End Sectors Size Id Type > pine-a64-lts1 2048 194559 192512 94M ef EFI vfat > pine-a64-lts2 * 194560 2148351 1953792 954M 83 Linux ext2 > pine-a64-lts3 2148352 25585663 23437312 11.2G 83 Linux ext4 > pine-a64-lts4 25585664 67106815 41521152 19.8G 83 Linux ext4 > > Looking at the debug output below the following questions arise: > > Why is ext2 not recognized as a file system? > Why is the system crashing when trying to read 1024 blocks from the ext4 > partition? Try the workaround attached below. It seems that some fields, particularly log2blksz, in blk_dev held by ext_fs(of ext_filesystem in fs/ext4/ext4fs.c) are not initialized. I think that ext4's initialization code should be reworked. -Takahiro Akashi diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 861fcaf3747f..0792e53b32c6 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -337,6 +337,12 @@ static efi_status_t efi_disk_add_dev( diskobj->dp); if (ret != EFI_SUCCESS) return ret; + if (!part) { + char buf[10]; + + sprintf(buf, "%d:%d", dev_index, part); + fs_set_blk_dev(if_typename, buf, FS_TYPE_ANY); + } if (part >= 1 && efi_fs_exists(desc, part)) { diskobj->volume = efi_simple_file_system(desc, part, diskobj->dp);
On 10/23/19 12:30 PM, AKASHI Takahiro wrote: > On Tue, Oct 22, 2019 at 10:29:09PM +0200, Heinrich Schuchardt wrote: >> The patch >> >> commit 867400677cda0fac4a411f1549fe3a61bb5ed172 >> efi_loader: disk: install FILE_SYSTEM_PROTOCOL only if available >> >> breaks booting my Pine A64 LTS board via iPXE and GRUB. But I assume >> this is not at the base of the problem. >> >> My iSCSI drive is partitioned like this: >> >> Device Boot Start End Sectors Size Id Type >> pine-a64-lts1 2048 194559 192512 94M ef EFI vfat >> pine-a64-lts2 * 194560 2148351 1953792 954M 83 Linux ext2 >> pine-a64-lts3 2148352 25585663 23437312 11.2G 83 Linux ext4 >> pine-a64-lts4 25585664 67106815 41521152 19.8G 83 Linux ext4 >> >> Looking at the debug output below the following questions arise: >> >> Why is ext2 not recognized as a file system? >> Why is the system crashing when trying to read 1024 blocks from the ext4 >> partition? > > Try the workaround attached below. > It seems that some fields, particularly log2blksz, in blk_dev held by > ext_fs(of ext_filesystem in fs/ext4/ext4fs.c) are not initialized. > > I think that ext4's initialization code should be reworked. Thanks for looking into this. The error is in efi_bl_bind() (lib/efi_driver/efi_block_device.c). I missed to use the block size of the block IO protocol to initialize desc->blksz and desc->log2blksz. Our FAT driver takes the sector size from the boot sector in get_fs_info() (fs/fat/fat.c) and ignores the block descriptor which will lead to errors if the logical sector size does not match the physical sector size. Best regards Heinrich
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 9007a5f77f3d..861fcaf3747f 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -9,6 +9,7 @@ #include <blk.h> #include <dm.h> #include <efi_loader.h> +#include <fs.h> #include <part.h> #include <malloc.h> @@ -262,6 +263,27 @@ efi_fs_from_path(struct efi_device_path *full_path) return handler->protocol_interface; } +/** + * efi_fs_exists() - check if a partition bears a file system + * + * @desc: block device descriptor + * @part: partition number + * Return: 1 if a file system exists on the partition + * 0 otherwise + */ +static int efi_fs_exists(struct blk_desc *desc, int part) +{ + if (fs_set_blk_dev_with_part(desc, part)) + return 0; + + if (fs_get_type() == FS_TYPE_ANY) + return 0; + + fs_close(); + + return 1; +} + /* * Create a handle for a partition or disk * @@ -315,7 +337,7 @@ static efi_status_t efi_disk_add_dev( diskobj->dp); if (ret != EFI_SUCCESS) return ret; - if (part >= 1) { + if (part >= 1 && efi_fs_exists(desc, part)) { diskobj->volume = efi_simple_file_system(desc, part, diskobj->dp); ret = efi_add_protocol(&diskobj->header,