On 2022-05-05 17:42, Vladimir 'phcoder' Serbinenko wrote: > Le jeu. 5 mai 2022, 15:55, Stefan Agner <ste...@agner.ch> a écrit : > >> Despite the UEFI specification saying "the requirement is that the >> start address of a buffer must be evenly divisible by IoAlign with >> no remainder.", it seems that a higher alignment requirement is >> neecssary on some system (e.g. a Intel NUC system with NVMe SSD). >> That particular system has IoAlign set to 2, and sometimes returns >> status 7 when buffers with alignment of 2 are passed. Things seem >> to work fine with buffers aligned to 4 bytes. >> >> It seems that IoAlign > 1 means 2 ^ IoAlign. There is also such a hint >> in an example printed in the Driver Writer's Guide: >> ScsiPassThruMode.IoAlign = 2; // Data must be alligned on 4-byte boundary >> >> Pass 2 ^ IoAlign aligned buffers to make sure GRUB2 works properly on >> all systems. >> >> Note: The problem has only noticed with compressed squashfs. It seems >> that ext4 (and presumably other file system drivers) pass buffers with >> a higher alignment already. >> >> Signed-off-by: Stefan Agner <ste...@agner.ch> >> --- >> grub-core/disk/efi/efidisk.c | 12 ++++++++++-- >> 1 file changed, 10 insertions(+), 2 deletions(-) >> >> diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c >> index f077b5f55..0fc2f0826 100644 >> --- a/grub-core/disk/efi/efidisk.c >> +++ b/grub-core/disk/efi/efidisk.c >> @@ -553,8 +553,16 @@ grub_efidisk_readwrite (struct grub_disk *disk, >> grub_disk_addr_t sector, >> d = disk->data; >> bio = d->block_io; >> >> - /* Set alignment to 1 if 0 specified */ >> - io_align = bio->media->io_align ? bio->media->io_align : 1; >> + /* >> + * If IoAlign is > 1, it means alignment by 2^IoAlign >> + * Note: UEFI spec claims alignment by IoAlign. But there are systems >> + * with IoAlign=2 which return status 7 if 2 bytes aligned buffers are >> + * passed. >> + */ >> + if (bio->media->io_align > 1) >> + io_align = 1 << bio->media->io_align; >> + else >> + io_align = 1; > > May be it should be >=1 rather than > 1? >
No, 1 is explicitly defined to mean no alignment, hence io_align needs to be set to 1. -- Stefan >> num_bytes = size << disk->log_sector_size; >> >> if ((grub_addr_t) buf & (io_align - 1)) >> -- >> 2.36.0 >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> https://lists.gnu.org/mailman/listinfo/grub-devel > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel