Improve GRUB2 boot to also adhere UEFI spec (#1830) (#1893)

This commit is contained in:
Stefan Agner 2022-05-11 01:51:30 +02:00 committed by GitHub
parent ba8bda73fa
commit 925984c09f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,7 +1,7 @@
From 74d815143bb9b504fb54d3eaf0ed3e382b26000a Mon Sep 17 00:00:00 2001
Message-Id: <74d815143bb9b504fb54d3eaf0ed3e382b26000a.1651759401.git.stefan@agner.ch>
In-Reply-To: <184b6a054e04bb4c7fb4885a30d62314229dc551.1651759401.git.stefan@agner.ch>
References: <184b6a054e04bb4c7fb4885a30d62314229dc551.1651759401.git.stefan@agner.ch>
From e3c27254802e1d7ebaa64df8edb93b0a899f1678 Mon Sep 17 00:00:00 2001
Message-Id: <e3c27254802e1d7ebaa64df8edb93b0a899f1678.1652212828.git.stefan@agner.ch>
In-Reply-To: <184b6a054e04bb4c7fb4885a30d62314229dc551.1652212828.git.stefan@agner.ch>
References: <184b6a054e04bb4c7fb4885a30d62314229dc551.1652212828.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 5 May 2022 15:46:51 +0200
Subject: [PATCH] efidisk: pass buffers with higher alignment
@ -14,12 +14,18 @@ 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:
It seems that some system interpret IoAlign > 1 to mean 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.
However, some systems (e.g. U-Boot and some drivers in EDK II) do follow
the UEFI specification.
Work around by using an alignment of at least 512 bytes in case
alignment is requested. Also make sure that IoAlign is still respected
as per UEFI specification if a higher alignment than block size is
requested.
Note: The problem has only noticed with compressed squashfs. It seems
that ext4 (and presumably other file system drivers) pass buffers with
@ -27,32 +33,38 @@ a higher alignment already.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
grub-core/disk/efi/efidisk.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
grub-core/disk/efi/efidisk.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index 9e20af70e..eaf22367f 100644
index 9e20af70e..c4eb4f4e7 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,
@@ -553,8 +553,22 @@ 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 IoAlign is > 1, it should represent the required alignment. However,
+ * some UEFI implementation on Intel NUC systems seem to use IoAlign=2 but
+ * require 2^IoAlign.
+ * Make sure to align to at least block size if IO alignment is required.
+ */
+ if (bio->media->io_align > 1)
+ io_align = 1 << bio->media->io_align;
+ {
+ if (bio->media->io_align < bio->media->block_size)
+ io_align = bio->media->block_size;
+ else
+ io_align = bio->media->io_align;
+ }
+ else
+ io_align = 1;
+
num_bytes = size << disk->log_sector_size;
if ((grub_addr_t) buf & (io_align - 1))
--
2.36.0
2.36.1