forked from home-assistant/operating-system
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve GRUB2 boot to also adhere UEFI spec (home-assistant#1830)
- Loading branch information
Showing
1 changed file
with
30 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
From 74d815143bb9b504fb54d3eaf0ed3e382b26000a Mon Sep 17 00:00:00 2001 | ||
Message-Id: <74d815143bb9b504fb54d3eaf0ed3e382b26000a.1651759401[email protected]> | ||
In-Reply-To: <184b6a054e04bb4c7fb4885a30d62314229dc551.1651759401[email protected]> | ||
References: <184b6a054e04bb4c7fb4885a30d62314229dc551.1651759401[email protected]> | ||
From e3c27254802e1d7ebaa64df8edb93b0a899f1678 Mon Sep 17 00:00:00 2001 | ||
Message-Id: <e3c27254802e1d7ebaa64df8edb93b0a899f1678.1652212828[email protected]> | ||
In-Reply-To: <184b6a054e04bb4c7fb4885a30d62314229dc551.1652212828[email protected]> | ||
References: <184b6a054e04bb4c7fb4885a30d62314229dc551.1652212828[email protected]> | ||
From: Stefan Agner <[email protected]> | ||
Date: Thu, 5 May 2022 15:46:51 +0200 | ||
Subject: [PATCH] efidisk: pass buffers with higher alignment | ||
|
@@ -14,45 +14,57 @@ 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 | ||
a higher alignment already. | ||
|
||
Signed-off-by: Stefan Agner <[email protected]> | ||
--- | ||
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 | ||
|