aboutsummaryrefslogtreecommitdiffstats
path: root/sys-boot/grub/files
diff options
context:
space:
mode:
authorPA4WDH2021-08-25 12:02:32 +0200
committerPA4WDH2021-08-25 12:02:32 +0200
commit38be1b3221b1e85cac1af8a67c733752265425d7 (patch)
tree62805f905167039e00378ede54f5dd41203bc577 /sys-boot/grub/files
parentAdd patch to sys-boot/u-boot-2021.07 to make it work (diff)
downloadunmatched-patchwork-38be1b3221b1e85cac1af8a67c733752265425d7.tar.gz
unmatched-patchwork-38be1b3221b1e85cac1af8a67c733752265425d7.tar.bz2
unmatched-patchwork-38be1b3221b1e85cac1af8a67c733752265425d7.zip
Add sys-boot/grub-2.06-r1
Diffstat (limited to 'sys-boot/grub/files')
-rw-r--r--sys-boot/grub/files/grub-2.06-001-loader-drop-argv-in-grub_initrd_load.patch173
-rw-r--r--sys-boot/grub/files/grub-2.06-002-efi-add-definition-of-loadfile2-protocol.patch58
-rw-r--r--sys-boot/grub/files/grub-2.06-003-efi-implemented-loadfile2-initrd-loading.patch180
-rw-r--r--sys-boot/grub/files/grub-2.06-004-linux-ignore-fdt-unless-we-need-to-modify-it.patch77
-rw-r--r--sys-boot/grub/files/grub-2.06-005-loader-move-arm64-linux-loader.patch73
-rw-r--r--sys-boot/grub/files/grub-2.06-006-riscv-update-image-header.patch81
-rw-r--r--sys-boot/grub/files/grub-2.06-007-riscv-use-common-linux-loader.patch117
-rw-r--r--sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch135
-rw-r--r--sys-boot/grub/files/grub-2.06-011-support-loading-device-trees.patch73
-rw-r--r--sys-boot/grub/files/grub-2.06-012-move-load-fdt.patch21
10 files changed, 988 insertions, 0 deletions
diff --git a/sys-boot/grub/files/grub-2.06-001-loader-drop-argv-in-grub_initrd_load.patch b/sys-boot/grub/files/grub-2.06-001-loader-drop-argv-in-grub_initrd_load.patch
new file mode 100644
index 0000000..66d91dd
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-001-loader-drop-argv-in-grub_initrd_load.patch
@@ -0,0 +1,173 @@
+
+In the case of an error grub_initrd_load() uses argv[] to print the
+filename that caused the error. It is also possible to obtain the
+filename from the file handles and there is no need to duplicate that
+information in argv[], so let's drop it.
+
+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
+---
+ grub-core/loader/arm/linux.c | 2 +-
+ grub-core/loader/arm64/linux.c | 2 +-
+ grub-core/loader/i386/linux.c | 2 +-
+ grub-core/loader/i386/pc/linux.c | 2 +-
+ grub-core/loader/i386/xen.c | 3 +--
+ grub-core/loader/ia64/efi/linux.c | 2 +-
+ grub-core/loader/linux.c | 4 ++--
+ grub-core/loader/mips/linux.c | 2 +-
+ grub-core/loader/powerpc/ieee1275/linux.c | 2 +-
+ grub-core/loader/sparc64/ieee1275/linux.c | 2 +-
+ include/grub/linux.h | 2 +-
+ 11 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
+index ed23dc71e..1f7ab7578 100644
+--- a/grub-core/loader/arm/linux.c
++++ b/grub-core/loader/arm/linux.c
+@@ -422,7 +422,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ grub_dprintf ("loader", "Loading initrd to 0x%08x\n",
+ (grub_addr_t) initrd_start);
+
+- if (grub_initrd_load (&initrd_ctx, argv, (void *) initrd_start))
++ if (grub_initrd_load (&initrd_ctx, (void *) initrd_start))
+ goto fail;
+
+ initrd_end = initrd_start + size;
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
+index ef3e9f944..aed7a200b 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/arm64/linux.c
+@@ -266,7 +266,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ goto fail;
+ }
+
+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
+ goto fail;
+
+ initrd_start = (grub_addr_t) initrd_mem;
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
+index 9f74a96b1..f30a1586a 100644
+--- a/grub-core/loader/i386/linux.c
++++ b/grub-core/loader/i386/linux.c
+@@ -1107,7 +1107,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ initrd_mem_target = get_physical_target_address (ch);
+ }
+
+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
+ goto fail;
+
+ grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
+diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
+index 2a2995201..efeeeb206 100644
+--- a/grub-core/loader/i386/pc/linux.c
++++ b/grub-core/loader/i386/pc/linux.c
+@@ -462,7 +462,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ initrd_addr = get_physical_target_address (ch);
+ }
+
+- if (grub_initrd_load (&initrd_ctx, argv, initrd_chunk))
++ if (grub_initrd_load (&initrd_ctx, initrd_chunk))
+ goto fail;
+
+ lh->ramdisk_image = initrd_addr;
+diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
+index cd24874ca..3b856e842 100644
+--- a/grub-core/loader/i386/xen.c
++++ b/grub-core/loader/i386/xen.c
+@@ -809,8 +809,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ if (err)
+ goto fail;
+
+- if (grub_initrd_load (&initrd_ctx, argv,
+- get_virtual_current_address (ch)))
++ if (grub_initrd_load (&initrd_ctx, get_virtual_current_address (ch)))
+ goto fail;
+ }
+
+diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c
+index 7987fd1ba..8873b7a55 100644
+--- a/grub-core/loader/ia64/efi/linux.c
++++ b/grub-core/loader/ia64/efi/linux.c
+@@ -563,7 +563,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n",
+ (grub_uint64_t) initrd_mem, initrd_size);
+
+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
+ goto fail;
+ fail:
+ grub_initrd_close (&initrd_ctx);
+diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
+index 3fe390f17..d19df670e 100644
+--- a/grub-core/loader/linux.c
++++ b/grub-core/loader/linux.c
+@@ -271,7 +271,7 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
+
+ grub_err_t
+ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
+- char *argv[], void *target)
++ void *target)
+ {
+ grub_uint8_t *ptr = target;
+ int i;
+@@ -317,7 +317,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+- argv[i]);
++ initrd_ctx->components[i].file->name);
+ grub_initrd_close (initrd_ctx);
+ return grub_errno;
+ }
+diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
+index e4ed95921..94594721d 100644
+--- a/grub-core/loader/mips/linux.c
++++ b/grub-core/loader/mips/linux.c
+@@ -452,7 +452,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ initrd_dest = get_physical_target_address (ch) | 0x80000000;
+ }
+
+- if (grub_initrd_load (&initrd_ctx, argv, initrd_src))
++ if (grub_initrd_load (&initrd_ctx, initrd_src))
+ goto fail;
+
+ #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
+diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
+index 818b2a86d..a51e7a786 100644
+--- a/grub-core/loader/powerpc/ieee1275/linux.c
++++ b/grub-core/loader/powerpc/ieee1275/linux.c
+@@ -363,7 +363,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+
+ grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
+
+- if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
++ if (grub_initrd_load (&initrd_ctx, (void *) addr))
+ goto fail;
+
+ initrd_addr = addr;
+diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
+index bb47ee0cc..ac2206f3c 100644
+--- a/grub-core/loader/sparc64/ieee1275/linux.c
++++ b/grub-core/loader/sparc64/ieee1275/linux.c
+@@ -413,7 +413,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
+ addr, paddr, size);
+
+- if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
++ if (grub_initrd_load (&initrd_ctx, (void *) addr))
+ goto fail;
+
+ initrd_addr = addr;
+diff --git a/include/grub/linux.h b/include/grub/linux.h
+index 594a3f307..a96ac2048 100644
+--- a/include/grub/linux.h
++++ b/include/grub/linux.h
+@@ -21,4 +21,4 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx);
+
+ grub_err_t
+ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
+- char *argv[], void *target);
++ void *target);
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-002-efi-add-definition-of-loadfile2-protocol.patch b/sys-boot/grub/files/grub-2.06-002-efi-add-definition-of-loadfile2-protocol.patch
new file mode 100644
index 0000000..35777b5
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-002-efi-add-definition-of-loadfile2-protocol.patch
@@ -0,0 +1,58 @@
+Incorporate the EFI_LOAD_FILE2_PROTOCOL GUID and C types from the
+UEFI spec.
+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
+Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
+---
+ grub-core/commands/efi/lsefi.c | 1 +
+ include/grub/efi/api.h | 15 +++++++++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
+index d1ce99af4..4085f5df2 100644
+--- a/grub-core/commands/efi/lsefi.c
++++ b/grub-core/commands/efi/lsefi.c
+@@ -55,6 +55,7 @@ struct known_protocol
+ { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
+ { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" },
+ { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" },
++ { GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" },
+ { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" },
+ { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" },
+ { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" },
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index f1a52210c..3de0a7d12 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -149,6 +149,11 @@
+ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
+ }
+
++#define GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID \
++ { 0x4006c0c1, 0xfcb3, 0x403e, \
++ { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \
++ }
++
+ #define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { 0x0964e5b22, 0x6459, 0x11d2, \
+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+@@ -1729,6 +1734,16 @@ struct grub_efi_rng_protocol
+ };
+ typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
+
++struct grub_efi_load_file2
++{
++ grub_efi_status_t (*load_file)(struct grub_efi_load_file2 *this,
++ grub_efi_device_path_t *file_path,
++ grub_efi_boolean_t boot_policy,
++ grub_efi_uintn_t *buffer_size,
++ void *buffer);
++};
++typedef struct grub_efi_load_file2 grub_efi_load_file2_t;
++
+ #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
+ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
+ || defined(__riscv)
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-003-efi-implemented-loadfile2-initrd-loading.patch b/sys-boot/grub/files/grub-2.06-003-efi-implemented-loadfile2-initrd-loading.patch
new file mode 100644
index 0000000..65fdf2e
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-003-efi-implemented-loadfile2-initrd-loading.patch
@@ -0,0 +1,180 @@
+Recent Linux kernels will invoke the LoadFile2 protocol installed on
+a well-known vendor media path to load the initrd if it is exposed by
+the firmware. Using this method is preferred for two reasons:
+- the Linux kernel is in charge of allocating the memory, and so it can
+ implement any placement policy it wants (given that these tend to
+ change between kernel versions),
+- it is no longer necessary to modify the device tree provided by the
+ firmware.
+
+So let's install this protocol when handling the 'initrd' command if
+such a recent kernel was detected (based on the PE/COFF image version),
+and defer loading the initrd contents until the point where the kernel
+invokes the LoadFile2 protocol.
+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
+---
+ grub-core/loader/arm64/linux.c | 117 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 116 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
+index aed7a200b..6b03455d1 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/arm64/linux.c
+@@ -48,9 +48,18 @@ static grub_uint32_t cmdline_size;
+ static grub_addr_t initrd_start;
+ static grub_addr_t initrd_end;
+
++static struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
++static grub_efi_handle_t initrd_lf2_handle;
++static int initrd_use_loadfile2;
++static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
++static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
++
+ grub_err_t
+ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
+ {
++ struct grub_pe32_coff_header *coff_header;
++ struct grub_pe32_optional_header *optional_header;
++
+ if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
+ return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
+
+@@ -61,6 +70,21 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
+
++ coff_header = (struct grub_pe32_coff_header *)((unsigned long)lh + lh->hdr_offset);
++ optional_header = (struct grub_pe32_optional_header *)(coff_header + 1);
++
++ /*
++ * Linux kernels built for any architecture are guaranteed to support the
++ * LoadFile2 based initrd loading protocol if the image version is >= 1.
++ */
++ if (optional_header->major_image_version >= 1)
++ initrd_use_loadfile2 = 1;
++ else
++ initrd_use_loadfile2 = 0;
++
++ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
++ initrd_use_loadfile2 ? "en" : "dis");
++
+ return GRUB_ERR_NONE;
+ }
+
+@@ -230,13 +254,86 @@ allocate_initrd_mem (int initrd_pages)
+ GRUB_EFI_LOADER_DATA);
+ }
+
++struct initrd_media_device_path {
++ grub_efi_vendor_media_device_path_t vendor;
++ grub_efi_device_path_t end;
++} GRUB_PACKED;
++
++#define LINUX_EFI_INITRD_MEDIA_GUID \
++ { 0x5568e427, 0x68fc, 0x4f3d, \
++ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \
++ }
++
++static struct initrd_media_device_path initrd_lf2_device_path = {
++ {
++ {
++ GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
++ GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
++ sizeof(grub_efi_vendor_media_device_path_t),
++ },
++ LINUX_EFI_INITRD_MEDIA_GUID
++ }, {
++ GRUB_EFI_END_DEVICE_PATH_TYPE,
++ GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
++ sizeof(grub_efi_device_path_t)
++ }
++};
++
++static grub_efi_status_t
++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
++ grub_efi_device_path_t *device_path,
++ grub_efi_boolean_t boot_policy,
++ grub_efi_uintn_t *buffer_size,
++ void *buffer);
++
++static grub_efi_load_file2_t initrd_lf2 = {
++ grub_efi_initrd_load_file2
++};
++
++static grub_efi_status_t
++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
++ grub_efi_device_path_t *device_path,
++ grub_efi_boolean_t boot_policy,
++ grub_efi_uintn_t *buffer_size,
++ void *buffer)
++{
++ grub_efi_status_t status = GRUB_EFI_SUCCESS;
++ grub_efi_uintn_t initrd_size;
++
++ if (!this || this != &initrd_lf2 || !buffer_size)
++ return GRUB_EFI_INVALID_PARAMETER;
++
++ if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE ||
++ device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
++ return GRUB_EFI_NOT_FOUND;
++
++ if (boot_policy)
++ return GRUB_EFI_UNSUPPORTED;
++
++ initrd_size = grub_get_initrd_size (&initrd_ctx);
++ if (!buffer || *buffer_size < initrd_size)
++ {
++ *buffer_size = initrd_size;
++ return GRUB_EFI_BUFFER_TOO_SMALL;
++ }
++
++ grub_dprintf ("linux", "Providing initrd via LOAD_FILE2_PROTOCOL\n");
++
++ if (grub_initrd_load (&initrd_ctx, buffer))
++ status = GRUB_EFI_LOAD_ERROR;
++
++ grub_initrd_close (&initrd_ctx);
++ return status;
++}
++
+ static grub_err_t
+ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+ {
+- struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+ int initrd_size, initrd_pages;
+ void *initrd_mem = NULL;
++ grub_efi_boot_services_t *b;
++ grub_efi_status_t status;
+
+ if (argc == 0)
+ {
+@@ -254,6 +351,24 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
+ goto fail;
+
++ if (initrd_use_loadfile2 && !initrd_lf2_handle)
++ {
++ b = grub_efi_system_table->boot_services;
++ status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle,
++ &load_file2_guid,
++ &initrd_lf2,
++ &device_path_guid,
++ &initrd_lf2_device_path,
++ NULL);
++ if (status == GRUB_EFI_OUT_OF_RESOURCES)
++ {
++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
++ return grub_errno;
++ }
++ grub_dprintf ("linux", "LoadFile2 initrd loading protocol installed\n");
++ return GRUB_ERR_NONE;
++ }
++
+ initrd_size = grub_get_initrd_size (&initrd_ctx);
+ grub_dprintf ("linux", "Loading initrd\n");
+
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-004-linux-ignore-fdt-unless-we-need-to-modify-it.patch b/sys-boot/grub/files/grub-2.06-004-linux-ignore-fdt-unless-we-need-to-modify-it.patch
new file mode 100644
index 0000000..0655fab
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-004-linux-ignore-fdt-unless-we-need-to-modify-it.patch
@@ -0,0 +1,77 @@
+Now that we implemented supported for the LoadFile2 protocol for initrd
+loading, there is no longer a need to pass the initrd parameters via
+the device tree. This means there is no longer a reason to update the
+device tree in the first place, and so we can ignore it entirely.
+
+The only remaining reason to deal with the devicetree is if we are
+using the 'devicetree' command to load one from disk, so tweak the
+logic in grub_fdt_install() to take that into account.
+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
+---
+ grub-core/loader/arm64/linux.c | 22 +++++++++++-----------
+ grub-core/loader/efi/fdt.c | 7 +++++--
+ 2 files changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
+index 6b03455d1..65f1275fb 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/arm64/linux.c
+@@ -95,21 +95,21 @@ finalize_params_linux (void)
+
+ void *fdt;
+
+- fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
++ /* Set initrd info */
++ if (initrd_start && initrd_end > initrd_start)
++ {
++ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+
+- if (!fdt)
+- goto failure;
++ if (!fdt)
++ goto failure;
+
+- node = grub_fdt_find_subnode (fdt, 0, "chosen");
+- if (node < 0)
+- node = grub_fdt_add_subnode (fdt, 0, "chosen");
++ node = grub_fdt_find_subnode (fdt, 0, "chosen");
++ if (node < 0)
++ node = grub_fdt_add_subnode (fdt, 0, "chosen");
+
+- if (node < 1)
+- goto failure;
++ if (node < 1)
++ goto failure;
+
+- /* Set initrd info */
+- if (initrd_start && initrd_end > initrd_start)
+- {
+ grub_dprintf ("linux", "Initrd @ %p-%p\n",
+ (void *) initrd_start, (void *) initrd_end);
+
+diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
+index c86f283d7..771d455c7 100644
+--- a/grub-core/loader/efi/fdt.c
++++ b/grub-core/loader/efi/fdt.c
+@@ -89,13 +89,16 @@ grub_fdt_install (void)
+ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
+ grub_efi_status_t status;
+
++ if (!fdt && !loaded_fdt)
++ return GRUB_ERR_NONE;
++
+ b = grub_efi_system_table->boot_services;
+- status = b->install_configuration_table (&fdt_guid, fdt);
++ status = b->install_configuration_table (&fdt_guid, fdt ?: loaded_fdt);
+ if (status != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_IO, "failed to install FDT");
+
+ grub_dprintf ("fdt", "Installed/updated FDT configuration table @ %p\n",
+- fdt);
++ fdt ?: loaded_fdt);
+ return GRUB_ERR_NONE;
+ }
+
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-005-loader-move-arm64-linux-loader.patch b/sys-boot/grub/files/grub-2.06-005-loader-move-arm64-linux-loader.patch
new file mode 100644
index 0000000..4a98b44
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-005-loader-move-arm64-linux-loader.patch
@@ -0,0 +1,73 @@
+ARM64 linux loader code is written in such a way that it can be reused
+across different architectures without much change. Move it to common
+code so that RISC-V doesn't have to define a separate loader.
+
+Signed-off-by: Atish Patra <atish.patra@wdc.com>
+---
+ grub-core/Makefile.core.def | 4 ++--
+ grub-core/loader/{arm64 => efi}/linux.c | 2 +-
+ include/grub/arm/linux.h | 2 +-
+ include/grub/arm64/linux.h | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+ rename grub-core/loader/{arm64 => efi}/linux.c (99%)
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index 8022e1c0a..b36cf663a 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -1806,9 +1806,9 @@ module = {
+ sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
+ ia64_efi = loader/ia64/efi/linux.c;
+ arm_coreboot = loader/arm/linux.c;
+- arm_efi = loader/arm64/linux.c;
++ arm_efi = loader/efi/linux.c;
+ arm_uboot = loader/arm/linux.c;
+- arm64 = loader/arm64/linux.c;
++ arm64 = loader/efi/linux.c;
+ riscv32 = loader/riscv/linux.c;
+ riscv64 = loader/riscv/linux.c;
+ common = loader/linux.c;
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/efi/linux.c
+similarity index 99%
+rename from grub-core/loader/arm64/linux.c
+rename to grub-core/loader/efi/linux.c
+index 65f1275fb..60f0fa264 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/efi/linux.c
+@@ -60,7 +60,7 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
+ struct grub_pe32_coff_header *coff_header;
+ struct grub_pe32_optional_header *optional_header;
+
+- if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
++ if (lh->magic != GRUB_LINUX_ARCH_MAGIC_SIGNATURE)
+ return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
+
+ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
+diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
+index bcd5a7eb1..8c13978d2 100644
+--- a/include/grub/arm/linux.h
++++ b/include/grub/arm/linux.h
+@@ -35,7 +35,7 @@ struct linux_arm_kernel_header {
+ };
+
+ #if defined(__arm__)
+-# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
+ # define linux_arch_kernel_header linux_arm_kernel_header
+ #endif
+
+diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
+index 7e22b4ab6..effd870ef 100644
+--- a/include/grub/arm64/linux.h
++++ b/include/grub/arm64/linux.h
+@@ -39,7 +39,7 @@ struct linux_arm64_kernel_header
+ };
+
+ #if defined(__aarch64__)
+-# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
+ # define linux_arch_kernel_header linux_arm64_kernel_header
+ #endif
+
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-006-riscv-update-image-header.patch b/sys-boot/grub/files/grub-2.06-006-riscv-update-image-header.patch
new file mode 100644
index 0000000..5ebd4f2
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-006-riscv-update-image-header.patch
@@ -0,0 +1,81 @@
+Update the RISC-V Linux kernel image headers as per the current header.
+
+Reference:
+<Linux kernel source>/Documentation/riscv/boot-image-header.rst
+
+Signed-off-by: Atish Patra <atish.patra@wdc.com>
+---
+ include/grub/riscv32/linux.h | 15 ++++++++-------
+ include/grub/riscv64/linux.h | 15 ++++++++-------
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
+index 512b777c8..de0dbdcd1 100644
+--- a/include/grub/riscv32/linux.h
++++ b/include/grub/riscv32/linux.h
+@@ -19,20 +19,21 @@
+ #ifndef GRUB_RISCV32_LINUX_HEADER
+ #define GRUB_RISCV32_LINUX_HEADER 1
+
+-#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
++#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x05435352 /* 'RSC\0x5' */
+
+-/* From linux/Documentation/riscv/booting.txt */
++/* From linux/Documentation/riscv/boot-image-header.rst */
+ struct linux_riscv_kernel_header
+ {
+ grub_uint32_t code0; /* Executable code */
+ grub_uint32_t code1; /* Executable code */
+- grub_uint64_t text_offset; /* Image load offset */
+- grub_uint64_t res0; /* reserved */
+- grub_uint64_t res1; /* reserved */
++ grub_uint64_t text_offset; /* Image load offset, little endian */
++ grub_uint64_t image_size; /* Effective Image size, little endian */
++ grub_uint64_t flags; /* kernel flags, little endian */
++ grub_uint32_t version; /* Version of this header */
++ grub_uint32_t res1; /* reserved */
+ grub_uint64_t res2; /* reserved */
+ grub_uint64_t res3; /* reserved */
+- grub_uint64_t res4; /* reserved */
+- grub_uint32_t magic; /* Magic number, little endian, "RSCV" */
++ grub_uint32_t magic; /* Magic number, little endian, "RSC\x05" */
+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
+ };
+
+diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h
+index 3630c30fb..7c28bc922 100644
+--- a/include/grub/riscv64/linux.h
++++ b/include/grub/riscv64/linux.h
+@@ -19,22 +19,23 @@
+ #ifndef GRUB_RISCV64_LINUX_HEADER
+ #define GRUB_RISCV64_LINUX_HEADER 1
+
+-#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
++#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x05435352 /* 'RSC\0x5' */
+
+ #define GRUB_EFI_PE_MAGIC 0x5A4D
+
+-/* From linux/Documentation/riscv/booting.txt */
++/* From linux/Documentation/riscv/boot-image-header.rst */
+ struct linux_riscv_kernel_header
+ {
+ grub_uint32_t code0; /* Executable code */
+ grub_uint32_t code1; /* Executable code */
+- grub_uint64_t text_offset; /* Image load offset */
+- grub_uint64_t res0; /* reserved */
+- grub_uint64_t res1; /* reserved */
++ grub_uint64_t text_offset; /* Image load offset, little endian */
++ grub_uint64_t image_size; /* Effective Image size, little endian */
++ grub_uint64_t flags; /* kernel flags, little endian */
++ grub_uint32_t version; /* Version of this header */
++ grub_uint32_t res1; /* reserved */
+ grub_uint64_t res2; /* reserved */
+ grub_uint64_t res3; /* reserved */
+- grub_uint64_t res4; /* reserved */
+- grub_uint32_t magic; /* Magic number, little endian, "RSCV" */
++ grub_uint32_t magic; /* Magic number, little endian, "RSC\x05" */
+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
+ };
+
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-007-riscv-use-common-linux-loader.patch b/sys-boot/grub/files/grub-2.06-007-riscv-use-common-linux-loader.patch
new file mode 100644
index 0000000..525d3a9
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-007-riscv-use-common-linux-loader.patch
@@ -0,0 +1,117 @@
+RISC-V doesn't have to do anything very different from other architectures
+to loader EFI stub linux kernel. As a result, just use the common linux
+loader instead of defining a RISC-V specific linux loader.
+
+Signed-off-by: Atish Patra <atish.patra@wdc.com>
+---
+ grub-core/Makefile.core.def | 4 +--
+ grub-core/loader/riscv/linux.c | 59 ----------------------------------
+ include/grub/riscv32/linux.h | 1 +
+ include/grub/riscv64/linux.h | 1 +
+ 4 files changed, 4 insertions(+), 61 deletions(-)
+ delete mode 100644 grub-core/loader/riscv/linux.c
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index b36cf663a..0536575bc 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -1809,8 +1809,8 @@ module = {
+ arm_efi = loader/efi/linux.c;
+ arm_uboot = loader/arm/linux.c;
+ arm64 = loader/efi/linux.c;
+- riscv32 = loader/riscv/linux.c;
+- riscv64 = loader/riscv/linux.c;
++ riscv32 = loader/efi/linux.c;
++ riscv64 = loader/efi/linux.c;
+ common = loader/linux.c;
+ common = lib/cmdline.c;
+ enable = noemu;
+diff --git a/grub-core/loader/riscv/linux.c b/grub-core/loader/riscv/linux.c
+deleted file mode 100644
+index d17c488e1..000000000
+--- a/grub-core/loader/riscv/linux.c
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/*
+- * GRUB -- GRand Unified Bootloader
+- * Copyright (C) 2018 Free Software Foundation, Inc.
+- *
+- * GRUB is free software: you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation, either version 3 of the License, or
+- * (at your option) any later version.
+- *
+- * GRUB is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+- */
+-
+-#include <grub/command.h>
+-#include <grub/dl.h>
+-#include <grub/lib/cmdline.h>
+-
+-GRUB_MOD_LICENSE ("GPLv3+");
+-
+-static grub_err_t
+-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+- int argc __attribute__ ((unused)),
+- char *argv[] __attribute__ ((unused)))
+-{
+- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet"));
+-
+- return grub_errno;
+-}
+-
+-static grub_err_t
+-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+- int argc __attribute__ ((unused)),
+- char *argv[] __attribute__ ((unused)))
+-{
+- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet"));
+-
+- return grub_errno;
+-}
+-
+-static grub_command_t cmd_linux, cmd_initrd;
+-
+-GRUB_MOD_INIT (linux)
+-{
+- cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
+- N_("Load Linux."));
+- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
+- N_("Load initrd."));
+-}
+-
+-GRUB_MOD_FINI (linux)
+-{
+- grub_unregister_command (cmd_linux);
+- grub_unregister_command (cmd_initrd);
+-}
+diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
+index de0dbdcd1..706c69087 100644
+--- a/include/grub/riscv32/linux.h
++++ b/include/grub/riscv32/linux.h
+@@ -38,5 +38,6 @@ struct linux_riscv_kernel_header
+ };
+
+ #define linux_arch_kernel_header linux_riscv_kernel_header
++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_RISCV_MAGIC_SIGNATURE
+
+ #endif /* ! GRUB_RISCV32_LINUX_HEADER */
+diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h
+index 7c28bc922..88d5df781 100644
+--- a/include/grub/riscv64/linux.h
++++ b/include/grub/riscv64/linux.h
+@@ -40,5 +40,6 @@ struct linux_riscv_kernel_header
+ };
+
+ #define linux_arch_kernel_header linux_riscv_kernel_header
++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_RISCV_MAGIC_SIGNATURE
+
+ #endif /* ! GRUB_RISCV64_LINUX_HEADER */
+--
+2.29.3
diff --git a/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch b/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch
new file mode 100644
index 0000000..ee7c122
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch
@@ -0,0 +1,135 @@
+Device-trees are used to convey information about hardware to the operating
+system. Some of the properties are only known at boot time. (One example of
+such a property is the number of the boot hart on RISC-V systems.) Therefore
+the firmware applies fix-ups to the original device-tree. Some nodes and
+properties are added or altered.
+
+When using GRUB's device-tree command the same fix-ups have to be applied.
+The EFI Device Tree Fixup Protocol allows to pass the loaded device tree
+to the firmware for this purpose.
+
+The protocol can
+
+* add nodes and update properties
+* reserve memory according to the /reserved-memory node and the memory
+ reservation block
+* install the device-tree as configuration table
+
+With the patch GRUB checks if the protocol is installed and invokes it if
+available.
+
+Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+---
+ grub-core/loader/efi/fdt.c | 35 ++++++++++++++++++++++++++++++++++-
+ include/grub/efi/api.h | 22 ++++++++++++++++++++++
+ 2 files changed, 56 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
+index 57ee81686..58e95eb05 100644
+--- a/grub-core/loader/efi/fdt.c
++++ b/grub-core/loader/efi/fdt.c
+@@ -29,6 +29,7 @@
+
+ static void *loaded_fdt;
+ static void *fdt;
++static grub_efi_guid_t dt_fixup_guid = GRUB_EFI_DT_FIXUP_PROTOCOL_GUID;
+
+ #define FDT_ADDR_CELLS_STRING "#address-cells"
+ #define FDT_SIZE_CELLS_STRING "#size-cells"
+@@ -36,6 +37,38 @@ static void *fdt;
+ sizeof (FDT_ADDR_CELLS_STRING) + \
+ sizeof (FDT_SIZE_CELLS_STRING))
+
++static void *grub_fdt_fixup (void)
++{
++ grub_efi_dt_fixup_t *dt_fixup_prot;
++ grub_efi_uintn_t size = 0;
++ grub_efi_status_t status;
++ void *fixup_fdt;
++
++ dt_fixup_prot = grub_efi_locate_protocol (&dt_fixup_guid, 0);
++ if (! dt_fixup_prot)
++ return loaded_fdt;
++
++ grub_dprintf ("linux", "EFI_DT_FIXUP_PROTOCOL available\n");
++
++ status = efi_call_4 (dt_fixup_prot->fixup, dt_fixup_prot, loaded_fdt, &size,
++ GRUB_EFI_DT_APPLY_FIXUPS | GRUB_EFI_DT_RESERVE_MEMORY);
++ if (status != GRUB_EFI_BUFFER_TOO_SMALL)
++ return loaded_fdt;
++
++ fixup_fdt = grub_realloc (loaded_fdt, size);
++ if (!fixup_fdt)
++ return loaded_fdt;
++ loaded_fdt = fixup_fdt;
++
++ status = efi_call_4 (dt_fixup_prot->fixup, dt_fixup_prot, loaded_fdt, &size,
++ GRUB_EFI_DT_APPLY_FIXUPS | GRUB_EFI_DT_RESERVE_MEMORY);
++
++ if (status == GRUB_EFI_SUCCESS)
++ grub_dprintf ("linux", "Device tree fixed up via EFI_DT_FIXUP_PROTOCOL\n");
++
++ return loaded_fdt;
++}
++
+ void *
+ grub_fdt_load (grub_size_t additional_size)
+ {
+@@ -49,7 +82,7 @@ grub_fdt_load (grub_size_t additional_size)
+ }
+
+ if (loaded_fdt)
+- raw_fdt = loaded_fdt;
++ raw_fdt = grub_fdt_fixup();
+ else
+ raw_fdt = grub_efi_get_firmware_fdt();
+
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 34109861a..8101df0df 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -334,6 +334,11 @@
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+ }
+
++#define GRUB_EFI_DT_FIXUP_PROTOCOL_GUID \
++ { 0xe617d64c, 0xfe08, 0x46da, \
++ { 0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00 } \
++ }
++
+ #define GRUB_EFI_VENDOR_APPLE_GUID \
+ { 0x2B0585EB, 0xD8B8, 0x49A9, \
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+@@ -1641,6 +1646,13 @@ enum
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10,
+ };
+
++enum
++ {
++ GRUB_EFI_DT_APPLY_FIXUPS = 0x01,
++ GRUB_EFI_DT_RESERVE_MEMORY = 0x02,
++ GRUB_EFI_EFI_DT_INSTALL_TABLE = 0x04,
++ };
++
+ struct grub_efi_simple_network
+ {
+ grub_uint64_t revision;
+@@ -1704,6 +1716,16 @@ struct grub_efi_block_io
+ };
+ typedef struct grub_efi_block_io grub_efi_block_io_t;
+
++struct grub_efi_dt_fixup
++{
++ grub_efi_uint64_t revision;
++ grub_efi_status_t (*fixup) (struct grub_efi_dt_fixup *this,
++ void *fdt,
++ grub_efi_uintn_t *buffer_size,
++ grub_uint32_t flags);
++};
++typedef struct grub_efi_dt_fixup grub_efi_dt_fixup_t;
++
+ struct grub_efi_shim_lock_protocol
+ {
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+--
+2.30.0
diff --git a/sys-boot/grub/files/grub-2.06-011-support-loading-device-trees.patch b/sys-boot/grub/files/grub-2.06-011-support-loading-device-trees.patch
new file mode 100644
index 0000000..f892376
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-011-support-loading-device-trees.patch
@@ -0,0 +1,73 @@
+diff --git a/docs/grub.texi b/docs/grub.texi
+index eeac9b2ce..64cf95e6f 100644
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -1560,6 +1560,12 @@ This option may be set to a list of GRUB module names separated by spaces.
+ Each module will be loaded as early as possible, at the start of
+ @file{grub.cfg}.
+
++@item GRUB_LOAD_DEVICE_TREE
++If this option is set to @samp{true}, a devicetree command will be added
++to the Linux menu entries in @file{grub.cfg}. Device-trees require fix-ups
++by the firmware. You should use this option only if your firmware supports
++the EFI Device Tree Fixup Protocol.
++
+ @end table
+
+ The following options are still accepted for compatibility with existing
+diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
+index d3e879b8e..3d7fd54f3 100644
+--- a/util/grub-mkconfig.in
++++ b/util/grub-mkconfig.in
+@@ -230,6 +230,7 @@ export GRUB_DEFAULT \
+ GRUB_CMDLINE_GNUMACH \
+ GRUB_EARLY_INITRD_LINUX_CUSTOM \
+ GRUB_EARLY_INITRD_LINUX_STOCK \
++ GRUB_LOAD_DEVICETREE \
+ GRUB_TERMINAL_INPUT \
+ GRUB_TERMINAL_OUTPUT \
+ GRUB_SERIAL_COMMAND \
+diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
+index e8b01c0d0..15bc26ba8 100644
+--- a/util/grub.d/10_linux.in
++++ b/util/grub.d/10_linux.in
+@@ -143,6 +143,15 @@ linux_entry ()
+ echo '$(echo "$message" | grub_quote)'
+ linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
+ EOF
++ if [ "x${GRUB_LOAD_DEVICETREE}" = "xtrue" ]; then
++ if test -n "${dtb}" ; then
++ message="$(gettext_printf "Loading device tree ...")"
++ sed "s/^/$submenu_indentation/" << EOF
++ echo '$(echo "$message" | grub_quote)'
++ devicetree ${rel_dirname}/${dtb}
++EOF
++ fi
++ fi
+ if test -n "${initrd}" ; then
+ # TRANSLATORS: ramdisk isn't identifier. Should be translated.
+ message="$(gettext_printf "Loading initial ramdisk ...")"
+@@ -244,6 +253,20 @@ while [ "x$list" != "x" ] ; do
+ fi
+ done
+
++ if [ "x${GRUB_LOAD_DEVICETREE}" = "xtrue" ]; then
++ dtb=
++ for i in "dtb-${version}" "dtb" ; do
++ if test -e "${dirname}/${i}" ; then
++ dtb="${i}"
++ break
++ fi
++ done
++
++ if test -n "${dtb}" ; then
++ gettext_printf "Found dtb: %s\n" "${dirname}/${dtb}" >&2
++ fi
++ fi
++
+ initramfs=
+ if test -n "${config}" ; then
+ initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr
+-d \"`
+--
+2.30.0
diff --git a/sys-boot/grub/files/grub-2.06-012-move-load-fdt.patch b/sys-boot/grub/files/grub-2.06-012-move-load-fdt.patch
new file mode 100644
index 0000000..b348225
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-012-move-load-fdt.patch
@@ -0,0 +1,21 @@
+--- grub-2.06/grub-core/loader/efi/linux.c 2021-08-25 11:30:12.186661512 +0200
++++ grub-2.06-mod/grub-core/loader/efi/linux.c 2021-08-25 11:25:50.337761208 +0200
+@@ -95,13 +95,14 @@
+
+ void *fdt;
+
++ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
++
++ if (!fdt)
++ goto failure;
++
+ /* Set initrd info */
+ if (initrd_start && initrd_end > initrd_start)
+ {
+- fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+-
+- if (!fdt)
+- goto failure;
+
+ node = grub_fdt_find_subnode (fdt, 0, "chosen");
+ if (node < 0)