Merge ~xypron/grub:riscv into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu

Proposed by Heinrich Schuchardt
Status: Merged
Merge reported by: Julian Andres Klode
Merged at revision: aa394cde19ed136dc1d0feabe89e9de44a2826c1
Proposed branch: ~xypron/grub:riscv
Merge into: ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Diff against target: 4172 lines (+3092/-223) (has conflicts)
37 files modified
debian/control (+57/-7)
debian/patches/0076-ubuntu-Make-the-linux-command-in-EFI-grub-always-try.patch (+1/-1)
debian/patches/0096-linuxefi-fail-kernel-validation-without-shim-protoco.patch (+22/-22)
debian/patches/0099-chainloader-Avoid-a-double-free-when-validation-fail.patch (+3/-3)
debian/patches/RISC-V-Update-image-header.patch (+84/-0)
debian/patches/RISC-V-Use-common-linux-loader.patch (+120/-0)
debian/patches/dejavu-font-path.patch (+2/-2)
debian/patches/efi-add-definition-of-LoadFile2-protocol.patch (+61/-0)
debian/patches/efi-correct-struct-grub_efi_boot_services.patch (+28/-0)
debian/patches/efi-implement-grub_efi_run_image.patch (+898/-0)
debian/patches/efi-implemented-LoadFile2-initrd-loading-protocol-fo.patch (+183/-0)
debian/patches/efi-variable-storage-minimise-writes.patch (+1/-1)
debian/patches/efinet-set-dns-from-uefi-proto.patch (+4/-4)
debian/patches/efinet-set-network-from-uefi-devpath.patch (+3/-3)
debian/patches/efinet-uefi-ipv6-pxe-support.patch (+2/-2)
debian/patches/fat-fix-listing-the-root-directory.patch (+46/-0)
debian/patches/gfxpayload-dynamic.patch (+3/-3)
debian/patches/linux-ignore-FDT-unless-we-need-to-modify-it.patch (+80/-0)
debian/patches/loader-Move-arm64-linux-loader-to-common-code.patch (+1091/-0)
debian/patches/loader-drop-argv-argument-in-grub_initrd_load.patch (+178/-0)
debian/patches/maybe-quiet.patch (+3/-3)
debian/patches/mkconfig-ubuntu-recovery.patch (+2/-2)
debian/patches/no-devicetree-if-secure-boot.patch (+3/-3)
debian/patches/pc-verifiers-module.patch (+1/-1)
debian/patches/quick-boot.patch (+2/-2)
debian/patches/riscv-adjust-march-flags-for-binutils-2.38.patch (+43/-0)
debian/patches/series (+14/-0)
debian/patches/suse-add-support-for-UEFI-network-protocols.patch (+11/-11)
debian/patches/ubuntu-add-initrd-less-boot-fallback.patch (+1/-1)
debian/patches/ubuntu-efi-allow-loopmount-chainload.patch (+4/-4)
debian/patches/ubuntu-fix-lzma-decompressor-objcopy.patch (+1/-1)
debian/patches/ubuntu-linuxefi-arm64-set-base-addr.patch (+4/-4)
debian/patches/ubuntu-linuxefi-arm64.patch (+39/-52)
debian/patches/ubuntu-linuxefi.patch (+84/-83)
debian/patches/vt-handoff.patch (+2/-2)
debian/postinst.in (+2/-1)
debian/rules (+9/-5)
Conflict in debian/patches/series
Reviewer Review Type Date Requested Status
Ubuntu Core Development Team Pending
Review via email: mp+415733@code.launchpad.net

Commit message

With this pull request GRUB is built for riscv64.

* for ARM keep the broken existing code path
* for RISC-V use a new implementation of LoadImage(), StartImage() in peimage.c
* signing is not foreseen for RISC-V currently

This replaces https://code.launchpad.net/~xypron/grub/+git/grub/+merge/415323 and considers the comments provided.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/control b/debian/control
2index cdcb96f..f88631f 100644
3--- a/debian/control
4+++ b/debian/control
5@@ -34,8 +34,8 @@ Build-Depends: debhelper-compat (= 10),
6 libparted-dev [any-powerpc any-ppc64 any-ppc64el],
7 pkg-config,
8 bash-completion,
9- libefiboot-dev [i386 amd64 ia64 x32 armel armhf arm64],
10- libefivar-dev [i386 amd64 ia64 x32 armel armhf arm64],
11+ libefiboot-dev [i386 amd64 ia64 x32 armel armhf arm64 riscv64],
12+ libefivar-dev [i386 amd64 ia64 x32 armel armhf arm64 riscv64],
13 Build-Conflicts: autoconf2.13, libzfs-dev, libnvpair-dev
14 Standards-Version: 3.9.6
15 Homepage: https://www.gnu.org/software/grub/
16@@ -63,9 +63,9 @@ Description: GRand Unified Bootloader, version 2 (dummy package)
17 This is a dummy transitional package that depends on grub-coreboot.
18
19 Package: grub-efi
20-Architecture: any-i386 any-amd64 any-arm64 any-ia64 any-arm
21+Architecture: any-i386 any-amd64 any-arm64 any-ia64 any-arm any-riscv64
22 Pre-Depends: ${misc:Pre-Depends}
23-Depends: ${misc:Depends}, grub-efi-ia32 (= ${binary:Version}) [any-i386], grub-efi-amd64 (>= ${binary:Version}) [any-amd64], grub-efi-arm64 (>= ${binary:Version}) [any-arm64], grub-efi-ia64 (= ${binary:Version}) [any-ia64], grub-efi-arm (= ${binary:Version}) [any-arm]
24+Depends: ${misc:Depends}, grub-efi-ia32 (= ${binary:Version}) [any-i386], grub-efi-amd64 (>= ${binary:Version}) [any-amd64], grub-efi-arm64 (>= ${binary:Version}) [any-arm64], grub-efi-ia64 (= ${binary:Version}) [any-ia64], grub-efi-arm (= ${binary:Version}) [any-arm], grub-efi-riscv64 (= ${binary:Version}) [any-riscv64]
25 Multi-Arch: foreign
26 Description: GRand Unified Bootloader, version 2 (dummy package)
27 This is a dummy package that depends on the grub-efi-$ARCH package most likely
28@@ -77,7 +77,7 @@ Built-Using: ${Built-Using}
29 Depends: ${shlibs:Depends}, ${misc:Depends}, gettext-base, ${lsb-base-depends}
30 Replaces: grub-pc (<< 2.00-4), grub-ieee1275 (<< 2.00-4), grub-efi (<< 1.99-1), grub-coreboot (<< 2.00-4), grub-linuxbios (<< 1.96+20080831-1), grub-efi-ia32 (<< 2.00-4), grub-efi-amd64 (<< 2.00-4), grub-efi-ia64 (<< 2.00-4), grub-yeeloong (<< 2.00-4), init-select
31 Recommends: os-prober (>= 1.33)
32-Suggests: multiboot-doc, grub-emu [any-i386 any-amd64 any-powerpc], mtools [any-i386 any-amd64 any-ia64 any-arm any-arm64], xorriso (>= 0.5.6.pl00), desktop-base (>= 4.0.6), console-setup
33+Suggests: multiboot-doc, grub-emu [any-i386 any-amd64 any-powerpc], mtools [any-i386 any-amd64 any-ia64 any-arm any-arm64 riscv64], xorriso (>= 0.5.6.pl00), desktop-base (>= 4.0.6), console-setup
34 Conflicts: init-select
35 # mdadm: See bugs #435983 and #455746
36 Breaks: mdadm (<< 2.6.7-2), lupin-support (<< 0.55), friendly-recovery (<< 0.2.13), apport (<< 2.1.1)
37@@ -94,7 +94,7 @@ Package: grub2-common
38 # Not Architecture: any because this package contains some things which are
39 # only built when there is a real platform (e.g. grub-install), and the rest
40 # of the package is not very useful in a utilities-only build.
41-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64
42+Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64 any-riscv64
43 Depends: grub-common (= ${binary:Version}), dpkg (>= 1.15.4) | install-info, ${shlibs:Depends}, ${misc:Depends}
44 Replaces: grub, grub-legacy, ${legacy-doc-br}, grub-common (<< 1.99-1), grub-pc (<< 2.02+dfsg1-7), grub-coreboot (<< 2.02+dfsg1-7), grub-efi-ia32 (<< 2.02+dfsg1-7), grub-efi-amd64 (<< 2.02+dfsg1-7), grub-efi-ia64 (<< 2.02+dfsg1-7), grub-efi-arm (<< 2.02+dfsg1-7), grub-efi-arm64 (<< 2.02+dfsg1-7), grub-ieee1275 (<< 2.02+dfsg1-7), grub-uboot (<< 2.02+dfsg1-7), grub-xen (<< 2.02+dfsg1-7), grub-yeeloong (<< 2.02+dfsg1-7), grub-cloud-amd64 (<< 0.0.4)
45 Conflicts: grub-legacy
46@@ -526,6 +526,56 @@ Description: GRand Unified Bootloader, version 2 (ARM64 UEFI signing template)
47 This package contains template files for grub-efi-arm64-signed.
48 This is only needed for Secure Boot signing.
49
50+Package: grub-efi-riscv64-bin
51+Architecture: any-riscv64
52+Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (>= 2.02~beta2-9)
53+Recommends: efibootmgr [linux-any]
54+Multi-Arch: foreign
55+XB-Efi-Vendor: ${efi:Vendor}
56+Description: GRand Unified Bootloader, version 2 (riscv64 UEFI modules)
57+ GRUB is a portable, powerful bootloader. This version of GRUB is based on a
58+ cleaner design than its predecessors, and provides the following new features:
59+ .
60+ - Scripting in grub.cfg using BASH-like syntax.
61+ - Support for modern partition maps such as GPT.
62+ - Modular generation of grub.cfg via update-grub. Packages providing GRUB
63+ add-ons can plug in their own script rules and trigger updates by invoking
64+ update-grub.
65+ .
66+ This package contains GRUB modules that have been built for use on riscv64
67+ systems with UEFI. It can be installed in parallel with other flavours,
68+ but will not automatically install GRUB as the active boot loader nor
69+ automatically update grub.cfg on upgrade unless grub-efi-riscv64 is also
70+ installed.
71+
72+Package: grub-efi-riscv64-dbg
73+Section: debug
74+Architecture: any-riscv64
75+Depends: ${misc:Depends}, grub-efi-riscv64-bin (= ${binary:Version})
76+Multi-Arch: foreign
77+Description: GRand Unified Bootloader, version 2 (riscv64 UEFI debug files)
78+ This package contains debugging files for grub-efi-riscv64-bin. You only
79+ need these if you are trying to debug GRUB using its GDB stub.
80+
81+Package: grub-efi-riscv64
82+Architecture: any-riscv64
83+Pre-Depends: ${misc:Pre-Depends}
84+Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (>= 2.02~beta2-9), grub-efi-riscv64-bin (= ${binary:Version}), ucf
85+Multi-Arch: foreign
86+Description: GRand Unified Bootloader, version 2 (riscv64 UEFI version)
87+ GRUB is a portable, powerful bootloader. This version of GRUB is based on a
88+ cleaner design than its predecessors, and provides the following new features:
89+ .
90+ - Scripting in grub.cfg using BASH-like syntax.
91+ - Support for modern partition maps such as GPT.
92+ - Modular generation of grub.cfg via update-grub. Packages providing GRUB
93+ add-ons can plug in their own script rules and trigger updates by invoking
94+ update-grub.
95+ .
96+ This is a dependency package for a version of GRUB that has been built for
97+ use on RISC-V 64-bit systems with UEFI. Installing this package indicates that
98+ this version of GRUB should be the active boot loader.
99+
100 Package: grub-ieee1275-bin
101 Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
102 Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
103@@ -765,7 +815,7 @@ Description: GRand Unified Bootloader, version 2 (Yeeloong version)
104 Package: grub-theme-starfield
105 # Could be Architecture: any, but in practice this package is useless in a
106 # utilities-only build.
107-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64
108+Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64 any-riscv64
109 Depends: ${misc:Depends}, grub-common (= ${binary:Version})
110 Multi-Arch: foreign
111 Description: GRand Unified Bootloader, version 2 (starfield theme)
112diff --git a/debian/patches/0076-ubuntu-Make-the-linux-command-in-EFI-grub-always-try.patch b/debian/patches/0076-ubuntu-Make-the-linux-command-in-EFI-grub-always-try.patch
113index 53b5557..c225492 100644
114--- a/debian/patches/0076-ubuntu-Make-the-linux-command-in-EFI-grub-always-try.patch
115+++ b/debian/patches/0076-ubuntu-Make-the-linux-command-in-EFI-grub-always-try.patch
116@@ -50,7 +50,7 @@ index 382ff52..9241fed 100644
117
118 params = grub_efi_allocate_pages_max (0x3fffffff,
119 diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
120-index d55b7cd..1649342 100644
121+index b6c13d7..e764e2a 100644
122 --- a/grub-core/loader/i386/linux.c
123 +++ b/grub-core/loader/i386/linux.c
124 @@ -665,35 +665,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
125diff --git a/debian/patches/0096-linuxefi-fail-kernel-validation-without-shim-protoco.patch b/debian/patches/0096-linuxefi-fail-kernel-validation-without-shim-protoco.patch
126index 433780e..360e21c 100644
127--- a/debian/patches/0096-linuxefi-fail-kernel-validation-without-shim-protoco.patch
128+++ b/debian/patches/0096-linuxefi-fail-kernel-validation-without-shim-protoco.patch
129@@ -12,16 +12,28 @@ CVE-2020-15705
130 Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
131 Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
132 ---
133- grub-core/loader/arm64/linux.c | 13 +++++++++----
134 grub-core/loader/efi/chainloader.c | 1 +
135- grub-core/loader/efi/linux.c | 1 +
136+ grub-core/loader/efi/linux.c | 13 +++++++++----
137+ grub-core/loader/efi/linux_sb.c | 1 +
138 grub-core/loader/i386/efi/linux.c | 2 +-
139 4 files changed, 12 insertions(+), 5 deletions(-)
140
141-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
142-index 4e9eac3..f60ca2f 100644
143---- a/grub-core/loader/arm64/linux.c
144-+++ b/grub-core/loader/arm64/linux.c
145+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
146+index 2b74d79..9042603 100644
147+--- a/grub-core/loader/efi/chainloader.c
148++++ b/grub-core/loader/efi/chainloader.c
149+@@ -1097,6 +1097,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
150+
151+ return 0;
152+ }
153++ // -1 fall-through to fail
154+
155+ grub_file_close (file);
156+ grub_device_close (dev);
157+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
158+index 93e4cfc..56d6745 100644
159+--- a/grub-core/loader/efi/linux.c
160++++ b/grub-core/loader/efi/linux.c
161 @@ -34,6 +34,7 @@
162 #include <grub/i18n.h>
163 #include <grub/lib/cmdline.h>
164@@ -30,7 +42,7 @@ index 4e9eac3..f60ca2f 100644
165
166 GRUB_MOD_LICENSE ("GPLv3+");
167
168-@@ -345,11 +346,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
169+@@ -455,11 +456,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
170
171 grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
172
173@@ -50,22 +62,10 @@ index 4e9eac3..f60ca2f 100644
174 }
175
176 pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
177-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
178-index cf76f48..d64c851 100644
179---- a/grub-core/loader/efi/chainloader.c
180-+++ b/grub-core/loader/efi/chainloader.c
181-@@ -1098,6 +1098,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
182-
183- return 0;
184- }
185-+ // -1 fall-through to fail
186-
187- grub_file_close (file);
188- grub_device_close (dev);
189-diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
190+diff --git a/grub-core/loader/efi/linux_sb.c b/grub-core/loader/efi/linux_sb.c
191 index 73a7196..a09479c 100644
192---- a/grub-core/loader/efi/linux.c
193-+++ b/grub-core/loader/efi/linux.c
194+--- a/grub-core/loader/efi/linux_sb.c
195++++ b/grub-core/loader/efi/linux_sb.c
196 @@ -34,6 +34,7 @@ struct grub_efi_shim_lock
197 };
198 typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
199diff --git a/debian/patches/0099-chainloader-Avoid-a-double-free-when-validation-fail.patch b/debian/patches/0099-chainloader-Avoid-a-double-free-when-validation-fail.patch
200index 73748a8..defec76 100644
201--- a/debian/patches/0099-chainloader-Avoid-a-double-free-when-validation-fail.patch
202+++ b/debian/patches/0099-chainloader-Avoid-a-double-free-when-validation-fail.patch
203@@ -7,10 +7,10 @@ Subject: chainloader: Avoid a double free when validation fails
204 1 file changed, 6 insertions(+), 3 deletions(-)
205
206 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
207-index d64c851..8515f89 100644
208+index 9042603..4a85f41 100644
209 --- a/grub-core/loader/efi/chainloader.c
210 +++ b/grub-core/loader/efi/chainloader.c
211-@@ -1086,6 +1086,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
212+@@ -1085,6 +1085,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
213 if (rc > 0)
214 {
215 grub_file_close (file);
216@@ -20,7 +20,7 @@ index d64c851..8515f89 100644
217 grub_loader_set (grub_secureboot_chainloader_boot,
218 grub_secureboot_chainloader_unload, 0);
219 return 0;
220-@@ -1094,15 +1097,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
221+@@ -1093,15 +1096,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
222 {
223 grub_load_and_start_image(boot_image);
224 grub_file_close (file);
225diff --git a/debian/patches/RISC-V-Update-image-header.patch b/debian/patches/RISC-V-Update-image-header.patch
226new file mode 100644
227index 0000000..224165a
228--- /dev/null
229+++ b/debian/patches/RISC-V-Update-image-header.patch
230@@ -0,0 +1,84 @@
231+From: Atish Patra <atish.patra@wdc.com>
232+Date: Thu, 28 Oct 2021 23:31:19 +0300
233+Subject: RISC-V: Update image header
234+
235+Update the RISC-V Linux kernel image headers as per the current header.
236+
237+Reference:
238+<Linux kernel source>/Documentation/riscv/boot-image-header.rst
239+
240+Signed-off-by: Atish Patra <atish.patra@wdc.com>
241+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00213.html
242+---
243+ include/grub/riscv32/linux.h | 15 ++++++++-------
244+ include/grub/riscv64/linux.h | 15 ++++++++-------
245+ 2 files changed, 16 insertions(+), 14 deletions(-)
246+
247+diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
248+index 512b777..de0dbdc 100644
249+--- a/include/grub/riscv32/linux.h
250++++ b/include/grub/riscv32/linux.h
251+@@ -19,20 +19,21 @@
252+ #ifndef GRUB_RISCV32_LINUX_HEADER
253+ #define GRUB_RISCV32_LINUX_HEADER 1
254+
255+-#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
256++#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x05435352 /* 'RSC\0x5' */
257+
258+-/* From linux/Documentation/riscv/booting.txt */
259++/* From linux/Documentation/riscv/boot-image-header.rst */
260+ struct linux_riscv_kernel_header
261+ {
262+ grub_uint32_t code0; /* Executable code */
263+ grub_uint32_t code1; /* Executable code */
264+- grub_uint64_t text_offset; /* Image load offset */
265+- grub_uint64_t res0; /* reserved */
266+- grub_uint64_t res1; /* reserved */
267++ grub_uint64_t text_offset; /* Image load offset, little endian */
268++ grub_uint64_t image_size; /* Effective Image size, little endian */
269++ grub_uint64_t flags; /* kernel flags, little endian */
270++ grub_uint32_t version; /* Version of this header */
271++ grub_uint32_t res1; /* reserved */
272+ grub_uint64_t res2; /* reserved */
273+ grub_uint64_t res3; /* reserved */
274+- grub_uint64_t res4; /* reserved */
275+- grub_uint32_t magic; /* Magic number, little endian, "RSCV" */
276++ grub_uint32_t magic; /* Magic number, little endian, "RSC\x05" */
277+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
278+ };
279+
280+diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h
281+index 3630c30..7c28bc9 100644
282+--- a/include/grub/riscv64/linux.h
283++++ b/include/grub/riscv64/linux.h
284+@@ -19,22 +19,23 @@
285+ #ifndef GRUB_RISCV64_LINUX_HEADER
286+ #define GRUB_RISCV64_LINUX_HEADER 1
287+
288+-#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
289++#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x05435352 /* 'RSC\0x5' */
290+
291+ #define GRUB_EFI_PE_MAGIC 0x5A4D
292+
293+-/* From linux/Documentation/riscv/booting.txt */
294++/* From linux/Documentation/riscv/boot-image-header.rst */
295+ struct linux_riscv_kernel_header
296+ {
297+ grub_uint32_t code0; /* Executable code */
298+ grub_uint32_t code1; /* Executable code */
299+- grub_uint64_t text_offset; /* Image load offset */
300+- grub_uint64_t res0; /* reserved */
301+- grub_uint64_t res1; /* reserved */
302++ grub_uint64_t text_offset; /* Image load offset, little endian */
303++ grub_uint64_t image_size; /* Effective Image size, little endian */
304++ grub_uint64_t flags; /* kernel flags, little endian */
305++ grub_uint32_t version; /* Version of this header */
306++ grub_uint32_t res1; /* reserved */
307+ grub_uint64_t res2; /* reserved */
308+ grub_uint64_t res3; /* reserved */
309+- grub_uint64_t res4; /* reserved */
310+- grub_uint32_t magic; /* Magic number, little endian, "RSCV" */
311++ grub_uint32_t magic; /* Magic number, little endian, "RSC\x05" */
312+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
313+ };
314+
315diff --git a/debian/patches/RISC-V-Use-common-linux-loader.patch b/debian/patches/RISC-V-Use-common-linux-loader.patch
316new file mode 100644
317index 0000000..de50acc
318--- /dev/null
319+++ b/debian/patches/RISC-V-Use-common-linux-loader.patch
320@@ -0,0 +1,120 @@
321+From: Atish Patra <atish.patra@wdc.com>
322+Date: Thu, 28 Oct 2021 23:31:20 +0300
323+Subject: RISC-V: Use common linux loader
324+
325+RISC-V doesn't have to do anything very different from other architectures
326+to loader EFI stub linux kernel. As a result, just use the common linux
327+loader instead of defining a RISC-V specific linux loader.
328+
329+Signed-off-by: Atish Patra <atish.patra@wdc.com>
330+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00211.html
331+---
332+ grub-core/Makefile.core.def | 4 +--
333+ grub-core/loader/riscv/linux.c | 59 ------------------------------------------
334+ include/grub/riscv32/linux.h | 1 +
335+ include/grub/riscv64/linux.h | 1 +
336+ 4 files changed, 4 insertions(+), 61 deletions(-)
337+ delete mode 100644 grub-core/loader/riscv/linux.c
338+
339+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
340+index b36cf66..0536575 100644
341+--- a/grub-core/Makefile.core.def
342++++ b/grub-core/Makefile.core.def
343+@@ -1809,8 +1809,8 @@ module = {
344+ arm_efi = loader/efi/linux.c;
345+ arm_uboot = loader/arm/linux.c;
346+ arm64 = loader/efi/linux.c;
347+- riscv32 = loader/riscv/linux.c;
348+- riscv64 = loader/riscv/linux.c;
349++ riscv32 = loader/efi/linux.c;
350++ riscv64 = loader/efi/linux.c;
351+ common = loader/linux.c;
352+ common = lib/cmdline.c;
353+ enable = noemu;
354+diff --git a/grub-core/loader/riscv/linux.c b/grub-core/loader/riscv/linux.c
355+deleted file mode 100644
356+index d17c488..0000000
357+--- a/grub-core/loader/riscv/linux.c
358++++ /dev/null
359+@@ -1,59 +0,0 @@
360+-/*
361+- * GRUB -- GRand Unified Bootloader
362+- * Copyright (C) 2018 Free Software Foundation, Inc.
363+- *
364+- * GRUB is free software: you can redistribute it and/or modify
365+- * it under the terms of the GNU General Public License as published by
366+- * the Free Software Foundation, either version 3 of the License, or
367+- * (at your option) any later version.
368+- *
369+- * GRUB is distributed in the hope that it will be useful,
370+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
371+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
372+- * GNU General Public License for more details.
373+- *
374+- * You should have received a copy of the GNU General Public License
375+- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
376+- */
377+-
378+-#include <grub/command.h>
379+-#include <grub/dl.h>
380+-#include <grub/lib/cmdline.h>
381+-
382+-GRUB_MOD_LICENSE ("GPLv3+");
383+-
384+-static grub_err_t
385+-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
386+- int argc __attribute__ ((unused)),
387+- char *argv[] __attribute__ ((unused)))
388+-{
389+- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet"));
390+-
391+- return grub_errno;
392+-}
393+-
394+-static grub_err_t
395+-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
396+- int argc __attribute__ ((unused)),
397+- char *argv[] __attribute__ ((unused)))
398+-{
399+- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet"));
400+-
401+- return grub_errno;
402+-}
403+-
404+-static grub_command_t cmd_linux, cmd_initrd;
405+-
406+-GRUB_MOD_INIT (linux)
407+-{
408+- cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
409+- N_("Load Linux."));
410+- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
411+- N_("Load initrd."));
412+-}
413+-
414+-GRUB_MOD_FINI (linux)
415+-{
416+- grub_unregister_command (cmd_linux);
417+- grub_unregister_command (cmd_initrd);
418+-}
419+diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
420+index de0dbdc..706c690 100644
421+--- a/include/grub/riscv32/linux.h
422++++ b/include/grub/riscv32/linux.h
423+@@ -38,5 +38,6 @@ struct linux_riscv_kernel_header
424+ };
425+
426+ #define linux_arch_kernel_header linux_riscv_kernel_header
427++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_RISCV_MAGIC_SIGNATURE
428+
429+ #endif /* ! GRUB_RISCV32_LINUX_HEADER */
430+diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h
431+index 7c28bc9..88d5df7 100644
432+--- a/include/grub/riscv64/linux.h
433++++ b/include/grub/riscv64/linux.h
434+@@ -40,5 +40,6 @@ struct linux_riscv_kernel_header
435+ };
436+
437+ #define linux_arch_kernel_header linux_riscv_kernel_header
438++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_RISCV_MAGIC_SIGNATURE
439+
440+ #endif /* ! GRUB_RISCV64_LINUX_HEADER */
441diff --git a/debian/patches/dejavu-font-path.patch b/debian/patches/dejavu-font-path.patch
442index 18b8376..2d9d197 100644
443--- a/debian/patches/dejavu-font-path.patch
444+++ b/debian/patches/dejavu-font-path.patch
445@@ -8,10 +8,10 @@ Patch-Name: dejavu-font-path.patch
446 1 file changed, 1 insertion(+), 1 deletion(-)
447
448 diff --git a/configure.ac b/configure.ac
449-index b3fb743..22c6cf7 100644
450+index d422626..a29beb9 100644
451 --- a/configure.ac
452 +++ b/configure.ac
453-@@ -1719,7 +1719,7 @@ fi
454+@@ -1727,7 +1727,7 @@ fi
455
456 if test x"$starfield_excuse" = x; then
457 for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
458diff --git a/debian/patches/efi-add-definition-of-LoadFile2-protocol.patch b/debian/patches/efi-add-definition-of-LoadFile2-protocol.patch
459new file mode 100644
460index 0000000..d2263d3
461--- /dev/null
462+++ b/debian/patches/efi-add-definition-of-LoadFile2-protocol.patch
463@@ -0,0 +1,61 @@
464+From: Ard Biesheuvel <ard.biesheuvel@arm.com>
465+Date: Thu, 28 Oct 2021 23:31:15 +0300
466+Subject: efi: add definition of LoadFile2 protocol
467+
468+Incorporate the EFI_LOAD_FILE2_PROTOCOL GUID and C types from the
469+UEFI spec.
470+
471+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
472+Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
473+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
474+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00210.html
475+---
476+ grub-core/commands/efi/lsefi.c | 1 +
477+ include/grub/efi/api.h | 15 +++++++++++++++
478+ 2 files changed, 16 insertions(+)
479+
480+diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
481+index d1ce99a..4085f5d 100644
482+--- a/grub-core/commands/efi/lsefi.c
483++++ b/grub-core/commands/efi/lsefi.c
484+@@ -55,6 +55,7 @@ struct known_protocol
485+ { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
486+ { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" },
487+ { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" },
488++ { GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" },
489+ { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" },
490+ { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" },
491+ { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" },
492+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
493+index f1a5221..3de0a7d 100644
494+--- a/include/grub/efi/api.h
495++++ b/include/grub/efi/api.h
496+@@ -149,6 +149,11 @@
497+ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
498+ }
499+
500++#define GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID \
501++ { 0x4006c0c1, 0xfcb3, 0x403e, \
502++ { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \
503++ }
504++
505+ #define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
506+ { 0x0964e5b22, 0x6459, 0x11d2, \
507+ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
508+@@ -1729,6 +1734,16 @@ struct grub_efi_rng_protocol
509+ };
510+ typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
511+
512++struct grub_efi_load_file2
513++{
514++ grub_efi_status_t (*load_file)(struct grub_efi_load_file2 *this,
515++ grub_efi_device_path_t *file_path,
516++ grub_efi_boolean_t boot_policy,
517++ grub_efi_uintn_t *buffer_size,
518++ void *buffer);
519++};
520++typedef struct grub_efi_load_file2 grub_efi_load_file2_t;
521++
522+ #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
523+ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
524+ || defined(__riscv)
525diff --git a/debian/patches/efi-correct-struct-grub_efi_boot_services.patch b/debian/patches/efi-correct-struct-grub_efi_boot_services.patch
526new file mode 100644
527index 0000000..a4bf2c2
528--- /dev/null
529+++ b/debian/patches/efi-correct-struct-grub_efi_boot_services.patch
530@@ -0,0 +1,28 @@
531+From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
532+Date: Sat, 22 Jan 2022 11:11:32 +0100
533+Subject: efi: correct struct grub_efi_boot_services
534+
535+The UEFI specification defines that the EFI_BOOT_SERVICES.Exit(() service
536+may return EFI_SUCCESS or EFI_INVALID_PARAMETER. So it cannot be
537+__attribute__((noreturn)).
538+
539+Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
540+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
541+Origin: https://lists.gnu.org/archive/html/grub-devel/2022-01/msg00121.html
542+---
543+ include/grub/efi/api.h | 2 +-
544+ 1 file changed, 1 insertion(+), 1 deletion(-)
545+
546+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
547+index 3211f04..c5dd4af 100644
548+--- a/include/grub/efi/api.h
549++++ b/include/grub/efi/api.h
550+@@ -1267,7 +1267,7 @@ struct grub_efi_boot_services
551+ (*exit) (grub_efi_handle_t image_handle,
552+ grub_efi_status_t exit_status,
553+ grub_efi_uintn_t exit_data_size,
554+- grub_efi_char16_t *exit_data) __attribute__((noreturn));
555++ grub_efi_char16_t *exit_data);
556+
557+ grub_efi_status_t
558+ (*unload_image) (grub_efi_handle_t image_handle);
559diff --git a/debian/patches/efi-implement-grub_efi_run_image.patch b/debian/patches/efi-implement-grub_efi_run_image.patch
560new file mode 100644
561index 0000000..1ab5ba0
562--- /dev/null
563+++ b/debian/patches/efi-implement-grub_efi_run_image.patch
564@@ -0,0 +1,898 @@
565+From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
566+Date: Tue, 18 Jan 2022 11:55:56 +0100
567+Subject: efi: implement grub_efi_run_image
568+
569+Provide function grub_efi_run_image() which consumes a PE-COFF image
570+loaded into memory. The function
571+
572+* checks validity of header
573+* copies the sections
574+* relocates the code
575+* invalidates the instruction cache
576+* executes the image
577+* returns to caller
578+
579+Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
580+---
581+ grub-core/Makefile.core.def | 4 +
582+ grub-core/loader/efi/linux.c | 21 ++
583+ grub-core/loader/efi/peimage.c | 765 +++++++++++++++++++++++++++++++++++++++++
584+ include/grub/efi/linux.h | 3 +
585+ include/grub/efi/peimage.h | 28 ++
586+ 5 files changed, 821 insertions(+)
587+ create mode 100644 grub-core/loader/efi/peimage.c
588+ create mode 100644 include/grub/efi/peimage.h
589+
590+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
591+index 3b06462..2cfea95 100644
592+--- a/grub-core/Makefile.core.def
593++++ b/grub-core/Makefile.core.def
594+@@ -1822,13 +1822,17 @@ module = {
595+ arm_coreboot = loader/arm/linux.c;
596+ arm_efi = loader/efi/linux.c;
597+ arm_efi = loader/efi/linux_sb.c;
598++ arm_efi = loader/efi/peimage.c;
599+ arm_uboot = loader/arm/linux.c;
600+ arm64 = loader/efi/linux.c;
601+ arm64 = loader/efi/linux_sb.c;
602++ arm64 = loader/efi/peimage.c;
603+ riscv32 = loader/efi/linux.c;
604+ riscv32 = loader/efi/linux_sb.c;
605++ riscv32 = loader/efi/peimage.c;
606+ riscv64 = loader/efi/linux.c;
607+ riscv64 = loader/efi/linux_sb.c;
608++ riscv64 = loader/efi/peimage.c;
609+ cflags = '-Wno-error=cast-align';
610+ common = loader/linux.c;
611+ common = lib/cmdline.c;
612+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
613+index 56d6745..18e7fe2 100644
614+--- a/grub-core/loader/efi/linux.c
615++++ b/grub-core/loader/efi/linux.c
616+@@ -190,7 +190,28 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr __attribute__((unused)),
617+
618+ grub_dprintf ("linux", "linux command line: '%s'\n", args);
619+
620++/*
621++ * FIXME:
622++ *
623++ * We know that grub_efi_linux_boot() is broken:
624++ *
625++ * - The entry point address is not correctly determined.
626++ * - Section addresses are ignored.
627++ * - Sections having a raw size that is smaller than the virtual size are not
628++ * filled up with zeros.
629++ * - Relocations are ignored.
630++ * - Binaries calling Exit() quit GRUB.
631++ *
632++ * Thus we expect kernels to fail badly.
633++ *
634++ * Yet reviewers suggested to only change the code path for RISC-V until a
635++ * security audit of the code in grub_efi_run_image() is completed.
636++ */
637++#ifndef __riscv
638+ retval = grub_efi_linux_boot (kernel_addr, handover_offset, kernel_addr);
639++#else
640++ retval = grub_efi_run_image (kernel_addr, kernel_size, linux_args);
641++#endif
642+
643+ /* When successful, not reached */
644+ free_params();
645+diff --git a/grub-core/loader/efi/peimage.c b/grub-core/loader/efi/peimage.c
646+new file mode 100644
647+index 0000000..f9735ab
648+--- /dev/null
649++++ b/grub-core/loader/efi/peimage.c
650+@@ -0,0 +1,765 @@
651++// SPDX-License-Identifier: GPL-3.0+
652++
653++#include <grub/cache.h>
654++#include <grub/cpu/efi/memory.h>
655++#include <grub/efi/efi.h>
656++#include <grub/efi/linux.h>
657++#include <grub/efi/pe32.h>
658++#include <grub/efi/peimage.h>
659++#include <grub/env.h>
660++#include <grub/misc.h>
661++#include <grub/mm.h>
662++#include <grub/setjmp.h>
663++
664++struct image_info {
665++ void *data;
666++ grub_efi_uint32_t data_size;
667++ grub_efi_uint16_t machine;
668++ grub_efi_uint16_t num_sections;
669++ struct grub_pe32_section_table *section;
670++ struct grub_pe32_data_directory *reloc;
671++ grub_uint64_t image_base;
672++ grub_uint32_t section_alignment;
673++ grub_uint32_t image_size;
674++ void *alloc_addr;
675++ grub_uint32_t alloc_pages;
676++ void *image_addr;
677++ grub_efi_entry_point entry_point;
678++};
679++
680++static struct {
681++ grub_jmp_buf jmp;
682++ grub_efi_handle_t image_handle;
683++ grub_efi_status_t exit_status;
684++ grub_efi_status_t EFIAPI (*exit)(grub_efi_handle_t image_handle,
685++ grub_efi_status_t exit_status,
686++ grub_efi_uintn_t exit_data_size,
687++ grub_efi_char16_t *exit_data);
688++} started_image;
689++
690++static int
691++debug_enabled(const char *condition)
692++{
693++ const char *debug;
694++
695++ debug = grub_env_get ("debug");
696++ if (!debug || !grub_strword(debug, condition))
697++ return 0;
698++
699++ return 1;
700++}
701++
702++static void
703++debug(const char *constraint)
704++{
705++ volatile grub_uint64_t x;
706++
707++ if (!debug_enabled(constraint))
708++ return;
709++
710++ grub_printf("Attach debugger\n");
711++ for (x = 1; x; ++x)
712++ ;
713++}
714++
715++__attribute__((unused)) static void
716++dump(const char *text, void *addr, unsigned int size)
717++{
718++ char *pos = addr;
719++
720++ grub_printf("%s @ 0x%lx\n", text, (unsigned long)addr);
721++ for (unsigned int i = 0; i < size; i += 16)
722++ grub_printf("%04x: %02x%02x %02x%02x %02x%02x %02x%02x "
723++ "%02x%02x %02x%02x %02x%02x %02x%02x\n", i,
724++ pos[i + 0], pos[i + 1], pos[i + 2], pos[i + 3],
725++ pos[i + 4], pos[i + 5], pos[i + 6], pos[i + 7],
726++ pos[i + 8], pos[i + 9], pos[i + 10], pos[i + 11],
727++ pos[i + 12], pos[i + 13], pos[i + 14], pos[i + 15]);
728++}
729++
730++static grub_uint16_t machines[] = {
731++#if defined(__x86_64__)
732++ GRUB_PE32_MACHINE_AMD64,
733++#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
734++ GRUB_PE32_MACHINE_AMD64,
735++ GRUB_PE32_MACHINE_I386,
736++#elif defined(__aarch64__)
737++ GRUB_PE32_MACHINE_ARM64,
738++#elif defined(__arm__)
739++ GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
740++#elif defined(__riscv) && __riscv_xlen == 32
741++ GRUB_PE32_MACHINE_RISCV32,
742++#elif defined(__riscv) && __riscv_xlen == 64
743++ GRUB_PE32_MACHINE_RISCV64,
744++#endif
745++};
746++
747++/**
748++ * check_machine_type() - check if the machine type matches the architecture
749++ *
750++ * @machine: the value of the Machine field of the COFF file header.
751++ * Return: status code
752++ */
753++static grub_efi_status_t check_machine_type(grub_uint16_t machine)
754++{
755++ for (grub_size_t i = 0; i < sizeof(machines) / sizeof(*machines); ++i) {
756++ if (machine == machines[i])
757++ return GRUB_EFI_SUCCESS;
758++ }
759++
760++ return GRUB_EFI_LOAD_ERROR;
761++}
762++
763++/**
764++ * check_pe_header() - check the headers of a PE-COFF image
765++ *
766++ * @info: information about the image
767++ */
768++static grub_efi_status_t check_pe_header(struct image_info *info)
769++{
770++ struct grub_dos_stub *dos_stub = info->data;
771++ void *pe_magic;
772++ struct grub_pe32_coff_header *coff_header;
773++ struct grub_pe32_optional_header *pe32_header;
774++ struct grub_pe64_optional_header *pe64_header;
775++ grub_uint32_t header_size;
776++
777++ if (info->data_size < sizeof(struct grub_dos_stub)) {
778++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
779++ return GRUB_EFI_LOAD_ERROR;
780++ }
781++ if (dos_stub->magic != GRUB_PE32_MAGIC) {
782++ grub_error(GRUB_ERR_BAD_OS, "not a PE-COFF file");
783++ return GRUB_EFI_UNSUPPORTED;
784++ }
785++ if (info->data_size < dos_stub->pe_addr + sizeof(GRUB_PE_MAGIC) +
786++ sizeof(struct grub_pe32_coff_header) +
787++ sizeof(struct grub_pe64_optional_header)) {
788++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
789++ return GRUB_EFI_LOAD_ERROR;
790++ }
791++ pe_magic = (void *)((unsigned long)info->data + dos_stub->pe_addr);
792++ if (grub_memcmp(pe_magic, GRUB_PE_MAGIC, sizeof(GRUB_PE_MAGIC))) {
793++ grub_error(GRUB_ERR_BAD_OS, "not a PE-COFF file");
794++ return GRUB_EFI_LOAD_ERROR;
795++ }
796++
797++ coff_header = (void *)((unsigned long)pe_magic + sizeof(GRUB_PE_MAGIC));
798++ info->machine = coff_header->machine;
799++ info->num_sections = coff_header->num_sections;
800++
801++ if (check_machine_type(info->machine) != GRUB_EFI_SUCCESS) {
802++ grub_error(GRUB_ERR_BAD_OS, "wrong machine type %u",
803++ coff_header->machine);
804++ return GRUB_EFI_LOAD_ERROR;
805++ }
806++
807++ pe32_header = (void *)((unsigned long)coff_header +
808++ sizeof(*coff_header));
809++ pe64_header = (void *)((unsigned long)coff_header +
810++ sizeof(*coff_header));
811++
812++ switch (pe32_header->magic) {
813++ case GRUB_PE32_PE32_MAGIC:
814++ info->section_alignment = pe32_header->section_alignment;
815++ info->image_base = pe32_header->image_base;
816++ info->image_size = pe32_header->image_size;
817++ info->entry_point =
818++ (void *)(unsigned long)pe32_header->entry_addr;
819++ header_size = pe32_header->header_size;
820++ if (info->data_size < header_size) {
821++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
822++ return GRUB_EFI_LOAD_ERROR;
823++ }
824++
825++ if (pe32_header->num_data_directories >= 6 &&
826++ pe32_header->base_relocation_table.size)
827++ info->reloc = &pe32_header->base_relocation_table;
828++
829++ info->section = (void *)((unsigned long)&pe32_header->export_table +
830++ pe32_header->num_data_directories *
831++ sizeof(struct grub_pe32_data_directory));
832++ break;
833++ case GRUB_PE32_PE64_MAGIC:
834++ info->section_alignment = pe64_header->section_alignment;
835++ info->image_base = pe64_header->image_base;
836++ info->image_size = pe64_header->image_size;
837++ info->entry_point =
838++ (void *)(unsigned long)pe64_header->entry_addr;
839++ header_size = pe64_header->header_size;
840++ if (info->data_size < header_size) {
841++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
842++ return GRUB_EFI_LOAD_ERROR;
843++ }
844++
845++ if (pe64_header->num_data_directories >= 6 &&
846++ pe64_header->base_relocation_table.size)
847++ info->reloc = &pe64_header->base_relocation_table;
848++
849++ info->section = (void *)((unsigned long)&pe64_header->export_table +
850++ pe64_header->num_data_directories *
851++ sizeof(struct grub_pe32_data_directory));
852++ break;
853++ default:
854++ grub_error(GRUB_ERR_BAD_OS, "not a PE-COFF file");
855++ return GRUB_EFI_LOAD_ERROR;
856++ }
857++
858++ if ((unsigned long)info->section +
859++ info->num_sections * sizeof(*info->section) >
860++ (unsigned long)info->data + info->data_size) {
861++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
862++ return GRUB_EFI_LOAD_ERROR;
863++ }
864++
865++ grub_dprintf("linux", "PE-COFF header checked\n");
866++
867++ return GRUB_EFI_SUCCESS;
868++}
869++
870++/**
871++ * load_sections() - load image sections into memory
872++ *
873++ * Allocate fresh memory and copy the image sections there.
874++ *
875++ * @info: image information
876++ */
877++static grub_efi_status_t load_sections(struct image_info *info)
878++{
879++ struct grub_pe32_section_table *section;
880++ unsigned long align_mask = 0xfff;
881++
882++ /* Section alignment must be a power of two */
883++ if (info->section_alignment & (info->section_alignment - 1)) {
884++ grub_error(GRUB_ERR_BAD_OS, "invalid section alignment");
885++ return GRUB_EFI_LOAD_ERROR;
886++ }
887++
888++ if (info->section_alignment > align_mask)
889++ align_mask = info->section_alignment - 1;
890++
891++ info->alloc_pages = GRUB_EFI_BYTES_TO_PAGES(info->image_size +
892++ (align_mask & ~0xfffUL));
893++
894++ info->alloc_addr = grub_efi_allocate_pages_real(
895++ GRUB_EFI_MAX_USABLE_ADDRESS, info->alloc_pages,
896++ GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA);
897++ if (!info->alloc_addr)
898++ return GRUB_EFI_OUT_OF_RESOURCES;
899++
900++ info->image_addr =
901++ (void *)(((unsigned long)info->alloc_addr + align_mask) &
902++ ~align_mask);
903++
904++ for (section = &info->section[0];
905++ section < &info->section[info->num_sections]; ++section) {
906++ if (section->raw_data_offset + section->raw_data_size >
907++ info->data_size) {
908++ grub_error(GRUB_ERR_BAD_OS, "truncated image");
909++ return GRUB_EFI_LOAD_ERROR;
910++ }
911++ if (section->virtual_address + section->virtual_size >
912++ info->image_size) {
913++ grub_error(GRUB_ERR_BAD_OS, "section outside image");
914++ return GRUB_EFI_LOAD_ERROR;
915++ }
916++
917++ grub_memset(
918++ (void *)((unsigned long)info->image_addr +
919++ section->virtual_address), 0,
920++ section->virtual_size);
921++ grub_memcpy(
922++ (void *)((unsigned long)info->image_addr +
923++ section->virtual_address),
924++ (void *)((unsigned long)info->data +
925++ section->raw_data_offset),
926++ section->raw_data_size);
927++ }
928++
929++ info->entry_point = (void *)((unsigned long)info->entry_point +
930++ (unsigned long)info->image_addr);
931++
932++ grub_dprintf("linux", "sections loaded\n");
933++
934++ return GRUB_EFI_SUCCESS;
935++}
936++
937++/**
938++ * lo12i_get() - get the immediate value of a format I instruction
939++ *
940++ * Instruction format I::
941++ *
942++ * +---------------------------------------------------------------+
943++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
944++ * +-----------------------+---------+-----+---------+-------------+
945++ * | imm[11:0] | rs1 |fun3 | rd | opcode |
946++ * +-----------------------+---------+-----+---------+-------------+
947++ *
948++ * @instr: pointer to instruction
949++ * Return: immediate value
950++ */
951++static grub_uint16_t
952++lo12i_get(grub_uint32_t *instr)
953++{
954++ return ((*instr & 0xfff00000) >> 20);
955++}
956++
957++/**
958++ * lo12i_set() - set the immediate value of a format I instruction
959++ *
960++ * Instruction format I::
961++ *
962++ * +---------------------------------------------------------------+
963++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
964++ * +-----------------------+---------+-----+---------+-------------+
965++ * | imm[11:0] | rs1 |fun3 | rd | opcode |
966++ * +-----------------------+---------+-----+---------+-------------+
967++ *
968++ * @instr: pointer to instruction
969++ * @imm: immediate value
970++ */
971++static void
972++lo12i_set(grub_uint32_t *instr, grub_uint32_t imm)
973++{
974++ *instr = (*instr & 0x000fffff) |
975++ (imm & 0x00000fff << 20);
976++}
977++
978++/**
979++ * hi20_get() - get the immediate value of a format I instruction
980++ *
981++ * Instruction format U::
982++ *
983++ * +---------------------------------------------------------------+
984++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
985++ * +---------------------------------------+---------+-------------+
986++ * | imm[31:12] | rd | opcode |
987++ * +---------------------------------------+---------+-------------+
988++ *
989++ * @instr: pointer to instruction
990++ * Return: immediate value
991++ */
992++static grub_uint16_t
993++hi20_get(grub_uint32_t *instr)
994++{
995++ return *instr & 0xfffff000;
996++}
997++
998++/**
999++ * hi20_set() - set the immediate value of a format I instruction
1000++ *
1001++ * Instruction format U::
1002++ *
1003++ * +---------------------------------------------------------------+
1004++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
1005++ * +---------------------------------------+---------+-------------+
1006++ * | imm[31:12] | rd | opcode |
1007++ * +---------------------------------------+---------+-------------+
1008++ *
1009++ * @instr: pointer to instruction
1010++ * @imm: immediate value
1011++ */
1012++static void
1013++hi20_set(grub_uint32_t *instr, grub_uint32_t imm)
1014++{
1015++ *instr = (*instr & 0x00000fff) |
1016++ (imm & 0xfffff000);
1017++}
1018++
1019++/**
1020++ * lo12s_get() - get the immediate value of a format I instruction
1021++ *
1022++ * Instruction format S::
1023++ *
1024++ * +---------------------------------------------------------------+
1025++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
1026++ * +-------------+---------+---------+-----+----+----+-------------+
1027++ * | imm[11:5] | rs2 | rs1 |fun3 |imm[4:0] | opcode |
1028++ * +-------------+---------+---------+-----+----+----+-------------+
1029++ *
1030++ * @instr: pointer to instruction
1031++ * Return: immediate value
1032++ */
1033++static grub_uint16_t
1034++lo12s_get(grub_uint32_t *instr)
1035++{
1036++ return ((*instr & 0x00000f80) >> 7) |
1037++ ((*instr & 0xfe000000) >> 20);
1038++}
1039++
1040++/**
1041++ * lo12s_set() - set the immediate value of a format I instruction
1042++ *
1043++ * Instruction format S::
1044++ *
1045++ * +---------------------------------------------------------------+
1046++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0|
1047++ * +-------------+---------+---------+-----+----+----+-------------+
1048++ * | imm[11:5] | rs2 | rs1 |fun3 |imm[4:0] | opcode |
1049++ * +-------------+---------+---------+-----+----+----+-------------+
1050++ *
1051++ * @instr: pointer to instruction
1052++ * @imm: immediate value
1053++ */
1054++static void
1055++lo12s_set(grub_uint32_t *instr, grub_uint32_t imm)
1056++{
1057++ *instr = (*instr & 0x01fff07f) |
1058++ (imm & 0x00000fe0 << 20) |
1059++ (imm & 0x0000001f << 7);
1060++}
1061++
1062++/**
1063++ * movw_get_imm() - get the immediate value of MOVT and MOVT instructions
1064++ *
1065++ * MOVT::
1066++ *
1067++ * +-------------------------------+-------------------------------+
1068++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0|f e d c b a 9 8 7 6 5 4 3 2 1 0|
1069++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1070++ * |1 1 1 1 0|i|1 0 1 1 0 0| imm4 |0| imm3| Rd | imm8 |
1071++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1072++ *
1073++ * MOVW::
1074++ *
1075++ * +-------------------------------+-------------------------------+
1076++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0|f e d c b a 9 8 7 6 5 4 3 2 1 0|
1077++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1078++ * |1 1 1 1 0|i|1 0 0 1 0 0| imm4 |0| imm3| Rd | imm8 |
1079++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1080++ *
1081++ * @instr: pointer to instruction
1082++ * Return: immediate value
1083++ */
1084++static grub_uint16_t
1085++movw_get_imm(grub_uint16_t *instr)
1086++{
1087++ /* imm16 = imm4:i:imm3:imm8; */
1088++ return (instr[1] & 0x00ff) |
1089++ ((instr[1] & 0x7000) >> 3) |
1090++ ((instr[0] & 0x0400) >> 8) |
1091++ ((instr[0] & 0x000f) << 12);
1092++}
1093++
1094++/**
1095++ * movw_set_imm() - set the immediate value of MOVT and MOVT instructions
1096++ *
1097++ * MOVT::
1098++ *
1099++ * +-------------------------------+-------------------------------+
1100++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0|f e d c b a 9 8 7 6 5 4 3 2 1 0|
1101++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1102++ * |1 1 1 1 0|i|1 0 1 1 0 0| imm4 |0| imm3| Rd | imm8 |
1103++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1104++ *
1105++ * MOVW::
1106++ *
1107++ * +-------------------------------+-------------------------------+
1108++ * |f e d c b a 9 8 7 6 5 4 3 2 1 0|f e d c b a 9 8 7 6 5 4 3 2 1 0|
1109++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1110++ * |1 1 1 1 0|i|1 0 0 1 0 0| imm4 |0| imm3| Rd | imm8 |
1111++ * +---------+-+-----------+-------+-+-----+-------+---------------+
1112++ *
1113++ * @instr: pointer to instruction
1114++ * @imm immediate value
1115++ */
1116++static void
1117++movw_set_imm(grub_uint16_t *instr, grub_uint16_t imm)
1118++{
1119++ /* imm16 = imm4:i:imm3:imm8; */
1120++ instr[0] = (instr[0] & 0xfbf0) |
1121++ (imm & 0xf000) >> 12 |
1122++ (imm & 0x0800) << 3;
1123++ instr[1] = (instr[0] & 0x8f00) |
1124++ (imm & 0xff) |
1125++ (imm & 0x0700) >> 4;
1126++}
1127++
1128++/**
1129++ * relocate() - apply relocations to the image
1130++ *
1131++ * @info: information about the loaded image
1132++ */
1133++static grub_efi_status_t
1134++relocate(struct image_info *info)
1135++{
1136++ struct grub_pe32_fixup_block *block, *reloc_end;
1137++ unsigned long offset;
1138++ grub_uint16_t reloc_type;
1139++ grub_uint16_t *reloc_entry;
1140++ grub_uint32_t *rvhi20_addr = NULL;
1141++
1142++ if (!info->reloc || !(info->reloc->size)) {
1143++ grub_dprintf("linux", "no relocations\n");
1144++ return GRUB_EFI_SUCCESS;
1145++ }
1146++
1147++ if (info->reloc->rva + info->reloc->size > info->image_size) {
1148++ grub_error(GRUB_ERR_BAD_OS, "relocation block outside image");
1149++ return GRUB_EFI_LOAD_ERROR;
1150++ }
1151++
1152++ /*
1153++ * The relocations are based on the difference between
1154++ * actual load address and the preferred base address.
1155++ */
1156++ offset = (unsigned long)info->image_addr - info->image_base;
1157++
1158++ block = (void *)((unsigned long)info->image_addr + info->reloc->rva);
1159++ reloc_end = (void *)((unsigned long)block + info->reloc->size);
1160++
1161++ for (; block < reloc_end;
1162++ block = (void *)((unsigned long)block + block->block_size)) {
1163++ reloc_entry = block->entries;
1164++ grub_uint16_t *block_end =
1165++ (void *)((unsigned long)block + block->block_size);
1166++
1167++ for (; reloc_entry < block_end; ++reloc_entry) {
1168++ void *addr = (void *)((unsigned long)info->image_addr +
1169++ block->page_rva +
1170++ (*reloc_entry & 0xfff));
1171++
1172++ reloc_type = *reloc_entry >> 12;
1173++
1174++ switch (reloc_type) {
1175++ case GRUB_PE32_REL_BASED_ABSOLUTE:
1176++ /* skip */
1177++ break;
1178++ case GRUB_PE32_REL_BASED_HIGH:
1179++ *(grub_uint16_t *)addr += offset >> 16;
1180++ break;
1181++ case GRUB_PE32_REL_BASED_LOW:
1182++ *(grub_uint16_t *)addr += offset;
1183++ break;
1184++ case GRUB_PE32_REL_BASED_HIGHLOW:
1185++ *(grub_uint32_t *)addr += offset;
1186++ break;
1187++ case GRUB_PE32_REL_BASED_RISCV_HI20:
1188++ switch (info->machine) {
1189++ case GRUB_PE32_MACHINE_RISCV32:
1190++ case GRUB_PE32_MACHINE_RISCV64:
1191++ rvhi20_addr = addr;
1192++ break;
1193++ default:
1194++ goto bad_reloc;
1195++ }
1196++ break;
1197++ case GRUB_PE32_REL_BASED_ARM_MOV32T:
1198++ /* = GRUB_PE32_REL_BASED_RISCV_LOW12I */
1199++ switch (info->machine) {
1200++ case GRUB_PE32_MACHINE_ARMTHUMB_MIXED: {
1201++ grub_uint16_t *instr = addr;
1202++ grub_uint32_t val;
1203++
1204++ val = movw_get_imm(&instr[0]) +
1205++ (movw_get_imm(&instr[2]) << 16) +
1206++ offset;
1207++ movw_set_imm(&instr[0], val);
1208++ movw_set_imm(&instr[2], val >> 16);
1209++ break;
1210++ }
1211++ case GRUB_PE32_MACHINE_RISCV32:
1212++ case GRUB_PE32_MACHINE_RISCV64:
1213++ if (rvhi20_addr) {
1214++ grub_uint32_t val =
1215++ hi20_get(rvhi20_addr) +
1216++ lo12i_get(addr) +
1217++ offset;
1218++ hi20_set(rvhi20_addr, val);
1219++ lo12i_set(addr, val);
1220++ rvhi20_addr = NULL;
1221++ } else {
1222++ goto bad_reloc;
1223++ }
1224++ break;
1225++ default:
1226++ goto bad_reloc;
1227++ }
1228++ break;
1229++ case GRUB_PE32_REL_BASED_RISCV_LOW12S:
1230++ switch (info->machine) {
1231++ case GRUB_PE32_MACHINE_RISCV32:
1232++ case GRUB_PE32_MACHINE_RISCV64:
1233++ if (rvhi20_addr) {
1234++ grub_uint32_t val =
1235++ hi20_get(rvhi20_addr) +
1236++ lo12s_get(addr) +
1237++ offset;
1238++ hi20_set(rvhi20_addr, val);
1239++ lo12s_set(addr, val);
1240++ rvhi20_addr = NULL;
1241++ } else {
1242++ goto bad_reloc;
1243++ }
1244++ break;
1245++ default:
1246++ goto bad_reloc;
1247++ }
1248++ break;
1249++ case GRUB_PE32_REL_BASED_DIR64:
1250++ *(grub_uint64_t *)addr += offset;
1251++ break;
1252++ default:
1253++ goto bad_reloc;
1254++ }
1255++ }
1256++ }
1257++
1258++ grub_dprintf("linux", "image relocated\n");
1259++
1260++ return GRUB_EFI_SUCCESS;
1261++
1262++bad_reloc:
1263++ grub_error(GRUB_ERR_BAD_OS,
1264++ "unsupported relocation type %d, rva 0x%08lx\n",
1265++ *reloc_entry >> 12,
1266++ (unsigned long)reloc_entry -
1267++ (unsigned long)info->image_addr);
1268++ return GRUB_EFI_LOAD_ERROR;
1269++}
1270++
1271++/**
1272++ * efi_exit() - replacement for EFI_BOOT_SERVICES.Exit()
1273++ *
1274++ * This function is inserted into system table to trap invocations of
1275++ * EFI_BOOT_SERVICES.Exit(). If Exit() is called with our handle
1276++ * return to our start routine using a long jump.
1277++ *
1278++ * @image_handle: handle of the application as passed on entry
1279++ * @exit_status: the images exit code
1280++ * @exit_data_size: size of @exit_data
1281++ * @exit_data: null terminated string followed by optional data
1282++ */
1283++static grub_efi_status_t EFIAPI
1284++efi_exit(grub_efi_handle_t image_handle,
1285++ grub_efi_status_t exit_status,
1286++ grub_efi_uintn_t exit_data_size,
1287++ grub_efi_char16_t *exit_data)
1288++{
1289++ grub_efi_system_table->boot_services->exit = started_image.exit;
1290++
1291++ if (!image_handle)
1292++ return GRUB_EFI_INVALID_PARAMETER;
1293++
1294++ if (image_handle != started_image.image_handle) {
1295++ grub_dprintf("linux", "delegating Exit()\n");
1296++ return efi_call_4(started_image.exit, image_handle,
1297++ exit_status, exit_data_size,
1298++ (grub_efi_char16_t *)exit_data);
1299++ }
1300++
1301++ started_image.exit_status = exit_status;
1302++
1303++ if (exit_status != GRUB_EFI_SUCCESS) {
1304++ grub_printf("Application failed, r = %d\n",
1305++ (int)exit_status & 0x7fffffff);
1306++ if (exit_data_size && exit_data) {
1307++ grub_printf("exit message: ");
1308++ for (grub_efi_uintn_t pos = 0;
1309++ exit_data[pos] && pos < exit_data_size / 2; ++pos)
1310++ grub_printf("%C", exit_data[pos]);
1311++ grub_printf("\n");
1312++ }
1313++ }
1314++ if (exit_data_size && exit_data) {
1315++ /* exit data must be freed by the caller */
1316++ efi_call_1(grub_efi_system_table->boot_services->free_pool,
1317++ exit_data);
1318++ }
1319++ grub_longjmp(started_image.jmp, 1);
1320++}
1321++
1322++/**
1323++ * start_image() - our implementation of StartImage()
1324++ *
1325++ * As we do not load the image via LoadImage() we need our own implementation
1326++ * of StartImage() to launch the PE-COFF image.
1327++ */
1328++static grub_efi_status_t
1329++start_image(struct image_info *info)
1330++{
1331++ int ret;
1332++ grub_efi_status_t status;
1333++ grub_efi_loaded_image_t *loaded_image;
1334++
1335++ /*
1336++ * TODO: It would better comply to the UEFI specification to
1337++ * use a separate handle for the image we are running.
1338++ */
1339++ started_image.image_handle = grub_efi_image_handle;
1340++
1341++ loaded_image = grub_efi_get_loaded_image(grub_efi_image_handle);
1342++ if (loaded_image) {
1343++ loaded_image->image_base = info->image_addr;
1344++ loaded_image->image_size = info->image_size;
1345++ } else {
1346++ grub_dprintf ("linux", "Loaded image protocol missing\n");
1347++ }
1348++
1349++ ret = grub_setjmp(started_image.jmp);
1350++ if (ret) {
1351++ started_image.image_handle = NULL;
1352++
1353++ return started_image.exit_status;
1354++ }
1355++
1356++ started_image.exit = grub_efi_system_table->boot_services->exit;
1357++ grub_efi_system_table->boot_services->exit = efi_exit;
1358++
1359++ grub_dprintf("linux",
1360++ "Executing image loaded at 0x%lx\nEntry point 0x%lx\nSize 0x%08x\n",
1361++ (unsigned long)info->image_addr,
1362++ (unsigned long)info->entry_point,
1363++ info->image_size);
1364++
1365++ /* Invalidate the instruction cache */
1366++ grub_arch_sync_caches(info->image_addr, info->image_size);
1367++
1368++ debug("pestart");
1369++ status = efi_call_2(info->entry_point, started_image.image_handle,
1370++ grub_efi_system_table);
1371++
1372++ grub_dprintf("linux", "Application returned\n");
1373++
1374++ return efi_exit(started_image.image_handle, status, 0, NULL);
1375++}
1376++
1377++/**
1378++ * grub_efi_run_image() - run a PE-COFF image from memory
1379++ *
1380++ * TODO: move the creation of the load options here
1381++ *
1382++ * @data: buffer with PE-COFF image
1383++ * @data_size: size of the buffer
1384++ * @args: command line to be passed as load options
1385++ */
1386++grub_efi_boolean_t
1387++grub_efi_run_image(void *data, grub_efi_uint32_t data_size,
1388++ const char *args __attribute__((unused)))
1389++{
1390++ struct image_info info = {
1391++ .data = data,
1392++ .data_size = data_size,
1393++ };
1394++
1395++ /* read and check header */
1396++ if (check_pe_header(&info) != GRUB_EFI_SUCCESS)
1397++ goto err;
1398++ /* load sections */
1399++ if (load_sections(&info) != GRUB_EFI_SUCCESS)
1400++ goto err;
1401++
1402++ if (relocate(&info) != GRUB_EFI_SUCCESS)
1403++ goto err;
1404++
1405++ if (start_image(&info) != GRUB_EFI_SUCCESS)
1406++ goto err;
1407++
1408++err:
1409++ /* free allocated memory */
1410++ if (info.alloc_addr)
1411++ grub_efi_free_pages((unsigned long)info.alloc_addr,
1412++ info.alloc_pages);
1413++
1414++ return 0;
1415++}
1416+diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
1417+index 0033d93..39f5a9a 100644
1418+--- a/include/grub/efi/linux.h
1419++++ b/include/grub/efi/linux.h
1420+@@ -27,5 +27,8 @@ EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
1421+ grub_err_t
1422+ EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
1423+ void *kernel_param);
1424++grub_efi_boolean_t
1425++EXPORT_FUNC(grub_efi_run_image) (void *data, grub_efi_uint32_t data_size,
1426++ const char *args);
1427+
1428+ #endif /* ! GRUB_EFI_LINUX_HEADER */
1429+diff --git a/include/grub/efi/peimage.h b/include/grub/efi/peimage.h
1430+new file mode 100644
1431+index 0000000..70bfdc7
1432+--- /dev/null
1433++++ b/include/grub/efi/peimage.h
1434+@@ -0,0 +1,28 @@
1435++/* SPDX-License-Identifier: GPL-3.0+ */
1436++
1437++#define GRUB_PE_MAGIC "PE\0"
1438++
1439++#ifdef __x86_64__
1440++#define EFIAPI __attribute__((ms_abi))
1441++#else
1442++#define EFIAPI
1443++#endif
1444++
1445++#define EFI_LOADED_IMAGE_PROTOCOL_REVISION (0x1000)
1446++
1447++typedef grub_efi_status_t (*grub_efi_entry_point)
1448++ (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
1449++
1450++struct grub_dos_stub {
1451++ grub_uint16_t magic; /* MZ magic */
1452++ grub_uint16_t lbsize; /* size of last block */
1453++ grub_uint32_t res0; /* reserved */
1454++ grub_uint64_t res1; /* reserved */
1455++ grub_uint64_t res2; /* reserved */
1456++ grub_uint64_t res3; /* reserved */
1457++ grub_uint64_t res4; /* reserved */
1458++ grub_uint64_t res5; /* reserved */
1459++ grub_uint64_t res6; /* reserved */
1460++ grub_uint32_t linux_arch; /* linux architecture */
1461++ grub_uint32_t pe_addr; /* offset of PE/COFF header */
1462++};
1463diff --git a/debian/patches/efi-implemented-LoadFile2-initrd-loading-protocol-fo.patch b/debian/patches/efi-implemented-LoadFile2-initrd-loading-protocol-fo.patch
1464new file mode 100644
1465index 0000000..be73410
1466--- /dev/null
1467+++ b/debian/patches/efi-implemented-LoadFile2-initrd-loading-protocol-fo.patch
1468@@ -0,0 +1,183 @@
1469+From: Ard Biesheuvel <ard.biesheuvel@arm.com>
1470+Date: Thu, 28 Oct 2021 23:31:16 +0300
1471+Subject: efi: implemented LoadFile2 initrd loading protocol for Linux
1472+
1473+Recent Linux kernels will invoke the LoadFile2 protocol installed on
1474+a well-known vendor media path to load the initrd if it is exposed by
1475+the firmware. Using this method is preferred for two reasons:
1476+- the Linux kernel is in charge of allocating the memory, and so it can
1477+ implement any placement policy it wants (given that these tend to
1478+ change between kernel versions),
1479+- it is no longer necessary to modify the device tree provided by the
1480+ firmware.
1481+
1482+So let's install this protocol when handling the 'initrd' command if
1483+such a recent kernel was detected (based on the PE/COFF image version),
1484+and defer loading the initrd contents until the point where the kernel
1485+invokes the LoadFile2 protocol.
1486+
1487+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
1488+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
1489+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00214.html
1490+---
1491+ grub-core/loader/arm64/linux.c | 117 ++++++++++++++++++++++++++++++++++++++++-
1492+ 1 file changed, 116 insertions(+), 1 deletion(-)
1493+
1494+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
1495+index aed7a20..6b03455 100644
1496+--- a/grub-core/loader/arm64/linux.c
1497++++ b/grub-core/loader/arm64/linux.c
1498+@@ -48,9 +48,18 @@ static grub_uint32_t cmdline_size;
1499+ static grub_addr_t initrd_start;
1500+ static grub_addr_t initrd_end;
1501+
1502++static struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
1503++static grub_efi_handle_t initrd_lf2_handle;
1504++static int initrd_use_loadfile2;
1505++static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
1506++static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
1507++
1508+ grub_err_t
1509+ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
1510+ {
1511++ struct grub_pe32_coff_header *coff_header;
1512++ struct grub_pe32_optional_header *optional_header;
1513++
1514+ if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
1515+ return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
1516+
1517+@@ -61,6 +70,21 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
1518+ grub_dprintf ("linux", "UEFI stub kernel:\n");
1519+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
1520+
1521++ coff_header = (struct grub_pe32_coff_header *)((unsigned long)lh + lh->hdr_offset);
1522++ optional_header = (struct grub_pe32_optional_header *)(coff_header + 1);
1523++
1524++ /*
1525++ * Linux kernels built for any architecture are guaranteed to support the
1526++ * LoadFile2 based initrd loading protocol if the image version is >= 1.
1527++ */
1528++ if (optional_header->major_image_version >= 1)
1529++ initrd_use_loadfile2 = 1;
1530++ else
1531++ initrd_use_loadfile2 = 0;
1532++
1533++ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
1534++ initrd_use_loadfile2 ? "en" : "dis");
1535++
1536+ return GRUB_ERR_NONE;
1537+ }
1538+
1539+@@ -230,13 +254,86 @@ allocate_initrd_mem (int initrd_pages)
1540+ GRUB_EFI_LOADER_DATA);
1541+ }
1542+
1543++struct initrd_media_device_path {
1544++ grub_efi_vendor_media_device_path_t vendor;
1545++ grub_efi_device_path_t end;
1546++} GRUB_PACKED;
1547++
1548++#define LINUX_EFI_INITRD_MEDIA_GUID \
1549++ { 0x5568e427, 0x68fc, 0x4f3d, \
1550++ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \
1551++ }
1552++
1553++static struct initrd_media_device_path initrd_lf2_device_path = {
1554++ {
1555++ {
1556++ GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
1557++ GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
1558++ sizeof(grub_efi_vendor_media_device_path_t),
1559++ },
1560++ LINUX_EFI_INITRD_MEDIA_GUID
1561++ }, {
1562++ GRUB_EFI_END_DEVICE_PATH_TYPE,
1563++ GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
1564++ sizeof(grub_efi_device_path_t)
1565++ }
1566++};
1567++
1568++static grub_efi_status_t
1569++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
1570++ grub_efi_device_path_t *device_path,
1571++ grub_efi_boolean_t boot_policy,
1572++ grub_efi_uintn_t *buffer_size,
1573++ void *buffer);
1574++
1575++static grub_efi_load_file2_t initrd_lf2 = {
1576++ grub_efi_initrd_load_file2
1577++};
1578++
1579++static grub_efi_status_t
1580++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
1581++ grub_efi_device_path_t *device_path,
1582++ grub_efi_boolean_t boot_policy,
1583++ grub_efi_uintn_t *buffer_size,
1584++ void *buffer)
1585++{
1586++ grub_efi_status_t status = GRUB_EFI_SUCCESS;
1587++ grub_efi_uintn_t initrd_size;
1588++
1589++ if (!this || this != &initrd_lf2 || !buffer_size)
1590++ return GRUB_EFI_INVALID_PARAMETER;
1591++
1592++ if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE ||
1593++ device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
1594++ return GRUB_EFI_NOT_FOUND;
1595++
1596++ if (boot_policy)
1597++ return GRUB_EFI_UNSUPPORTED;
1598++
1599++ initrd_size = grub_get_initrd_size (&initrd_ctx);
1600++ if (!buffer || *buffer_size < initrd_size)
1601++ {
1602++ *buffer_size = initrd_size;
1603++ return GRUB_EFI_BUFFER_TOO_SMALL;
1604++ }
1605++
1606++ grub_dprintf ("linux", "Providing initrd via LOAD_FILE2_PROTOCOL\n");
1607++
1608++ if (grub_initrd_load (&initrd_ctx, buffer))
1609++ status = GRUB_EFI_LOAD_ERROR;
1610++
1611++ grub_initrd_close (&initrd_ctx);
1612++ return status;
1613++}
1614++
1615+ static grub_err_t
1616+ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
1617+ int argc, char *argv[])
1618+ {
1619+- struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
1620+ int initrd_size, initrd_pages;
1621+ void *initrd_mem = NULL;
1622++ grub_efi_boot_services_t *b;
1623++ grub_efi_status_t status;
1624+
1625+ if (argc == 0)
1626+ {
1627+@@ -254,6 +351,24 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
1628+ if (grub_initrd_init (argc, argv, &initrd_ctx))
1629+ goto fail;
1630+
1631++ if (initrd_use_loadfile2 && !initrd_lf2_handle)
1632++ {
1633++ b = grub_efi_system_table->boot_services;
1634++ status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle,
1635++ &load_file2_guid,
1636++ &initrd_lf2,
1637++ &device_path_guid,
1638++ &initrd_lf2_device_path,
1639++ NULL);
1640++ if (status == GRUB_EFI_OUT_OF_RESOURCES)
1641++ {
1642++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
1643++ return grub_errno;
1644++ }
1645++ grub_dprintf ("linux", "LoadFile2 initrd loading protocol installed\n");
1646++ return GRUB_ERR_NONE;
1647++ }
1648++
1649+ initrd_size = grub_get_initrd_size (&initrd_ctx);
1650+ grub_dprintf ("linux", "Loading initrd\n");
1651+
1652diff --git a/debian/patches/efi-variable-storage-minimise-writes.patch b/debian/patches/efi-variable-storage-minimise-writes.patch
1653index 4d3d134..7609e21 100644
1654--- a/debian/patches/efi-variable-storage-minimise-writes.patch
1655+++ b/debian/patches/efi-variable-storage-minimise-writes.patch
1656@@ -179,7 +179,7 @@ index 27f9482..a3d134b 100644
1657
1658 script = {
1659 diff --git a/configure.ac b/configure.ac
1660-index e11df6b..b3fb743 100644
1661+index b4e33a6..d422626 100644
1662 --- a/configure.ac
1663 +++ b/configure.ac
1664 @@ -452,6 +452,18 @@ AC_CHECK_HEADER([util.h], [
1665diff --git a/debian/patches/efinet-set-dns-from-uefi-proto.patch b/debian/patches/efinet-set-dns-from-uefi-proto.patch
1666index 4588309..03da490 100644
1667--- a/debian/patches/efinet-set-dns-from-uefi-proto.patch
1668+++ b/debian/patches/efinet-set-dns-from-uefi-proto.patch
1669@@ -245,10 +245,10 @@ index 2d3b00f..82a28fb 100644
1670 }
1671
1672 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
1673-index 4b4652c..9cab1a5 100644
1674+index d67c3f1..479c2a8 100644
1675 --- a/include/grub/efi/api.h
1676 +++ b/include/grub/efi/api.h
1677-@@ -354,6 +354,16 @@
1678+@@ -359,6 +359,16 @@
1679 { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
1680 }
1681
1682@@ -265,9 +265,9 @@ index 4b4652c..9cab1a5 100644
1683 struct grub_efi_sal_system_table
1684 {
1685 grub_uint32_t signature;
1686-@@ -1793,6 +1803,72 @@ struct grub_efi_rng_protocol
1687+@@ -1808,6 +1818,72 @@ struct grub_efi_load_file2
1688 };
1689- typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
1690+ typedef struct grub_efi_load_file2 grub_efi_load_file2_t;
1691
1692 +enum grub_efi_ip4_config2_data_type {
1693 + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO,
1694diff --git a/debian/patches/efinet-set-network-from-uefi-devpath.patch b/debian/patches/efinet-set-network-from-uefi-devpath.patch
1695index af95c63..bd19f83 100644
1696--- a/debian/patches/efinet-set-network-from-uefi-devpath.patch
1697+++ b/debian/patches/efinet-set-network-from-uefi-devpath.patch
1698@@ -357,10 +357,10 @@ index fc90415..2d3b00f 100644
1699 }
1700 }
1701 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
1702-index 50ab8e8..4b4652c 100644
1703+index 2c649cf..d67c3f1 100644
1704 --- a/include/grub/efi/api.h
1705 +++ b/include/grub/efi/api.h
1706-@@ -849,6 +849,8 @@ struct grub_efi_ipv4_device_path
1707+@@ -854,6 +854,8 @@ struct grub_efi_ipv4_device_path
1708 grub_efi_uint16_t remote_port;
1709 grub_efi_uint16_t protocol;
1710 grub_efi_uint8_t static_ip_address;
1711@@ -369,7 +369,7 @@ index 50ab8e8..4b4652c 100644
1712 } GRUB_PACKED;
1713 typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
1714
1715-@@ -903,6 +905,15 @@ struct grub_efi_sata_device_path
1716+@@ -908,6 +910,15 @@ struct grub_efi_sata_device_path
1717 } GRUB_PACKED;
1718 typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t;
1719
1720diff --git a/debian/patches/efinet-uefi-ipv6-pxe-support.patch b/debian/patches/efinet-uefi-ipv6-pxe-support.patch
1721index 13f69ed..d256127 100644
1722--- a/debian/patches/efinet-uefi-ipv6-pxe-support.patch
1723+++ b/debian/patches/efinet-uefi-ipv6-pxe-support.patch
1724@@ -51,10 +51,10 @@ index 5388f95..fc90415 100644
1725 }
1726 }
1727 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
1728-index f1a5221..50ab8e8 100644
1729+index 3de0a7d..2c649cf 100644
1730 --- a/include/grub/efi/api.h
1731 +++ b/include/grub/efi/api.h
1732-@@ -1476,14 +1476,67 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
1733+@@ -1481,14 +1481,67 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
1734
1735 typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
1736
1737diff --git a/debian/patches/fat-fix-listing-the-root-directory.patch b/debian/patches/fat-fix-listing-the-root-directory.patch
1738new file mode 100644
1739index 0000000..335ec4c
1740--- /dev/null
1741+++ b/debian/patches/fat-fix-listing-the-root-directory.patch
1742@@ -0,0 +1,46 @@
1743+From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1744+Date: Fri, 21 Jan 2022 20:15:41 +0100
1745+Subject: fat: fix listing the root directory
1746+
1747+ls / for a FAT partition leads to
1748+
1749+ error: invalid modification timestamp for /.
1750+
1751+Not all entries of the directory are displayed.
1752+
1753+Linux never updates the modification timestamp of the /. directory entry.
1754+The FAT specification allows the access and creation date fields to be
1755+zero.
1756+
1757+We should follow Linux and render initial FAT timestamps as start of
1758+the epoch.
1759+
1760+Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1761+Origin: https://lists.gnu.org/archive/html/grub-devel/2022-01/msg00116.html
1762+---
1763+ grub-core/fs/fat.c | 12 ++++++++++++
1764+ 1 file changed, 12 insertions(+)
1765+
1766+diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
1767+index dd82e4e..35ff0b2 100644
1768+--- a/grub-core/fs/fat.c
1769++++ b/grub-core/fs/fat.c
1770+@@ -901,6 +901,18 @@ grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int64_t *nix) {
1771+ .second = (time & 0x001F) * 2,
1772+ };
1773+
1774++ /*
1775++ * The modification time of the root directory is never set by Linux.
1776++ * Creation and access time are optional and can be zero.
1777++ * Follow Linux and render FAT initial timestamps as the start of the epoch.
1778++ */
1779++ if (date == 0 && time == 0)
1780++ {
1781++ datetime.year = 1970;
1782++ datetime.month = 1;
1783++ datetime.day = 1;
1784++ }
1785++
1786+ /* The conversion below allows seconds=60, so don't trust its validation. */
1787+ if ((time & 0x1F) > 29)
1788+ return 0;
1789diff --git a/debian/patches/gfxpayload-dynamic.patch b/debian/patches/gfxpayload-dynamic.patch
1790index 0148257..e59cb02 100644
1791--- a/debian/patches/gfxpayload-dynamic.patch
1792+++ b/debian/patches/gfxpayload-dynamic.patch
1793@@ -21,10 +21,10 @@ Patch-Name: gfxpayload-dynamic.patch
1794 create mode 100644 grub-core/commands/i386/pc/hwmatch.c
1795
1796 diff --git a/configure.ac b/configure.ac
1797-index c42e4c7..947fd52 100644
1798+index 4882eba..3203749 100644
1799 --- a/configure.ac
1800 +++ b/configure.ac
1801-@@ -1937,6 +1937,17 @@ else
1802+@@ -1945,6 +1945,17 @@ else
1803 fi
1804 AC_SUBST([QUICK_BOOT])
1805
1806@@ -43,7 +43,7 @@ index c42e4c7..947fd52 100644
1807
1808 AC_SUBST([FONT_SOURCE])
1809 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
1810-index 715d137..10f839b 100644
1811+index 1a3ead6..0d7bce1 100644
1812 --- a/grub-core/Makefile.core.def
1813 +++ b/grub-core/Makefile.core.def
1814 @@ -964,6 +964,14 @@ module = {
1815diff --git a/debian/patches/linux-ignore-FDT-unless-we-need-to-modify-it.patch b/debian/patches/linux-ignore-FDT-unless-we-need-to-modify-it.patch
1816new file mode 100644
1817index 0000000..a37aea4
1818--- /dev/null
1819+++ b/debian/patches/linux-ignore-FDT-unless-we-need-to-modify-it.patch
1820@@ -0,0 +1,80 @@
1821+From: Ard Biesheuvel <ard.biesheuvel@arm.com>
1822+Date: Thu, 28 Oct 2021 23:31:17 +0300
1823+Subject: linux: ignore FDT unless we need to modify it
1824+
1825+Now that we implemented supported for the LoadFile2 protocol for initrd
1826+loading, there is no longer a need to pass the initrd parameters via
1827+the device tree. This means there is no longer a reason to update the
1828+device tree in the first place, and so we can ignore it entirely.
1829+
1830+The only remaining reason to deal with the devicetree is if we are
1831+using the 'devicetree' command to load one from disk, so tweak the
1832+logic in grub_fdt_install() to take that into account.
1833+
1834+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
1835+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00216.html
1836+---
1837+ grub-core/loader/arm64/linux.c | 22 +++++++++++-----------
1838+ grub-core/loader/efi/fdt.c | 7 +++++--
1839+ 2 files changed, 16 insertions(+), 13 deletions(-)
1840+
1841+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
1842+index 6b03455..65f1275 100644
1843+--- a/grub-core/loader/arm64/linux.c
1844++++ b/grub-core/loader/arm64/linux.c
1845+@@ -95,21 +95,21 @@ finalize_params_linux (void)
1846+
1847+ void *fdt;
1848+
1849+- fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
1850++ /* Set initrd info */
1851++ if (initrd_start && initrd_end > initrd_start)
1852++ {
1853++ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
1854+
1855+- if (!fdt)
1856+- goto failure;
1857++ if (!fdt)
1858++ goto failure;
1859+
1860+- node = grub_fdt_find_subnode (fdt, 0, "chosen");
1861+- if (node < 0)
1862+- node = grub_fdt_add_subnode (fdt, 0, "chosen");
1863++ node = grub_fdt_find_subnode (fdt, 0, "chosen");
1864++ if (node < 0)
1865++ node = grub_fdt_add_subnode (fdt, 0, "chosen");
1866+
1867+- if (node < 1)
1868+- goto failure;
1869++ if (node < 1)
1870++ goto failure;
1871+
1872+- /* Set initrd info */
1873+- if (initrd_start && initrd_end > initrd_start)
1874+- {
1875+ grub_dprintf ("linux", "Initrd @ %p-%p\n",
1876+ (void *) initrd_start, (void *) initrd_end);
1877+
1878+diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
1879+index c86f283..771d455 100644
1880+--- a/grub-core/loader/efi/fdt.c
1881++++ b/grub-core/loader/efi/fdt.c
1882+@@ -89,13 +89,16 @@ grub_fdt_install (void)
1883+ grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
1884+ grub_efi_status_t status;
1885+
1886++ if (!fdt && !loaded_fdt)
1887++ return GRUB_ERR_NONE;
1888++
1889+ b = grub_efi_system_table->boot_services;
1890+- status = b->install_configuration_table (&fdt_guid, fdt);
1891++ status = b->install_configuration_table (&fdt_guid, fdt ?: loaded_fdt);
1892+ if (status != GRUB_EFI_SUCCESS)
1893+ return grub_error (GRUB_ERR_IO, "failed to install FDT");
1894+
1895+ grub_dprintf ("fdt", "Installed/updated FDT configuration table @ %p\n",
1896+- fdt);
1897++ fdt ?: loaded_fdt);
1898+ return GRUB_ERR_NONE;
1899+ }
1900+
1901diff --git a/debian/patches/loader-Move-arm64-linux-loader-to-common-code.patch b/debian/patches/loader-Move-arm64-linux-loader-to-common-code.patch
1902new file mode 100644
1903index 0000000..0cf0470
1904--- /dev/null
1905+++ b/debian/patches/loader-Move-arm64-linux-loader-to-common-code.patch
1906@@ -0,0 +1,1091 @@
1907+From: Atish Patra <atish.patra@wdc.com>
1908+Date: Thu, 28 Oct 2021 23:31:18 +0300
1909+Subject: loader: Move arm64 linux loader to common code
1910+
1911+ARM64 linux loader code is written in such a way that it can be reused
1912+across different architectures without much change. Move it to common
1913+code so that RISC-V doesn't have to define a separate loader.
1914+
1915+Signed-off-by: Atish Patra <atish.patra@wdc.com>
1916+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
1917+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00215.html
1918+---
1919+ grub-core/Makefile.core.def | 4 +-
1920+ grub-core/loader/arm64/linux.c | 508 -----------------------------------------
1921+ grub-core/loader/efi/linux.c | 508 +++++++++++++++++++++++++++++++++++++++++
1922+ include/grub/arm/linux.h | 2 +-
1923+ include/grub/arm64/linux.h | 2 +-
1924+ 5 files changed, 512 insertions(+), 512 deletions(-)
1925+ delete mode 100644 grub-core/loader/arm64/linux.c
1926+ create mode 100644 grub-core/loader/efi/linux.c
1927+
1928+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
1929+index 8022e1c..b36cf66 100644
1930+--- a/grub-core/Makefile.core.def
1931++++ b/grub-core/Makefile.core.def
1932+@@ -1806,9 +1806,9 @@ module = {
1933+ sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
1934+ ia64_efi = loader/ia64/efi/linux.c;
1935+ arm_coreboot = loader/arm/linux.c;
1936+- arm_efi = loader/arm64/linux.c;
1937++ arm_efi = loader/efi/linux.c;
1938+ arm_uboot = loader/arm/linux.c;
1939+- arm64 = loader/arm64/linux.c;
1940++ arm64 = loader/efi/linux.c;
1941+ riscv32 = loader/riscv/linux.c;
1942+ riscv64 = loader/riscv/linux.c;
1943+ common = loader/linux.c;
1944+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
1945+deleted file mode 100644
1946+index 65f1275..0000000
1947+--- a/grub-core/loader/arm64/linux.c
1948++++ /dev/null
1949+@@ -1,508 +0,0 @@
1950+-/*
1951+- * GRUB -- GRand Unified Bootloader
1952+- * Copyright (C) 2013 Free Software Foundation, Inc.
1953+- *
1954+- * GRUB is free software: you can redistribute it and/or modify
1955+- * it under the terms of the GNU General Public License as published by
1956+- * the Free Software Foundation, either version 3 of the License, or
1957+- * (at your option) any later version.
1958+- *
1959+- * GRUB is distributed in the hope that it will be useful,
1960+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1961+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1962+- * GNU General Public License for more details.
1963+- *
1964+- * You should have received a copy of the GNU General Public License
1965+- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
1966+- */
1967+-
1968+-#include <grub/charset.h>
1969+-#include <grub/command.h>
1970+-#include <grub/err.h>
1971+-#include <grub/file.h>
1972+-#include <grub/fdt.h>
1973+-#include <grub/linux.h>
1974+-#include <grub/loader.h>
1975+-#include <grub/mm.h>
1976+-#include <grub/types.h>
1977+-#include <grub/cpu/linux.h>
1978+-#include <grub/efi/efi.h>
1979+-#include <grub/efi/fdtload.h>
1980+-#include <grub/efi/memory.h>
1981+-#include <grub/efi/pe32.h>
1982+-#include <grub/i18n.h>
1983+-#include <grub/lib/cmdline.h>
1984+-#include <grub/verify.h>
1985+-
1986+-GRUB_MOD_LICENSE ("GPLv3+");
1987+-
1988+-static grub_dl_t my_mod;
1989+-static int loaded;
1990+-
1991+-static void *kernel_addr;
1992+-static grub_uint64_t kernel_size;
1993+-
1994+-static char *linux_args;
1995+-static grub_uint32_t cmdline_size;
1996+-
1997+-static grub_addr_t initrd_start;
1998+-static grub_addr_t initrd_end;
1999+-
2000+-static struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
2001+-static grub_efi_handle_t initrd_lf2_handle;
2002+-static int initrd_use_loadfile2;
2003+-static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
2004+-static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
2005+-
2006+-grub_err_t
2007+-grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
2008+-{
2009+- struct grub_pe32_coff_header *coff_header;
2010+- struct grub_pe32_optional_header *optional_header;
2011+-
2012+- if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
2013+- return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
2014+-
2015+- if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
2016+- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
2017+- N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
2018+-
2019+- grub_dprintf ("linux", "UEFI stub kernel:\n");
2020+- grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
2021+-
2022+- coff_header = (struct grub_pe32_coff_header *)((unsigned long)lh + lh->hdr_offset);
2023+- optional_header = (struct grub_pe32_optional_header *)(coff_header + 1);
2024+-
2025+- /*
2026+- * Linux kernels built for any architecture are guaranteed to support the
2027+- * LoadFile2 based initrd loading protocol if the image version is >= 1.
2028+- */
2029+- if (optional_header->major_image_version >= 1)
2030+- initrd_use_loadfile2 = 1;
2031+- else
2032+- initrd_use_loadfile2 = 0;
2033+-
2034+- grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
2035+- initrd_use_loadfile2 ? "en" : "dis");
2036+-
2037+- return GRUB_ERR_NONE;
2038+-}
2039+-
2040+-static grub_err_t
2041+-finalize_params_linux (void)
2042+-{
2043+- int node, retval;
2044+-
2045+- void *fdt;
2046+-
2047+- /* Set initrd info */
2048+- if (initrd_start && initrd_end > initrd_start)
2049+- {
2050+- fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
2051+-
2052+- if (!fdt)
2053+- goto failure;
2054+-
2055+- node = grub_fdt_find_subnode (fdt, 0, "chosen");
2056+- if (node < 0)
2057+- node = grub_fdt_add_subnode (fdt, 0, "chosen");
2058+-
2059+- if (node < 1)
2060+- goto failure;
2061+-
2062+- grub_dprintf ("linux", "Initrd @ %p-%p\n",
2063+- (void *) initrd_start, (void *) initrd_end);
2064+-
2065+- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
2066+- initrd_start);
2067+- if (retval)
2068+- goto failure;
2069+- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
2070+- initrd_end);
2071+- if (retval)
2072+- goto failure;
2073+- }
2074+-
2075+- if (grub_fdt_install() != GRUB_ERR_NONE)
2076+- goto failure;
2077+-
2078+- return GRUB_ERR_NONE;
2079+-
2080+-failure:
2081+- grub_fdt_unload();
2082+- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
2083+-}
2084+-
2085+-grub_err_t
2086+-grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
2087+-{
2088+- grub_efi_memory_mapped_device_path_t *mempath;
2089+- grub_efi_handle_t image_handle;
2090+- grub_efi_boot_services_t *b;
2091+- grub_efi_status_t status;
2092+- grub_efi_loaded_image_t *loaded_image;
2093+- int len;
2094+-
2095+- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
2096+- if (!mempath)
2097+- return grub_errno;
2098+-
2099+- mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
2100+- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
2101+- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
2102+- mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
2103+- mempath[0].start_address = addr;
2104+- mempath[0].end_address = addr + size;
2105+-
2106+- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
2107+- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
2108+- mempath[1].header.length = sizeof (grub_efi_device_path_t);
2109+-
2110+- b = grub_efi_system_table->boot_services;
2111+- status = b->load_image (0, grub_efi_image_handle,
2112+- (grub_efi_device_path_t *) mempath,
2113+- (void *) addr, size, &image_handle);
2114+- if (status != GRUB_EFI_SUCCESS)
2115+- return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
2116+-
2117+- grub_dprintf ("linux", "linux command line: '%s'\n", args);
2118+-
2119+- /* Convert command line to UCS-2 */
2120+- loaded_image = grub_efi_get_loaded_image (image_handle);
2121+- loaded_image->load_options_size = len =
2122+- (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
2123+- loaded_image->load_options =
2124+- grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
2125+- if (!loaded_image->load_options)
2126+- return grub_errno;
2127+-
2128+- loaded_image->load_options_size =
2129+- 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
2130+- (grub_uint8_t *) args, len, NULL);
2131+-
2132+- grub_dprintf ("linux", "starting image %p\n", image_handle);
2133+- status = b->start_image (image_handle, 0, NULL);
2134+-
2135+- /* When successful, not reached */
2136+- b->unload_image (image_handle);
2137+- grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
2138+- GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
2139+-
2140+- return grub_errno;
2141+-}
2142+-
2143+-static grub_err_t
2144+-grub_linux_boot (void)
2145+-{
2146+- if (finalize_params_linux () != GRUB_ERR_NONE)
2147+- return grub_errno;
2148+-
2149+- return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
2150+- kernel_size, linux_args));
2151+-}
2152+-
2153+-static grub_err_t
2154+-grub_linux_unload (void)
2155+-{
2156+- grub_dl_unref (my_mod);
2157+- loaded = 0;
2158+- if (initrd_start)
2159+- grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
2160+- GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
2161+- initrd_start = initrd_end = 0;
2162+- grub_free (linux_args);
2163+- if (kernel_addr)
2164+- grub_efi_free_pages ((grub_addr_t) kernel_addr,
2165+- GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2166+- grub_fdt_unload ();
2167+- return GRUB_ERR_NONE;
2168+-}
2169+-
2170+-/*
2171+- * As per linux/Documentation/arm/Booting
2172+- * ARM initrd needs to be covered by kernel linear mapping,
2173+- * so place it in the first 512MB of DRAM.
2174+- *
2175+- * As per linux/Documentation/arm64/booting.txt
2176+- * ARM64 initrd needs to be contained entirely within a 1GB aligned window
2177+- * of up to 32GB of size that covers the kernel image as well.
2178+- * Since the EFI stub loader will attempt to load the kernel near start of
2179+- * RAM, place the buffer in the first 32GB of RAM.
2180+- */
2181+-#ifdef __arm__
2182+-#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
2183+-#else /* __aarch64__ */
2184+-#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
2185+-#endif
2186+-
2187+-/*
2188+- * This function returns a pointer to a legally allocated initrd buffer,
2189+- * or NULL if unsuccessful
2190+- */
2191+-static void *
2192+-allocate_initrd_mem (int initrd_pages)
2193+-{
2194+- grub_addr_t max_addr;
2195+-
2196+- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
2197+- return NULL;
2198+-
2199+- max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
2200+-
2201+- return grub_efi_allocate_pages_real (max_addr, initrd_pages,
2202+- GRUB_EFI_ALLOCATE_MAX_ADDRESS,
2203+- GRUB_EFI_LOADER_DATA);
2204+-}
2205+-
2206+-struct initrd_media_device_path {
2207+- grub_efi_vendor_media_device_path_t vendor;
2208+- grub_efi_device_path_t end;
2209+-} GRUB_PACKED;
2210+-
2211+-#define LINUX_EFI_INITRD_MEDIA_GUID \
2212+- { 0x5568e427, 0x68fc, 0x4f3d, \
2213+- { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \
2214+- }
2215+-
2216+-static struct initrd_media_device_path initrd_lf2_device_path = {
2217+- {
2218+- {
2219+- GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
2220+- GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
2221+- sizeof(grub_efi_vendor_media_device_path_t),
2222+- },
2223+- LINUX_EFI_INITRD_MEDIA_GUID
2224+- }, {
2225+- GRUB_EFI_END_DEVICE_PATH_TYPE,
2226+- GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
2227+- sizeof(grub_efi_device_path_t)
2228+- }
2229+-};
2230+-
2231+-static grub_efi_status_t
2232+-grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
2233+- grub_efi_device_path_t *device_path,
2234+- grub_efi_boolean_t boot_policy,
2235+- grub_efi_uintn_t *buffer_size,
2236+- void *buffer);
2237+-
2238+-static grub_efi_load_file2_t initrd_lf2 = {
2239+- grub_efi_initrd_load_file2
2240+-};
2241+-
2242+-static grub_efi_status_t
2243+-grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
2244+- grub_efi_device_path_t *device_path,
2245+- grub_efi_boolean_t boot_policy,
2246+- grub_efi_uintn_t *buffer_size,
2247+- void *buffer)
2248+-{
2249+- grub_efi_status_t status = GRUB_EFI_SUCCESS;
2250+- grub_efi_uintn_t initrd_size;
2251+-
2252+- if (!this || this != &initrd_lf2 || !buffer_size)
2253+- return GRUB_EFI_INVALID_PARAMETER;
2254+-
2255+- if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE ||
2256+- device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
2257+- return GRUB_EFI_NOT_FOUND;
2258+-
2259+- if (boot_policy)
2260+- return GRUB_EFI_UNSUPPORTED;
2261+-
2262+- initrd_size = grub_get_initrd_size (&initrd_ctx);
2263+- if (!buffer || *buffer_size < initrd_size)
2264+- {
2265+- *buffer_size = initrd_size;
2266+- return GRUB_EFI_BUFFER_TOO_SMALL;
2267+- }
2268+-
2269+- grub_dprintf ("linux", "Providing initrd via LOAD_FILE2_PROTOCOL\n");
2270+-
2271+- if (grub_initrd_load (&initrd_ctx, buffer))
2272+- status = GRUB_EFI_LOAD_ERROR;
2273+-
2274+- grub_initrd_close (&initrd_ctx);
2275+- return status;
2276+-}
2277+-
2278+-static grub_err_t
2279+-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
2280+- int argc, char *argv[])
2281+-{
2282+- int initrd_size, initrd_pages;
2283+- void *initrd_mem = NULL;
2284+- grub_efi_boot_services_t *b;
2285+- grub_efi_status_t status;
2286+-
2287+- if (argc == 0)
2288+- {
2289+- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
2290+- goto fail;
2291+- }
2292+-
2293+- if (!loaded)
2294+- {
2295+- grub_error (GRUB_ERR_BAD_ARGUMENT,
2296+- N_("you need to load the kernel first"));
2297+- goto fail;
2298+- }
2299+-
2300+- if (grub_initrd_init (argc, argv, &initrd_ctx))
2301+- goto fail;
2302+-
2303+- if (initrd_use_loadfile2 && !initrd_lf2_handle)
2304+- {
2305+- b = grub_efi_system_table->boot_services;
2306+- status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle,
2307+- &load_file2_guid,
2308+- &initrd_lf2,
2309+- &device_path_guid,
2310+- &initrd_lf2_device_path,
2311+- NULL);
2312+- if (status == GRUB_EFI_OUT_OF_RESOURCES)
2313+- {
2314+- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2315+- return grub_errno;
2316+- }
2317+- grub_dprintf ("linux", "LoadFile2 initrd loading protocol installed\n");
2318+- return GRUB_ERR_NONE;
2319+- }
2320+-
2321+- initrd_size = grub_get_initrd_size (&initrd_ctx);
2322+- grub_dprintf ("linux", "Loading initrd\n");
2323+-
2324+- initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
2325+- initrd_mem = allocate_initrd_mem (initrd_pages);
2326+-
2327+- if (!initrd_mem)
2328+- {
2329+- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2330+- goto fail;
2331+- }
2332+-
2333+- if (grub_initrd_load (&initrd_ctx, initrd_mem))
2334+- goto fail;
2335+-
2336+- initrd_start = (grub_addr_t) initrd_mem;
2337+- initrd_end = initrd_start + initrd_size;
2338+- grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
2339+- (void *) initrd_start, initrd_size);
2340+-
2341+- fail:
2342+- grub_initrd_close (&initrd_ctx);
2343+- if (initrd_mem && !initrd_start)
2344+- grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
2345+-
2346+- return grub_errno;
2347+-}
2348+-
2349+-static grub_err_t
2350+-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
2351+- int argc, char *argv[])
2352+-{
2353+- grub_file_t file = 0;
2354+- struct linux_arch_kernel_header lh;
2355+- grub_err_t err;
2356+-
2357+- grub_dl_ref (my_mod);
2358+-
2359+- if (argc == 0)
2360+- {
2361+- grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
2362+- goto fail;
2363+- }
2364+-
2365+- file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
2366+- if (!file)
2367+- goto fail;
2368+-
2369+- kernel_size = grub_file_size (file);
2370+-
2371+- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
2372+- return grub_errno;
2373+-
2374+- if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
2375+- goto fail;
2376+-
2377+- grub_loader_unset();
2378+-
2379+- grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
2380+- kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2381+- grub_dprintf ("linux", "kernel numpages: %lld\n",
2382+- (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2383+- if (!kernel_addr)
2384+- {
2385+- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2386+- goto fail;
2387+- }
2388+-
2389+- grub_file_seek (file, 0);
2390+- if (grub_file_read (file, kernel_addr, kernel_size)
2391+- < (grub_int64_t) kernel_size)
2392+- {
2393+- if (!grub_errno)
2394+- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
2395+- goto fail;
2396+- }
2397+-
2398+- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
2399+-
2400+- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
2401+- linux_args = grub_malloc (cmdline_size);
2402+- if (!linux_args)
2403+- {
2404+- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2405+- goto fail;
2406+- }
2407+- grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
2408+- err = grub_create_loader_cmdline (argc, argv,
2409+- linux_args + sizeof (LINUX_IMAGE) - 1,
2410+- cmdline_size,
2411+- GRUB_VERIFY_KERNEL_CMDLINE);
2412+- if (err)
2413+- goto fail;
2414+-
2415+- if (grub_errno == GRUB_ERR_NONE)
2416+- {
2417+- grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
2418+- loaded = 1;
2419+- }
2420+-
2421+-fail:
2422+- if (file)
2423+- grub_file_close (file);
2424+-
2425+- if (grub_errno != GRUB_ERR_NONE)
2426+- {
2427+- grub_dl_unref (my_mod);
2428+- loaded = 0;
2429+- }
2430+-
2431+- if (linux_args && !loaded)
2432+- grub_free (linux_args);
2433+-
2434+- if (kernel_addr && !loaded)
2435+- grub_efi_free_pages ((grub_addr_t) kernel_addr,
2436+- GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2437+-
2438+- return grub_errno;
2439+-}
2440+-
2441+-
2442+-static grub_command_t cmd_linux, cmd_initrd;
2443+-
2444+-GRUB_MOD_INIT (linux)
2445+-{
2446+- cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
2447+- N_("Load Linux."));
2448+- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
2449+- N_("Load initrd."));
2450+- my_mod = mod;
2451+-}
2452+-
2453+-GRUB_MOD_FINI (linux)
2454+-{
2455+- grub_unregister_command (cmd_linux);
2456+- grub_unregister_command (cmd_initrd);
2457+-}
2458+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
2459+new file mode 100644
2460+index 0000000..3292cab
2461+--- /dev/null
2462++++ b/grub-core/loader/efi/linux.c
2463+@@ -0,0 +1,508 @@
2464++/*
2465++ * GRUB -- GRand Unified Bootloader
2466++ * Copyright (C) 2013 Free Software Foundation, Inc.
2467++ *
2468++ * GRUB is free software: you can redistribute it and/or modify
2469++ * it under the terms of the GNU General Public License as published by
2470++ * the Free Software Foundation, either version 3 of the License, or
2471++ * (at your option) any later version.
2472++ *
2473++ * GRUB is distributed in the hope that it will be useful,
2474++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2475++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2476++ * GNU General Public License for more details.
2477++ *
2478++ * You should have received a copy of the GNU General Public License
2479++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
2480++ */
2481++
2482++#include <grub/charset.h>
2483++#include <grub/command.h>
2484++#include <grub/err.h>
2485++#include <grub/file.h>
2486++#include <grub/fdt.h>
2487++#include <grub/linux.h>
2488++#include <grub/loader.h>
2489++#include <grub/mm.h>
2490++#include <grub/types.h>
2491++#include <grub/cpu/linux.h>
2492++#include <grub/efi/efi.h>
2493++#include <grub/efi/fdtload.h>
2494++#include <grub/efi/memory.h>
2495++#include <grub/efi/pe32.h>
2496++#include <grub/i18n.h>
2497++#include <grub/lib/cmdline.h>
2498++#include <grub/verify.h>
2499++
2500++GRUB_MOD_LICENSE ("GPLv3+");
2501++
2502++static grub_dl_t my_mod;
2503++static int loaded;
2504++
2505++static void *kernel_addr;
2506++static grub_uint64_t kernel_size;
2507++
2508++static char *linux_args;
2509++static grub_uint32_t cmdline_size;
2510++
2511++static grub_addr_t initrd_start;
2512++static grub_addr_t initrd_end;
2513++
2514++static struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
2515++static grub_efi_handle_t initrd_lf2_handle;
2516++static int initrd_use_loadfile2;
2517++static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
2518++static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
2519++
2520++grub_err_t
2521++grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
2522++{
2523++ struct grub_pe32_coff_header *coff_header;
2524++ struct grub_pe32_optional_header *optional_header;
2525++
2526++ if (lh->magic != GRUB_LINUX_ARCH_MAGIC_SIGNATURE)
2527++ return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
2528++
2529++ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
2530++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
2531++ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
2532++
2533++ grub_dprintf ("linux", "UEFI stub kernel:\n");
2534++ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
2535++
2536++ coff_header = (struct grub_pe32_coff_header *)((unsigned long)lh + lh->hdr_offset);
2537++ optional_header = (struct grub_pe32_optional_header *)(coff_header + 1);
2538++
2539++ /*
2540++ * Linux kernels built for any architecture are guaranteed to support the
2541++ * LoadFile2 based initrd loading protocol if the image version is >= 1.
2542++ */
2543++ if (optional_header->major_image_version >= 1)
2544++ initrd_use_loadfile2 = 1;
2545++ else
2546++ initrd_use_loadfile2 = 0;
2547++
2548++ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
2549++ initrd_use_loadfile2 ? "en" : "dis");
2550++
2551++ return GRUB_ERR_NONE;
2552++}
2553++
2554++static grub_err_t
2555++finalize_params_linux (void)
2556++{
2557++ int node, retval;
2558++
2559++ void *fdt = NULL;
2560++
2561++ /* Set initrd info */
2562++ if (initrd_start && initrd_end > initrd_start)
2563++ {
2564++ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
2565++
2566++ if (!fdt)
2567++ goto failure;
2568++
2569++ node = grub_fdt_find_subnode (fdt, 0, "chosen");
2570++ if (node < 0)
2571++ node = grub_fdt_add_subnode (fdt, 0, "chosen");
2572++
2573++ if (node < 1)
2574++ goto failure;
2575++
2576++ grub_dprintf ("linux", "Initrd @ %p-%p\n",
2577++ (void *) initrd_start, (void *) initrd_end);
2578++
2579++ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
2580++ initrd_start);
2581++ if (retval)
2582++ goto failure;
2583++ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
2584++ initrd_end);
2585++ if (retval)
2586++ goto failure;
2587++ }
2588++
2589++ if (grub_fdt_install() != GRUB_ERR_NONE)
2590++ goto failure;
2591++
2592++ return GRUB_ERR_NONE;
2593++
2594++failure:
2595++ grub_fdt_unload();
2596++ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
2597++}
2598++
2599++grub_err_t
2600++grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
2601++{
2602++ grub_efi_memory_mapped_device_path_t *mempath;
2603++ grub_efi_handle_t image_handle;
2604++ grub_efi_boot_services_t *b;
2605++ grub_efi_status_t status;
2606++ grub_efi_loaded_image_t *loaded_image;
2607++ int len;
2608++
2609++ mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t));
2610++ if (!mempath)
2611++ return grub_errno;
2612++
2613++ mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE;
2614++ mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE;
2615++ mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath));
2616++ mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
2617++ mempath[0].start_address = addr;
2618++ mempath[0].end_address = addr + size;
2619++
2620++ mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
2621++ mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
2622++ mempath[1].header.length = sizeof (grub_efi_device_path_t);
2623++
2624++ b = grub_efi_system_table->boot_services;
2625++ status = b->load_image (0, grub_efi_image_handle,
2626++ (grub_efi_device_path_t *) mempath,
2627++ (void *) addr, size, &image_handle);
2628++ if (status != GRUB_EFI_SUCCESS)
2629++ return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
2630++
2631++ grub_dprintf ("linux", "linux command line: '%s'\n", args);
2632++
2633++ /* Convert command line to UCS-2 */
2634++ loaded_image = grub_efi_get_loaded_image (image_handle);
2635++ loaded_image->load_options_size = len =
2636++ (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
2637++ loaded_image->load_options =
2638++ grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
2639++ if (!loaded_image->load_options)
2640++ return grub_errno;
2641++
2642++ loaded_image->load_options_size =
2643++ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
2644++ (grub_uint8_t *) args, len, NULL);
2645++
2646++ grub_dprintf ("linux", "starting image %p\n", image_handle);
2647++ status = b->start_image (image_handle, 0, NULL);
2648++
2649++ /* When successful, not reached */
2650++ b->unload_image (image_handle);
2651++ grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
2652++ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
2653++
2654++ return grub_errno;
2655++}
2656++
2657++static grub_err_t
2658++grub_linux_boot (void)
2659++{
2660++ if (finalize_params_linux () != GRUB_ERR_NONE)
2661++ return grub_errno;
2662++
2663++ return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
2664++ kernel_size, linux_args));
2665++}
2666++
2667++static grub_err_t
2668++grub_linux_unload (void)
2669++{
2670++ grub_dl_unref (my_mod);
2671++ loaded = 0;
2672++ if (initrd_start)
2673++ grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
2674++ GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
2675++ initrd_start = initrd_end = 0;
2676++ grub_free (linux_args);
2677++ if (kernel_addr)
2678++ grub_efi_free_pages ((grub_addr_t) kernel_addr,
2679++ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2680++ grub_fdt_unload ();
2681++ return GRUB_ERR_NONE;
2682++}
2683++
2684++/*
2685++ * As per linux/Documentation/arm/Booting
2686++ * ARM initrd needs to be covered by kernel linear mapping,
2687++ * so place it in the first 512MB of DRAM.
2688++ *
2689++ * As per linux/Documentation/arm64/booting.txt
2690++ * ARM64 initrd needs to be contained entirely within a 1GB aligned window
2691++ * of up to 32GB of size that covers the kernel image as well.
2692++ * Since the EFI stub loader will attempt to load the kernel near start of
2693++ * RAM, place the buffer in the first 32GB of RAM.
2694++ */
2695++#ifdef __arm__
2696++#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
2697++#else /* __aarch64__ */
2698++#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
2699++#endif
2700++
2701++/*
2702++ * This function returns a pointer to a legally allocated initrd buffer,
2703++ * or NULL if unsuccessful
2704++ */
2705++static void *
2706++allocate_initrd_mem (int initrd_pages)
2707++{
2708++ grub_addr_t max_addr;
2709++
2710++ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
2711++ return NULL;
2712++
2713++ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
2714++
2715++ return grub_efi_allocate_pages_real (max_addr, initrd_pages,
2716++ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
2717++ GRUB_EFI_LOADER_DATA);
2718++}
2719++
2720++struct initrd_media_device_path {
2721++ grub_efi_vendor_media_device_path_t vendor;
2722++ grub_efi_device_path_t end;
2723++} GRUB_PACKED;
2724++
2725++#define LINUX_EFI_INITRD_MEDIA_GUID \
2726++ { 0x5568e427, 0x68fc, 0x4f3d, \
2727++ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \
2728++ }
2729++
2730++static struct initrd_media_device_path initrd_lf2_device_path = {
2731++ {
2732++ {
2733++ GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
2734++ GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
2735++ sizeof(grub_efi_vendor_media_device_path_t),
2736++ },
2737++ LINUX_EFI_INITRD_MEDIA_GUID
2738++ }, {
2739++ GRUB_EFI_END_DEVICE_PATH_TYPE,
2740++ GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
2741++ sizeof(grub_efi_device_path_t)
2742++ }
2743++};
2744++
2745++static grub_efi_status_t
2746++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
2747++ grub_efi_device_path_t *device_path,
2748++ grub_efi_boolean_t boot_policy,
2749++ grub_efi_uintn_t *buffer_size,
2750++ void *buffer);
2751++
2752++static grub_efi_load_file2_t initrd_lf2 = {
2753++ grub_efi_initrd_load_file2
2754++};
2755++
2756++static grub_efi_status_t
2757++grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
2758++ grub_efi_device_path_t *device_path,
2759++ grub_efi_boolean_t boot_policy,
2760++ grub_efi_uintn_t *buffer_size,
2761++ void *buffer)
2762++{
2763++ grub_efi_status_t status = GRUB_EFI_SUCCESS;
2764++ grub_efi_uintn_t initrd_size;
2765++
2766++ if (!this || this != &initrd_lf2 || !buffer_size)
2767++ return GRUB_EFI_INVALID_PARAMETER;
2768++
2769++ if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE ||
2770++ device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
2771++ return GRUB_EFI_NOT_FOUND;
2772++
2773++ if (boot_policy)
2774++ return GRUB_EFI_UNSUPPORTED;
2775++
2776++ initrd_size = grub_get_initrd_size (&initrd_ctx);
2777++ if (!buffer || *buffer_size < initrd_size)
2778++ {
2779++ *buffer_size = initrd_size;
2780++ return GRUB_EFI_BUFFER_TOO_SMALL;
2781++ }
2782++
2783++ grub_dprintf ("linux", "Providing initrd via LOAD_FILE2_PROTOCOL\n");
2784++
2785++ if (grub_initrd_load (&initrd_ctx, buffer))
2786++ status = GRUB_EFI_LOAD_ERROR;
2787++
2788++ grub_initrd_close (&initrd_ctx);
2789++ return status;
2790++}
2791++
2792++static grub_err_t
2793++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
2794++ int argc, char *argv[])
2795++{
2796++ int initrd_size, initrd_pages;
2797++ void *initrd_mem = NULL;
2798++ grub_efi_boot_services_t *b;
2799++ grub_efi_status_t status;
2800++
2801++ if (argc == 0)
2802++ {
2803++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
2804++ goto fail;
2805++ }
2806++
2807++ if (!loaded)
2808++ {
2809++ grub_error (GRUB_ERR_BAD_ARGUMENT,
2810++ N_("you need to load the kernel first"));
2811++ goto fail;
2812++ }
2813++
2814++ if (grub_initrd_init (argc, argv, &initrd_ctx))
2815++ goto fail;
2816++
2817++ if (initrd_use_loadfile2 && !initrd_lf2_handle)
2818++ {
2819++ b = grub_efi_system_table->boot_services;
2820++ status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle,
2821++ &load_file2_guid,
2822++ &initrd_lf2,
2823++ &device_path_guid,
2824++ &initrd_lf2_device_path,
2825++ NULL);
2826++ if (status == GRUB_EFI_OUT_OF_RESOURCES)
2827++ {
2828++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2829++ return grub_errno;
2830++ }
2831++ grub_dprintf ("linux", "LoadFile2 initrd loading protocol installed\n");
2832++ return GRUB_ERR_NONE;
2833++ }
2834++
2835++ initrd_size = grub_get_initrd_size (&initrd_ctx);
2836++ grub_dprintf ("linux", "Loading initrd\n");
2837++
2838++ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
2839++ initrd_mem = allocate_initrd_mem (initrd_pages);
2840++
2841++ if (!initrd_mem)
2842++ {
2843++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2844++ goto fail;
2845++ }
2846++
2847++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
2848++ goto fail;
2849++
2850++ initrd_start = (grub_addr_t) initrd_mem;
2851++ initrd_end = initrd_start + initrd_size;
2852++ grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
2853++ (void *) initrd_start, initrd_size);
2854++
2855++ fail:
2856++ grub_initrd_close (&initrd_ctx);
2857++ if (initrd_mem && !initrd_start)
2858++ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
2859++
2860++ return grub_errno;
2861++}
2862++
2863++static grub_err_t
2864++grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
2865++ int argc, char *argv[])
2866++{
2867++ grub_file_t file = 0;
2868++ struct linux_arch_kernel_header lh;
2869++ grub_err_t err;
2870++
2871++ grub_dl_ref (my_mod);
2872++
2873++ if (argc == 0)
2874++ {
2875++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
2876++ goto fail;
2877++ }
2878++
2879++ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
2880++ if (!file)
2881++ goto fail;
2882++
2883++ kernel_size = grub_file_size (file);
2884++
2885++ if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
2886++ return grub_errno;
2887++
2888++ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
2889++ goto fail;
2890++
2891++ grub_loader_unset();
2892++
2893++ grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
2894++ kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2895++ grub_dprintf ("linux", "kernel numpages: %lld\n",
2896++ (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2897++ if (!kernel_addr)
2898++ {
2899++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2900++ goto fail;
2901++ }
2902++
2903++ grub_file_seek (file, 0);
2904++ if (grub_file_read (file, kernel_addr, kernel_size)
2905++ < (grub_int64_t) kernel_size)
2906++ {
2907++ if (!grub_errno)
2908++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
2909++ goto fail;
2910++ }
2911++
2912++ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
2913++
2914++ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
2915++ linux_args = grub_malloc (cmdline_size);
2916++ if (!linux_args)
2917++ {
2918++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
2919++ goto fail;
2920++ }
2921++ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
2922++ err = grub_create_loader_cmdline (argc, argv,
2923++ linux_args + sizeof (LINUX_IMAGE) - 1,
2924++ cmdline_size,
2925++ GRUB_VERIFY_KERNEL_CMDLINE);
2926++ if (err)
2927++ goto fail;
2928++
2929++ if (grub_errno == GRUB_ERR_NONE)
2930++ {
2931++ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
2932++ loaded = 1;
2933++ }
2934++
2935++fail:
2936++ if (file)
2937++ grub_file_close (file);
2938++
2939++ if (grub_errno != GRUB_ERR_NONE)
2940++ {
2941++ grub_dl_unref (my_mod);
2942++ loaded = 0;
2943++ }
2944++
2945++ if (linux_args && !loaded)
2946++ grub_free (linux_args);
2947++
2948++ if (kernel_addr && !loaded)
2949++ grub_efi_free_pages ((grub_addr_t) kernel_addr,
2950++ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
2951++
2952++ return grub_errno;
2953++}
2954++
2955++
2956++static grub_command_t cmd_linux, cmd_initrd;
2957++
2958++GRUB_MOD_INIT (linux)
2959++{
2960++ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
2961++ N_("Load Linux."));
2962++ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
2963++ N_("Load initrd."));
2964++ my_mod = mod;
2965++}
2966++
2967++GRUB_MOD_FINI (linux)
2968++{
2969++ grub_unregister_command (cmd_linux);
2970++ grub_unregister_command (cmd_initrd);
2971++}
2972+diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
2973+index bcd5a7e..8c13978 100644
2974+--- a/include/grub/arm/linux.h
2975++++ b/include/grub/arm/linux.h
2976+@@ -35,7 +35,7 @@ struct linux_arm_kernel_header {
2977+ };
2978+
2979+ #if defined(__arm__)
2980+-# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
2981++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
2982+ # define linux_arch_kernel_header linux_arm_kernel_header
2983+ #endif
2984+
2985+diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
2986+index 7e22b4a..effd870 100644
2987+--- a/include/grub/arm64/linux.h
2988++++ b/include/grub/arm64/linux.h
2989+@@ -39,7 +39,7 @@ struct linux_arm64_kernel_header
2990+ };
2991+
2992+ #if defined(__aarch64__)
2993+-# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
2994++# define GRUB_LINUX_ARCH_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
2995+ # define linux_arch_kernel_header linux_arm64_kernel_header
2996+ #endif
2997+
2998diff --git a/debian/patches/loader-drop-argv-argument-in-grub_initrd_load.patch b/debian/patches/loader-drop-argv-argument-in-grub_initrd_load.patch
2999new file mode 100644
3000index 0000000..a5af0f5
3001--- /dev/null
3002+++ b/debian/patches/loader-drop-argv-argument-in-grub_initrd_load.patch
3003@@ -0,0 +1,178 @@
3004+From: Nikita Ermakov <arei@altlinux.org>
3005+Date: Thu, 28 Oct 2021 23:31:13 +0300
3006+Subject: loader: drop argv[] argument in grub_initrd_load()
3007+
3008+In the case of an error grub_initrd_load() uses argv[] to print the
3009+filename that caused the error. It is also possible to obtain the
3010+filename from the file handles and there is no need to duplicate that
3011+information in argv[], so let's drop it.
3012+
3013+Signed-off-by: Nikita Ermakov <arei@altlinux.org>
3014+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3015+
3016+Last-Update: 2022-01-03
3017+Origin: https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00212.html
3018+---
3019+ grub-core/loader/arm/linux.c | 2 +-
3020+ grub-core/loader/arm64/linux.c | 2 +-
3021+ grub-core/loader/i386/linux.c | 2 +-
3022+ grub-core/loader/i386/pc/linux.c | 2 +-
3023+ grub-core/loader/i386/xen.c | 3 +--
3024+ grub-core/loader/ia64/efi/linux.c | 2 +-
3025+ grub-core/loader/linux.c | 4 ++--
3026+ grub-core/loader/mips/linux.c | 2 +-
3027+ grub-core/loader/powerpc/ieee1275/linux.c | 2 +-
3028+ grub-core/loader/sparc64/ieee1275/linux.c | 2 +-
3029+ include/grub/linux.h | 2 +-
3030+ 11 files changed, 12 insertions(+), 13 deletions(-)
3031+
3032+diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
3033+index ed23dc7..1f7ab75 100644
3034+--- a/grub-core/loader/arm/linux.c
3035++++ b/grub-core/loader/arm/linux.c
3036+@@ -422,7 +422,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3037+ grub_dprintf ("loader", "Loading initrd to 0x%08x\n",
3038+ (grub_addr_t) initrd_start);
3039+
3040+- if (grub_initrd_load (&initrd_ctx, argv, (void *) initrd_start))
3041++ if (grub_initrd_load (&initrd_ctx, (void *) initrd_start))
3042+ goto fail;
3043+
3044+ initrd_end = initrd_start + size;
3045+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
3046+index ef3e9f9..aed7a20 100644
3047+--- a/grub-core/loader/arm64/linux.c
3048++++ b/grub-core/loader/arm64/linux.c
3049+@@ -266,7 +266,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3050+ goto fail;
3051+ }
3052+
3053+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
3054++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
3055+ goto fail;
3056+
3057+ initrd_start = (grub_addr_t) initrd_mem;
3058+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
3059+index 9f74a96..f30a158 100644
3060+--- a/grub-core/loader/i386/linux.c
3061++++ b/grub-core/loader/i386/linux.c
3062+@@ -1107,7 +1107,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3063+ initrd_mem_target = get_physical_target_address (ch);
3064+ }
3065+
3066+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
3067++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
3068+ goto fail;
3069+
3070+ grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
3071+diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
3072+index 2a29952..efeeeb2 100644
3073+--- a/grub-core/loader/i386/pc/linux.c
3074++++ b/grub-core/loader/i386/pc/linux.c
3075+@@ -462,7 +462,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3076+ initrd_addr = get_physical_target_address (ch);
3077+ }
3078+
3079+- if (grub_initrd_load (&initrd_ctx, argv, initrd_chunk))
3080++ if (grub_initrd_load (&initrd_ctx, initrd_chunk))
3081+ goto fail;
3082+
3083+ lh->ramdisk_image = initrd_addr;
3084+diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
3085+index cd24874..3b856e8 100644
3086+--- a/grub-core/loader/i386/xen.c
3087++++ b/grub-core/loader/i386/xen.c
3088+@@ -809,8 +809,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3089+ if (err)
3090+ goto fail;
3091+
3092+- if (grub_initrd_load (&initrd_ctx, argv,
3093+- get_virtual_current_address (ch)))
3094++ if (grub_initrd_load (&initrd_ctx, get_virtual_current_address (ch)))
3095+ goto fail;
3096+ }
3097+
3098+diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c
3099+index 7987fd1..8873b7a 100644
3100+--- a/grub-core/loader/ia64/efi/linux.c
3101++++ b/grub-core/loader/ia64/efi/linux.c
3102+@@ -563,7 +563,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3103+ grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n",
3104+ (grub_uint64_t) initrd_mem, initrd_size);
3105+
3106+- if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
3107++ if (grub_initrd_load (&initrd_ctx, initrd_mem))
3108+ goto fail;
3109+ fail:
3110+ grub_initrd_close (&initrd_ctx);
3111+diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
3112+index 3fe390f..d19df67 100644
3113+--- a/grub-core/loader/linux.c
3114++++ b/grub-core/loader/linux.c
3115+@@ -271,7 +271,7 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
3116+
3117+ grub_err_t
3118+ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
3119+- char *argv[], void *target)
3120++ void *target)
3121+ {
3122+ grub_uint8_t *ptr = target;
3123+ int i;
3124+@@ -317,7 +317,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
3125+ {
3126+ if (!grub_errno)
3127+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
3128+- argv[i]);
3129++ initrd_ctx->components[i].file->name);
3130+ grub_initrd_close (initrd_ctx);
3131+ return grub_errno;
3132+ }
3133+diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
3134+index e4ed959..9459472 100644
3135+--- a/grub-core/loader/mips/linux.c
3136++++ b/grub-core/loader/mips/linux.c
3137+@@ -452,7 +452,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3138+ initrd_dest = get_physical_target_address (ch) | 0x80000000;
3139+ }
3140+
3141+- if (grub_initrd_load (&initrd_ctx, argv, initrd_src))
3142++ if (grub_initrd_load (&initrd_ctx, initrd_src))
3143+ goto fail;
3144+
3145+ #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
3146+diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
3147+index 818b2a8..a51e7a7 100644
3148+--- a/grub-core/loader/powerpc/ieee1275/linux.c
3149++++ b/grub-core/loader/powerpc/ieee1275/linux.c
3150+@@ -363,7 +363,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3151+
3152+ grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
3153+
3154+- if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
3155++ if (grub_initrd_load (&initrd_ctx, (void *) addr))
3156+ goto fail;
3157+
3158+ initrd_addr = addr;
3159+diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
3160+index bb47ee0..ac2206f 100644
3161+--- a/grub-core/loader/sparc64/ieee1275/linux.c
3162++++ b/grub-core/loader/sparc64/ieee1275/linux.c
3163+@@ -413,7 +413,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
3164+ grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
3165+ addr, paddr, size);
3166+
3167+- if (grub_initrd_load (&initrd_ctx, argv, (void *) addr))
3168++ if (grub_initrd_load (&initrd_ctx, (void *) addr))
3169+ goto fail;
3170+
3171+ initrd_addr = addr;
3172+diff --git a/include/grub/linux.h b/include/grub/linux.h
3173+index 594a3f3..a96ac20 100644
3174+--- a/include/grub/linux.h
3175++++ b/include/grub/linux.h
3176+@@ -21,4 +21,4 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx);
3177+
3178+ grub_err_t
3179+ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
3180+- char *argv[], void *target);
3181++ void *target);
3182diff --git a/debian/patches/maybe-quiet.patch b/debian/patches/maybe-quiet.patch
3183index 819d9ca..5833f08 100644
3184--- a/debian/patches/maybe-quiet.patch
3185+++ b/debian/patches/maybe-quiet.patch
3186@@ -58,10 +58,10 @@ index 9e8f991..d2c4ce8 100644
3187 /* We don't need those. */
3188 #define MINILZO_CFG_SKIP_LZO_PTR 1
3189 diff --git a/configure.ac b/configure.ac
3190-index 74778a6..256fc44 100644
3191+index fb980fd..2869155 100644
3192 --- a/configure.ac
3193 +++ b/configure.ac
3194-@@ -1915,6 +1915,17 @@ else
3195+@@ -1923,6 +1923,17 @@ else
3196 fi
3197 AC_SUBST([UBUNTU_RECOVERY])
3198
3199@@ -79,7 +79,7 @@ index 74778a6..256fc44 100644
3200 LIBS=""
3201
3202 AC_SUBST([FONT_SOURCE])
3203-@@ -2177,5 +2188,10 @@ echo "With stack smashing protector: Yes"
3204+@@ -2185,5 +2196,10 @@ echo "With stack smashing protector: Yes"
3205 else
3206 echo "With stack smashing protector: No"
3207 fi
3208diff --git a/debian/patches/mkconfig-ubuntu-recovery.patch b/debian/patches/mkconfig-ubuntu-recovery.patch
3209index 43beada..4d7a67d 100644
3210--- a/debian/patches/mkconfig-ubuntu-recovery.patch
3211+++ b/debian/patches/mkconfig-ubuntu-recovery.patch
3212@@ -22,10 +22,10 @@ Patch-Name: mkconfig-ubuntu-recovery.patch
3213 3 files changed, 26 insertions(+), 3 deletions(-)
3214
3215 diff --git a/configure.ac b/configure.ac
3216-index 7517fc4..74778a6 100644
3217+index e3d4d72..fb980fd 100644
3218 --- a/configure.ac
3219 +++ b/configure.ac
3220-@@ -1904,6 +1904,17 @@ fi
3221+@@ -1912,6 +1912,17 @@ fi
3222 AC_SUBST([LIBZFS])
3223 AC_SUBST([LIBNVPAIR])
3224
3225diff --git a/debian/patches/no-devicetree-if-secure-boot.patch b/debian/patches/no-devicetree-if-secure-boot.patch
3226index 3659f2d..50baa90 100644
3227--- a/debian/patches/no-devicetree-if-secure-boot.patch
3228+++ b/debian/patches/no-devicetree-if-secure-boot.patch
3229@@ -16,7 +16,7 @@ Patch-Name: no-devicetree-if-secure-boot.patch
3230 2 files changed, 20 insertions(+)
3231
3232 diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
3233-index ed23dc7..2c85ca8 100644
3234+index 1f7ab75..feb707b 100644
3235 --- a/grub-core/loader/arm/linux.c
3236 +++ b/grub-core/loader/arm/linux.c
3237 @@ -30,6 +30,10 @@
3238@@ -46,10 +46,10 @@ index ed23dc7..2c85ca8 100644
3239 if (!dtb)
3240 return grub_errno;
3241 diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
3242-index 7858d35..9b05e7e 100644
3243+index 971e84d..b846bf3 100644
3244 --- a/grub-core/loader/efi/fdt.c
3245 +++ b/grub-core/loader/efi/fdt.c
3246-@@ -128,6 +128,14 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
3247+@@ -131,6 +131,14 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
3248 return GRUB_ERR_NONE;
3249 }
3250
3251diff --git a/debian/patches/pc-verifiers-module.patch b/debian/patches/pc-verifiers-module.patch
3252index 089e9e9..f372dda 100644
3253--- a/debian/patches/pc-verifiers-module.patch
3254+++ b/debian/patches/pc-verifiers-module.patch
3255@@ -52,7 +52,7 @@ index ee88e44..b6872d2 100644
3256 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
3257 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
3258 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
3259-index 10f839b..f953817 100644
3260+index 0d7bce1..f252725 100644
3261 --- a/grub-core/Makefile.core.def
3262 +++ b/grub-core/Makefile.core.def
3263 @@ -141,7 +141,7 @@ kernel = {
3264diff --git a/debian/patches/quick-boot.patch b/debian/patches/quick-boot.patch
3265index b94aadc..a3675ac 100644
3266--- a/debian/patches/quick-boot.patch
3267+++ b/debian/patches/quick-boot.patch
3268@@ -32,10 +32,10 @@ Patch-Name: quick-boot.patch
3269 7 files changed, 141 insertions(+), 13 deletions(-)
3270
3271 diff --git a/configure.ac b/configure.ac
3272-index 256fc44..c42e4c7 100644
3273+index 2869155..4882eba 100644
3274 --- a/configure.ac
3275 +++ b/configure.ac
3276-@@ -1926,6 +1926,17 @@ else
3277+@@ -1934,6 +1934,17 @@ else
3278 fi
3279 AC_SUBST([QUIET_BOOT])
3280
3281diff --git a/debian/patches/riscv-adjust-march-flags-for-binutils-2.38.patch b/debian/patches/riscv-adjust-march-flags-for-binutils-2.38.patch
3282new file mode 100644
3283index 0000000..afddd6c
3284--- /dev/null
3285+++ b/debian/patches/riscv-adjust-march-flags-for-binutils-2.38.patch
3286@@ -0,0 +1,43 @@
3287+From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
3288+Date: Sat, 29 Jan 2022 11:26:58 +0100
3289+Subject: riscv: adjust -march flags for binutils 2.38
3290+
3291+As of version 2.38 binutils defaults to ISA specification version
3292+2019-12-13. This version of the specification has has separated the
3293+the csr read/write (csrr*/csrw*) instructions and the fence.i from
3294+the I extension and put them into separate Zicsr and Zifencei
3295+extensions.
3296+
3297+This implies that we have to adjust the -march flag passed to the
3298+compiler accordingly.
3299+
3300+Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
3301+Origin: https://lists.gnu.org/archive/html/grub-devel/2022-01/msg00173.html
3302+---
3303+ configure.ac | 8 ++++++++
3304+ 1 file changed, 8 insertions(+)
3305+
3306+diff --git a/configure.ac b/configure.ac
3307+index 7517fc4..e3d4d72 100644
3308+--- a/configure.ac
3309++++ b/configure.ac
3310+@@ -852,11 +852,19 @@ if test x"$platform" != xemu ; then
3311+ CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
3312+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
3313+ [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
3314++ # ISA spec version 20191213 factored out extensions Zicsr and Zifencei
3315++ CFLAGS="$TARGET_CFLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Werror"
3316++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
3317++ [grub_cv_target_cc_soft_float="-march=rv32imac_zicsr_zifencei -mabi=ilp32"], [])
3318+ fi
3319+ if test "x$target_cpu" = xriscv64; then
3320+ CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
3321+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
3322+ [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
3323++ # ISA spec version 20191213 factored out extensions Zicsr and Zifencei
3324++ CFLAGS="$TARGET_CFLAGS -march=rv64imac_zicsr_zifencei -mabi=lp64 -Werror"
3325++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
3326++ [grub_cv_target_cc_soft_float="-march=rv64imac_zicsr_zifencei -mabi=lp64"], [])
3327+ fi
3328+ if test "x$target_cpu" = xia64; then
3329+ CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
3330diff --git a/debian/patches/series b/debian/patches/series
3331index 0f2405b..9e6fc4f 100644
3332--- a/debian/patches/series
3333+++ b/debian/patches/series
3334@@ -1,3 +1,11 @@
3335+riscv-adjust-march-flags-for-binutils-2.38.patch
3336+loader-drop-argv-argument-in-grub_initrd_load.patch
3337+efi-add-definition-of-LoadFile2-protocol.patch
3338+efi-implemented-LoadFile2-initrd-loading-protocol-fo.patch
3339+linux-ignore-FDT-unless-we-need-to-modify-it.patch
3340+loader-Move-arm64-linux-loader-to-common-code.patch
3341+RISC-V-Update-image-header.patch
3342+RISC-V-Use-common-linux-loader.patch
3343 olpc-prefix-hack.patch
3344 core-in-fs.patch
3345 dpkg-version-comparison.patch
3346@@ -108,4 +116,10 @@ no-devicetree-if-secure-boot.patch
3347 0099-chainloader-Avoid-a-double-free-when-validation-fail.patch
3348 0105-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch
3349 ubuntu-verifiers-last.patch
3350+<<<<<<< debian/patches/series
3351 ubuntu-fuse3.patch
3352+=======
3353+efi-correct-struct-grub_efi_boot_services.patch
3354+efi-implement-grub_efi_run_image.patch
3355+fat-fix-listing-the-root-directory.patch
3356+>>>>>>> debian/patches/series
3357diff --git a/debian/patches/suse-add-support-for-UEFI-network-protocols.patch b/debian/patches/suse-add-support-for-UEFI-network-protocols.patch
3358index 9724f73..262f4d0 100644
3359--- a/debian/patches/suse-add-support-for-UEFI-network-protocols.patch
3360+++ b/debian/patches/suse-add-support-for-UEFI-network-protocols.patch
3361@@ -64,10 +64,10 @@ V6:
3362 create mode 100644 include/grub/net/efi.h
3363
3364 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
3365-index 98cda49..a47c403 100644
3366+index 0b5b4e7..3b06462 100644
3367 --- a/grub-core/Makefile.core.def
3368 +++ b/grub-core/Makefile.core.def
3369-@@ -2322,6 +2322,12 @@ module = {
3370+@@ -2324,6 +2324,12 @@ module = {
3371 common = net/ethernet.c;
3372 common = net/arp.c;
3373 common = net/netbuff.c;
3374@@ -3969,10 +3969,10 @@ index 15a2f29..34bf04f 100644
3375 +#endif
3376 }
3377 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
3378-index 9cab1a5..3b2f2e3 100644
3379+index 479c2a8..3211f04 100644
3380 --- a/include/grub/efi/api.h
3381 +++ b/include/grub/efi/api.h
3382-@@ -608,6 +608,23 @@ typedef grub_uint16_t grub_efi_ipv6_address_t[8];
3383+@@ -613,6 +613,23 @@ typedef grub_uint16_t grub_efi_ipv6_address_t[8];
3384 typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
3385 typedef grub_efi_uint64_t grub_efi_physical_address_t;
3386 typedef grub_efi_uint64_t grub_efi_virtual_address_t;
3387@@ -3996,7 +3996,7 @@ index 9cab1a5..3b2f2e3 100644
3388
3389 struct grub_efi_guid
3390 {
3391-@@ -875,6 +892,8 @@ struct grub_efi_ipv6_device_path
3392+@@ -880,6 +897,8 @@ struct grub_efi_ipv6_device_path
3393 grub_efi_uint16_t remote_port;
3394 grub_efi_uint16_t protocol;
3395 grub_efi_uint8_t static_ip_address;
3396@@ -4005,7 +4005,7 @@ index 9cab1a5..3b2f2e3 100644
3397 } GRUB_PACKED;
3398 typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
3399
3400-@@ -924,6 +943,15 @@ struct grub_efi_uri_device_path
3401+@@ -929,6 +948,15 @@ struct grub_efi_uri_device_path
3402 } GRUB_PACKED;
3403 typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t;
3404
3405@@ -4021,7 +4021,7 @@ index 9cab1a5..3b2f2e3 100644
3406 #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
3407
3408 /* Media Device Path. */
3409-@@ -1006,6 +1034,23 @@ struct grub_efi_bios_device_path
3410+@@ -1011,6 +1039,23 @@ struct grub_efi_bios_device_path
3411 } GRUB_PACKED;
3412 typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
3413
3414@@ -4045,7 +4045,7 @@ index 9cab1a5..3b2f2e3 100644
3415 struct grub_efi_open_protocol_information_entry
3416 {
3417 grub_efi_handle_t agent_handle;
3418-@@ -1497,23 +1542,28 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
3419+@@ -1502,23 +1547,28 @@ typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output
3420
3421 typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
3422
3423@@ -4088,7 +4088,7 @@ index 9cab1a5..3b2f2e3 100644
3424
3425 #define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8
3426 typedef struct {
3427-@@ -1563,17 +1613,31 @@ typedef struct grub_efi_pxe_mode
3428+@@ -1568,17 +1618,31 @@ typedef struct grub_efi_pxe_mode
3429 typedef struct grub_efi_pxe
3430 {
3431 grub_uint64_t rev;
3432@@ -4124,7 +4124,7 @@ index 9cab1a5..3b2f2e3 100644
3433 void (*setpackets) (void);
3434 struct grub_efi_pxe_mode *mode;
3435 } grub_efi_pxe_t;
3436-@@ -1835,6 +1899,44 @@ struct grub_efi_ip4_config2_protocol
3437+@@ -1850,6 +1914,44 @@ struct grub_efi_ip4_config2_protocol
3438 };
3439 typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t;
3440
3441@@ -4169,7 +4169,7 @@ index 9cab1a5..3b2f2e3 100644
3442 enum grub_efi_ip6_config_data_type {
3443 GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO,
3444 GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID,
3445-@@ -1869,6 +1971,49 @@ struct grub_efi_ip6_config_protocol
3446+@@ -1884,6 +1986,49 @@ struct grub_efi_ip6_config_protocol
3447 };
3448 typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t;
3449
3450diff --git a/debian/patches/ubuntu-add-initrd-less-boot-fallback.patch b/debian/patches/ubuntu-add-initrd-less-boot-fallback.patch
3451index 6dc4335..9a0ed6c 100644
3452--- a/debian/patches/ubuntu-add-initrd-less-boot-fallback.patch
3453+++ b/debian/patches/ubuntu-add-initrd-less-boot-fallback.patch
3454@@ -32,7 +32,7 @@ index bf9c1ba..353061e 100644
3455
3456 syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg
3457 diff --git a/configure.ac b/configure.ac
3458-index 22c6cf7..3c87596 100644
3459+index a29beb9..15a2a50 100644
3460 --- a/configure.ac
3461 +++ b/configure.ac
3462 @@ -314,6 +314,16 @@ AC_SUBST(grubdirname)
3463diff --git a/debian/patches/ubuntu-efi-allow-loopmount-chainload.patch b/debian/patches/ubuntu-efi-allow-loopmount-chainload.patch
3464index b0e49aa..7ab0799 100644
3465--- a/debian/patches/ubuntu-efi-allow-loopmount-chainload.patch
3466+++ b/debian/patches/ubuntu-efi-allow-loopmount-chainload.patch
3467@@ -40,7 +40,7 @@ index 41bebd1..99f4792 100644
3468 static unsigned long last_id = 0;
3469
3470 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
3471-index 9e301f2..cf76f48 100644
3472+index c3144de..2b74d79 100644
3473 --- a/grub-core/loader/efi/chainloader.c
3474 +++ b/grub-core/loader/efi/chainloader.c
3475 @@ -24,6 +24,7 @@
3476@@ -51,7 +51,7 @@ index 9e301f2..cf76f48 100644
3477 #include <grub/misc.h>
3478 #include <grub/charset.h>
3479 #include <grub/mm.h>
3480-@@ -906,6 +907,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3481+@@ -905,6 +906,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3482 grub_efi_status_t status;
3483 grub_efi_boot_services_t *b;
3484 grub_device_t dev = 0;
3485@@ -59,7 +59,7 @@ index 9e301f2..cf76f48 100644
3486 grub_efi_device_path_t *dp = 0;
3487 char *filename;
3488 void *boot_image = 0;
3489-@@ -963,6 +965,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3490+@@ -962,6 +964,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3491 if (! dev)
3492 goto fail;
3493
3494@@ -75,7 +75,7 @@ index 9e301f2..cf76f48 100644
3495 if (dev->disk)
3496 dev_handle = grub_efidisk_get_device_handle (dev->disk);
3497 else if (dev->net && dev->net->server)
3498-@@ -1092,6 +1103,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3499+@@ -1091,6 +1102,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3500 grub_device_close (dev);
3501
3502 fail:
3503diff --git a/debian/patches/ubuntu-fix-lzma-decompressor-objcopy.patch b/debian/patches/ubuntu-fix-lzma-decompressor-objcopy.patch
3504index 75ab70c..2c1a376 100644
3505--- a/debian/patches/ubuntu-fix-lzma-decompressor-objcopy.patch
3506+++ b/debian/patches/ubuntu-fix-lzma-decompressor-objcopy.patch
3507@@ -15,7 +15,7 @@ Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
3508 1 file changed, 1 insertion(+), 1 deletion(-)
3509
3510 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
3511-index f953817..98cda49 100644
3512+index f252725..0b5b4e7 100644
3513 --- a/grub-core/Makefile.core.def
3514 +++ b/grub-core/Makefile.core.def
3515 @@ -550,7 +550,7 @@ image = {
3516diff --git a/debian/patches/ubuntu-linuxefi-arm64-set-base-addr.patch b/debian/patches/ubuntu-linuxefi-arm64-set-base-addr.patch
3517index e00ae03..9b5e997 100644
3518--- a/debian/patches/ubuntu-linuxefi-arm64-set-base-addr.patch
3519+++ b/debian/patches/ubuntu-linuxefi-arm64-set-base-addr.patch
3520@@ -30,13 +30,13 @@ Origin: https://github.com/rhboot/grub2/commit/1d5ef08216edec4d31d0e10cfdb30b5eb
3521 Last-Updated: 2020-11-09
3522 Patch-Name: ubuntu-linuxefi-arm64-set-base-addr.patch
3523 ---
3524- grub-core/loader/efi/linux.c | 15 +++++++++++++++
3525+ grub-core/loader/efi/linux_sb.c | 15 +++++++++++++++
3526 1 file changed, 15 insertions(+)
3527
3528-diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
3529+diff --git a/grub-core/loader/efi/linux_sb.c b/grub-core/loader/efi/linux_sb.c
3530 index e372b26..73a7196 100644
3531---- a/grub-core/loader/efi/linux.c
3532-+++ b/grub-core/loader/efi/linux.c
3533+--- a/grub-core/loader/efi/linux_sb.c
3534++++ b/grub-core/loader/efi/linux_sb.c
3535 @@ -71,6 +71,7 @@ grub_err_t
3536 grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
3537 void *kernel_params)
3538diff --git a/debian/patches/ubuntu-linuxefi-arm64.patch b/debian/patches/ubuntu-linuxefi-arm64.patch
3539index e7f4e71..7789a5a 100644
3540--- a/debian/patches/ubuntu-linuxefi-arm64.patch
3541+++ b/debian/patches/ubuntu-linuxefi-arm64.patch
3542@@ -12,23 +12,22 @@ Bug-Ubuntu: https://bugs.launchpad.net/1862279
3543 Origin: vendor, https://github.com/rhboot/grub2/commit/2786ab864cf00c15123320671f653e9a36ba12b4
3544 Patch-Name: ubuntu-linuxefi-arm64.patch
3545 ---
3546- grub-core/loader/arm64/linux.c | 106 ++++++++++++++++++++++-------------------
3547- 1 file changed, 56 insertions(+), 50 deletions(-)
3548+ grub-core/loader/efi/linux.c | 101 ++++++++++++++++++++++---------------------
3549+ 1 file changed, 51 insertions(+), 50 deletions(-)
3550
3551-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
3552-index 1a5296a..4e9eac3 100644
3553---- a/grub-core/loader/arm64/linux.c
3554-+++ b/grub-core/loader/arm64/linux.c
3555-@@ -42,6 +42,8 @@ static int loaded;
3556+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
3557+index d81e7be..93e4cfc 100644
3558+--- a/grub-core/loader/efi/linux.c
3559++++ b/grub-core/loader/efi/linux.c
3560+@@ -42,6 +42,7 @@ static int loaded;
3561
3562 static void *kernel_addr;
3563 static grub_uint64_t kernel_size;
3564 +static grub_uint32_t handover_offset;
3565-+
3566
3567 static char *linux_args;
3568 static grub_uint32_t cmdline_size;
3569-@@ -75,7 +77,8 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
3570+@@ -99,7 +100,8 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
3571 static grub_err_t
3572 finalize_params_linux (void)
3573 {
3574@@ -36,9 +35,9 @@ index 1a5296a..4e9eac3 100644
3575 + grub_efi_loaded_image_t *loaded_image = NULL;
3576 + int node, retval, len;
3577
3578- void *fdt;
3579+ void *fdt = NULL;
3580
3581-@@ -110,6 +113,27 @@ finalize_params_linux (void)
3582+@@ -134,6 +136,27 @@ finalize_params_linux (void)
3583 if (grub_fdt_install() != GRUB_ERR_NONE)
3584 goto failure;
3585
3586@@ -66,28 +65,14 @@ index 1a5296a..4e9eac3 100644
3587 return GRUB_ERR_NONE;
3588
3589 failure:
3590-@@ -117,70 +141,48 @@ failure:
3591+@@ -141,62 +164,36 @@ failure:
3592 return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
3593 }
3594
3595+-grub_err_t
3596+-grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
3597 +static void
3598 +free_params (void)
3599-+{
3600-+ grub_efi_loaded_image_t *loaded_image = NULL;
3601-+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
3602-+ if (loaded_image)
3603-+ {
3604-+ if (loaded_image->load_options)
3605-+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)
3606-+ loaded_image->load_options,
3607-+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
3608-+ loaded_image->load_options = NULL;
3609-+ loaded_image->load_options_size = 0;
3610-+ }
3611-+}
3612-+
3613- grub_err_t
3614- grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
3615 {
3616 - grub_efi_memory_mapped_device_path_t *mempath;
3617 - grub_efi_handle_t image_handle;
3618@@ -106,21 +91,35 @@ index 1a5296a..4e9eac3 100644
3619 - mempath[0].memory_type = GRUB_EFI_LOADER_DATA;
3620 - mempath[0].start_address = addr;
3621 - mempath[0].end_address = addr + size;
3622-+ grub_err_t retval;
3623-
3624+-
3625 - mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE;
3626 - mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
3627 - mempath[1].header.length = sizeof (grub_efi_device_path_t);
3628--
3629++ grub_efi_loaded_image_t *loaded_image = NULL;
3630++ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
3631++ if (loaded_image)
3632++ {
3633++ if (loaded_image->load_options)
3634++ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)
3635++ loaded_image->load_options,
3636++ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
3637++ loaded_image->load_options = NULL;
3638++ loaded_image->load_options_size = 0;
3639++ }
3640++}
3641+
3642 - b = grub_efi_system_table->boot_services;
3643 - status = b->load_image (0, grub_efi_image_handle,
3644 - (grub_efi_device_path_t *) mempath,
3645 - (void *) addr, size, &image_handle);
3646 - if (status != GRUB_EFI_SUCCESS)
3647 - return grub_error (GRUB_ERR_BAD_OS, "cannot load image");
3648-+ retval = finalize_params_linux ();
3649-+ if (retval != GRUB_ERR_NONE)
3650-+ return grub_errno;
3651++grub_err_t
3652++grub_arch_efi_linux_boot_image (grub_addr_t addr __attribute__((unused)),
3653++ grub_size_t size __attribute__((unused)),
3654++ char *args)
3655++{
3656++ grub_err_t retval;
3657
3658 grub_dprintf ("linux", "linux command line: '%s'\n", args);
3659
3660@@ -136,35 +135,23 @@ index 1a5296a..4e9eac3 100644
3661 - loaded_image->load_options_size =
3662 - 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
3663 - (grub_uint8_t *) args, len, NULL);
3664-+ (void) addr;
3665-+ (void) size;
3666-
3667+-
3668 - grub_dprintf ("linux", "starting image %p\n", image_handle);
3669 - status = b->start_image (image_handle, 0, NULL);
3670++ retval = grub_efi_linux_boot (kernel_addr, handover_offset, kernel_addr);
3671
3672-- /* When successful, not reached */
3673+ /* When successful, not reached */
3674 - b->unload_image (image_handle);
3675 - grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
3676 - GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
3677-+ retval = grub_efi_linux_boot ((char *)kernel_addr, handover_offset,
3678-+ kernel_addr);
3679-
3680+-
3681 - return grub_errno;
3682-+ /* Never reached... */
3683 + free_params();
3684 + return retval;
3685 }
3686
3687 static grub_err_t
3688- grub_linux_boot (void)
3689- {
3690-- if (finalize_params_linux () != GRUB_ERR_NONE)
3691-- return grub_errno;
3692--
3693- return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
3694- kernel_size, linux_args));
3695- }
3696-@@ -296,6 +298,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3697+@@ -411,6 +408,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3698 {
3699 grub_file_t file = 0;
3700 struct linux_arch_kernel_header lh;
3701@@ -172,7 +159,7 @@ index 1a5296a..4e9eac3 100644
3702 grub_err_t err;
3703 int rc;
3704
3705-@@ -349,6 +352,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3706+@@ -464,6 +462,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3707 goto fail;
3708 }
3709
3710diff --git a/debian/patches/ubuntu-linuxefi.patch b/debian/patches/ubuntu-linuxefi.patch
3711index eb99d16..533b900 100644
3712--- a/debian/patches/ubuntu-linuxefi.patch
3713+++ b/debian/patches/ubuntu-linuxefi.patch
3714@@ -318,17 +318,17 @@ Last-Update: 2018-12-07
3715 Updated 2021-12-13: If we cannot allocate kernel at preferred address,
3716 reset errno so that we do not fail erroneously with out of memory.
3717 ---
3718- grub-core/Makefile.core.def | 15 +-
3719+ grub-core/Makefile.core.def | 17 +-
3720 grub-core/commands/iorw.c | 7 +
3721 grub-core/commands/memrw.c | 7 +
3722 grub-core/kern/arm/coreboot/coreboot.S | 6 +
3723 grub-core/kern/dl.c | 1 +
3724 grub-core/kern/efi/mm.c | 32 ++
3725- grub-core/loader/arm64/linux.c | 16 +
3726 grub-core/loader/efi/appleloader.c | 7 +
3727- grub-core/loader/efi/chainloader.c | 816 ++++++++++++++++++++++++++++++---
3728+ grub-core/loader/efi/chainloader.c | 815 ++++++++++++++++++++++++++++++---
3729 grub-core/loader/efi/fdt.c | 1 +
3730- grub-core/loader/efi/linux.c | 86 ++++
3731+ grub-core/loader/efi/linux.c | 16 +
3732+ grub-core/loader/efi/linux_sb.c | 86 ++++
3733 grub-core/loader/i386/bsd.c | 7 +
3734 grub-core/loader/i386/efi/linux.c | 382 +++++++++++++++
3735 grub-core/loader/i386/linux.c | 78 +++-
3736@@ -344,8 +344,8 @@ reset errno so that we do not fail erroneously with out of memory.
3737 include/grub/mips/linux.h | 0
3738 include/grub/powerpc/linux.h | 0
3739 include/grub/sparc64/linux.h | 0
3740- 26 files changed, 1510 insertions(+), 100 deletions(-)
3741- create mode 100644 grub-core/loader/efi/linux.c
3742+ 26 files changed, 1511 insertions(+), 100 deletions(-)
3743+ create mode 100644 grub-core/loader/efi/linux_sb.c
3744 create mode 100644 grub-core/loader/i386/efi/linux.c
3745 create mode 100644 include/grub/efi/linux.h
3746 create mode 100644 include/grub/ia64/linux.h
3747@@ -354,24 +354,26 @@ reset errno so that we do not fail erroneously with out of memory.
3748 create mode 100644 include/grub/sparc64/linux.h
3749
3750 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
3751-index 8022e1c..715d137 100644
3752+index 0536575..1a3ead6 100644
3753 --- a/grub-core/Makefile.core.def
3754 +++ b/grub-core/Makefile.core.def
3755-@@ -1807,10 +1807,13 @@ module = {
3756+@@ -1807,10 +1807,15 @@ module = {
3757 ia64_efi = loader/ia64/efi/linux.c;
3758 arm_coreboot = loader/arm/linux.c;
3759- arm_efi = loader/arm64/linux.c;
3760-+ arm_efi = loader/efi/linux.c;
3761+ arm_efi = loader/efi/linux.c;
3762++ arm_efi = loader/efi/linux_sb.c;
3763 arm_uboot = loader/arm/linux.c;
3764- arm64 = loader/arm64/linux.c;
3765-+ arm64 = loader/efi/linux.c;
3766- riscv32 = loader/riscv/linux.c;
3767- riscv64 = loader/riscv/linux.c;
3768+ arm64 = loader/efi/linux.c;
3769++ arm64 = loader/efi/linux_sb.c;
3770+ riscv32 = loader/efi/linux.c;
3771++ riscv32 = loader/efi/linux_sb.c;
3772+ riscv64 = loader/efi/linux.c;
3773++ riscv64 = loader/efi/linux_sb.c;
3774 + cflags = '-Wno-error=cast-align';
3775 common = loader/linux.c;
3776 common = lib/cmdline.c;
3777 enable = noemu;
3778-@@ -1819,7 +1822,7 @@ module = {
3779+@@ -1819,7 +1824,7 @@ module = {
3780 module = {
3781 name = fdt;
3782 efi = loader/efi/fdt.c;
3783@@ -380,14 +382,14 @@ index 8022e1c..715d137 100644
3784 enable = fdt;
3785 };
3786
3787-@@ -1874,12 +1877,22 @@ module = {
3788+@@ -1874,12 +1879,22 @@ module = {
3789 enable = x86_64_efi;
3790 };
3791
3792 +module = {
3793 + name = linuxefi;
3794 + efi = loader/i386/efi/linux.c;
3795-+ efi = loader/efi/linux.c;
3796++ efi = loader/efi/linux_sb.c;
3797 + cflags = '-Wno-error=cast-align';
3798 + enable = i386_efi;
3799 + enable = x86_64_efi;
3800@@ -536,54 +538,6 @@ index 9838fb2..f6aef0e 100644
3801 /* Allocate pages. Return the pointer to the first of allocated pages. */
3802 void *
3803 grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
3804-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
3805-index ef3e9f9..1a5296a 100644
3806---- a/grub-core/loader/arm64/linux.c
3807-+++ b/grub-core/loader/arm64/linux.c
3808-@@ -27,6 +27,7 @@
3809- #include <grub/types.h>
3810- #include <grub/cpu/linux.h>
3811- #include <grub/efi/efi.h>
3812-+#include <grub/efi/linux.h>
3813- #include <grub/efi/fdtload.h>
3814- #include <grub/efi/memory.h>
3815- #include <grub/efi/pe32.h>
3816-@@ -48,6 +49,13 @@ static grub_uint32_t cmdline_size;
3817- static grub_addr_t initrd_start;
3818- static grub_addr_t initrd_end;
3819-
3820-+struct grub_arm64_linux_pe_header
3821-+{
3822-+ grub_uint32_t magic;
3823-+ struct grub_pe32_coff_header coff;
3824-+ struct grub_pe64_optional_header opt;
3825-+};
3826-+
3827- grub_err_t
3828- grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
3829- {
3830-@@ -289,6 +297,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3831- grub_file_t file = 0;
3832- struct linux_arch_kernel_header lh;
3833- grub_err_t err;
3834-+ int rc;
3835-
3836- grub_dl_ref (my_mod);
3837-
3838-@@ -333,6 +342,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
3839-
3840- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
3841-
3842-+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
3843-+ if (rc < 0)
3844-+ {
3845-+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
3846-+ goto fail;
3847-+ }
3848-+
3849- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
3850- linux_args = grub_malloc (cmdline_size);
3851- if (!linux_args)
3852 diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c
3853 index 74888c4..07677f0 100644
3854 --- a/grub-core/loader/efi/appleloader.c
3855@@ -616,7 +570,7 @@ index 74888c4..07677f0 100644
3856 grub_unregister_command (cmd);
3857 }
3858 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
3859-index 2bd80f4..9e301f2 100644
3860+index 2bd80f4..c3144de 100644
3861 --- a/grub-core/loader/efi/chainloader.c
3862 +++ b/grub-core/loader/efi/chainloader.c
3863 @@ -32,6 +32,9 @@
3864@@ -652,7 +606,7 @@ index 2bd80f4..9e301f2 100644
3865
3866 grub_dl_unref (my_mod);
3867 return GRUB_ERR_NONE;
3868-@@ -213,20 +222,694 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
3869+@@ -213,20 +222,693 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
3870 return file_path;
3871 }
3872
3873@@ -767,6 +721,8 @@ index 2bd80f4..9e301f2 100644
3874 + GRUB_PE32_MACHINE_I386;
3875 +#elif defined(__ia64__)
3876 + GRUB_PE32_MACHINE_IA64;
3877++#elif defined(__riscv) && __riscv_xlen == 64
3878++ GRUB_PE32_MACHINE_RISCV64;
3879 +#else
3880 +#error this architecture is not supported by grub2
3881 +#endif
3882@@ -782,9 +738,7 @@ index 2bd80f4..9e301f2 100644
3883 + char *fixup, *fixup_base, *fixup_data = NULL;
3884 + grub_efi_uint16_t *fixup_16;
3885 + grub_efi_uint32_t *fixup_32;
3886-+#if defined(__x86_64__) || defined(__aarch64__)
3887 + grub_efi_uint64_t *fixup_64;
3888-+#endif /* defined(__x86_64__) || defined(__aarch64__) */
3889 + grub_efi_uint64_t size = context->image_size;
3890 + void *image_end = (char *)orig + size;
3891 + int n = 0;
3892@@ -911,7 +865,6 @@ index 2bd80f4..9e301f2 100644
3893 + fixup_data += sizeof (grub_uint32_t);
3894 + }
3895 + break;
3896-+#if defined(__x86_64__) || defined(__aarch64__)
3897 + case GRUB_PE32_REL_BASED_DIR64:
3898 + fixup_64 = (grub_uint64_t *)fixup;
3899 + *fixup_64 = *fixup_64 + (grub_uint64_t)adjust;
3900@@ -922,7 +875,7 @@ index 2bd80f4..9e301f2 100644
3901 + fixup_data += sizeof (grub_uint64_t);
3902 + }
3903 + break;
3904-+#endif /* defined(__x86_64__) || defined(__aarch64__) */
3905++ /* TODO: GRUB_PE32_REL_BASED_RISCV_HI20, GRUB_PE32_REL_BASED_RISCV_LOW12I/S */
3906 + default:
3907 + grub_error (GRUB_ERR_BAD_ARGUMENT,
3908 + "Reloc %d unknown relocation type %d",
3909@@ -1350,7 +1303,7 @@ index 2bd80f4..9e301f2 100644
3910
3911 if (argc == 0)
3912 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
3913-@@ -238,15 +921,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3914+@@ -238,15 +920,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3915 address = 0;
3916 image_handle = 0;
3917 file_path = 0;
3918@@ -1398,7 +1351,7 @@ index 2bd80f4..9e301f2 100644
3919 if (! dev)
3920 goto fail;
3921
3922-@@ -283,17 +996,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3923+@@ -283,17 +995,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3924 if (! file_path)
3925 goto fail;
3926
3927@@ -1419,7 +1372,7 @@ index 2bd80f4..9e301f2 100644
3928
3929 status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
3930 GRUB_EFI_LOADER_CODE,
3931-@@ -307,7 +1017,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3932+@@ -307,7 +1016,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3933 }
3934
3935 boot_image = (void *) ((grub_addr_t) address);
3936@@ -1428,7 +1381,7 @@ index 2bd80f4..9e301f2 100644
3937 {
3938 if (grub_errno == GRUB_ERR_NONE)
3939 grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
3940-@@ -317,7 +1027,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3941+@@ -317,7 +1026,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3942 }
3943
3944 #if defined (__i386__) || defined (__x86_64__)
3945@@ -1437,7 +1390,7 @@ index 2bd80f4..9e301f2 100644
3946 {
3947 struct grub_macho_fat_header *head = boot_image;
3948 if (head->magic
3949-@@ -326,6 +1036,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3950+@@ -326,6 +1035,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3951 grub_uint32_t i;
3952 struct grub_macho_fat_arch *archs
3953 = (struct grub_macho_fat_arch *) (head + 1);
3954@@ -1452,7 +1405,7 @@ index 2bd80f4..9e301f2 100644
3955 for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++)
3956 {
3957 if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype))
3958-@@ -340,79 +1058,40 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3959+@@ -340,79 +1057,40 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3960 > ~grub_cpu_to_le32 (archs[i].size)
3961 || grub_cpu_to_le32 (archs[i].offset)
3962 + grub_cpu_to_le32 (archs[i].size)
3963@@ -1547,7 +1500,7 @@ index 2bd80f4..9e301f2 100644
3964 if (dev)
3965 grub_device_close (dev);
3966
3967-@@ -424,6 +1103,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3968+@@ -424,6 +1102,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
3969 if (address)
3970 efi_call_2 (b->free_pages, address, pages);
3971
3972@@ -1558,7 +1511,7 @@ index 2bd80f4..9e301f2 100644
3973
3974 return grub_errno;
3975 diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
3976-index c86f283..7858d35 100644
3977+index 771d455..971e84d 100644
3978 --- a/grub-core/loader/efi/fdt.c
3979 +++ b/grub-core/loader/efi/fdt.c
3980 @@ -26,6 +26,7 @@
3981@@ -1570,10 +1523,58 @@ index c86f283..7858d35 100644
3982 static void *loaded_fdt;
3983 static void *fdt;
3984 diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
3985+index 3292cab..d81e7be 100644
3986+--- a/grub-core/loader/efi/linux.c
3987++++ b/grub-core/loader/efi/linux.c
3988+@@ -27,6 +27,7 @@
3989+ #include <grub/types.h>
3990+ #include <grub/cpu/linux.h>
3991+ #include <grub/efi/efi.h>
3992++#include <grub/efi/linux.h>
3993+ #include <grub/efi/fdtload.h>
3994+ #include <grub/efi/memory.h>
3995+ #include <grub/efi/pe32.h>
3996+@@ -54,6 +55,13 @@ static int initrd_use_loadfile2;
3997+ static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
3998+ static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
3999+
4000++struct grub_arm64_linux_pe_header
4001++{
4002++ grub_uint32_t magic;
4003++ struct grub_pe32_coff_header coff;
4004++ struct grub_pe64_optional_header opt;
4005++};
4006++
4007+ grub_err_t
4008+ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
4009+ {
4010+@@ -404,6 +412,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
4011+ grub_file_t file = 0;
4012+ struct linux_arch_kernel_header lh;
4013+ grub_err_t err;
4014++ int rc;
4015+
4016+ grub_dl_ref (my_mod);
4017+
4018+@@ -448,6 +457,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
4019+
4020+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
4021+
4022++ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
4023++ if (rc < 0)
4024++ {
4025++ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
4026++ goto fail;
4027++ }
4028++
4029+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
4030+ linux_args = grub_malloc (cmdline_size);
4031+ if (!linux_args)
4032+diff --git a/grub-core/loader/efi/linux_sb.c b/grub-core/loader/efi/linux_sb.c
4033 new file mode 100644
4034 index 0000000..e372b26
4035 --- /dev/null
4036-+++ b/grub-core/loader/efi/linux.c
4037++++ b/grub-core/loader/efi/linux_sb.c
4038 @@ -0,0 +1,86 @@
4039 +/*
4040 + * GRUB -- GRand Unified Bootloader
4041@@ -2082,7 +2083,7 @@ index 0000000..382ff52
4042 + grub_unregister_command (cmd_initrd);
4043 +}
4044 diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
4045-index 9f74a96..d55b7cd 100644
4046+index f30a158..b6c13d7 100644
4047 --- a/grub-core/loader/i386/linux.c
4048 +++ b/grub-core/loader/i386/linux.c
4049 @@ -78,6 +78,8 @@ static grub_size_t maximal_cmdline_size;
4050@@ -2243,7 +2244,7 @@ index 9f74a96..d55b7cd 100644
4051 {
4052 grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
4053 diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
4054-index 2a29952..f4ab6ad 100644
4055+index efeeeb2..69db786 100644
4056 --- a/grub-core/loader/i386/pc/linux.c
4057 +++ b/grub-core/loader/i386/pc/linux.c
4058 @@ -36,6 +36,7 @@
4059@@ -2420,7 +2421,7 @@ index 1c0cf6a..c5ba84c 100644
4060 grub_unregister_command (cmd_resume);
4061 #endif
4062 diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
4063-index 7e22b4a..6785b78 100644
4064+index effd870..9efd37a 100644
4065 --- a/include/grub/arm64/linux.h
4066 +++ b/include/grub/arm64/linux.h
4067 @@ -22,6 +22,8 @@
4068diff --git a/debian/patches/vt-handoff.patch b/debian/patches/vt-handoff.patch
4069index 94f8f4f..78c15da 100644
4070--- a/debian/patches/vt-handoff.patch
4071+++ b/debian/patches/vt-handoff.patch
4072@@ -17,10 +17,10 @@ Patch-Name: vt-handoff.patch
4073 2 files changed, 38 insertions(+), 1 deletion(-)
4074
4075 diff --git a/configure.ac b/configure.ac
4076-index 947fd52..e11df6b 100644
4077+index 3203749..b4e33a6 100644
4078 --- a/configure.ac
4079 +++ b/configure.ac
4080-@@ -1948,6 +1948,17 @@ else
4081+@@ -1956,6 +1956,17 @@ else
4082 fi
4083 AC_SUBST([GFXPAYLOAD_DYNAMIC])
4084
4085diff --git a/debian/postinst.in b/debian/postinst.in
4086index 5a64439..98020ab 100644
4087--- a/debian/postinst.in
4088+++ b/debian/postinst.in
4089@@ -759,7 +759,7 @@ case "$1" in
4090 fi
4091 ;;
4092
4093- grub-efi-ia32|grub-efi-amd64|grub-efi-ia64|grub-efi-arm|grub-efi-arm64)
4094+ grub-efi-ia32|grub-efi-amd64|grub-efi-ia64|grub-efi-arm|grub-efi-arm64|grub-efi-riscv64)
4095 bootloader_id="$(config_item GRUB_DISTRIBUTOR | tr A-Z a-z | \
4096 cut -d' ' -f1)"
4097 case $bootloader_id in
4098@@ -787,6 +787,7 @@ case "$1" in
4099 grub-efi-ia64) target=ia64-efi ;;
4100 grub-efi-arm) target=arm-efi ;;
4101 grub-efi-arm64) target=arm64-efi ;;
4102+ grub-efi-riscv64) target=riscv64-efi ;;
4103 esac
4104 # Check /boot/grub to see if we previously installed to an ESP. We don't
4105 # want to trigger the install code just by installing the package,
4106diff --git a/debian/rules b/debian/rules
4107index 9505998..90678d2 100755
4108--- a/debian/rules
4109+++ b/debian/rules
4110@@ -66,7 +66,7 @@ BUILD_PACKAGES := $(strip $(shell dh_listpackages))
4111 # REAL_PACKAGES build an actual grub variant (and therefore have both configure
4112 # and build stages). EXTRA_PACKAGES do not build grub but may depend on a
4113 # REAL_PACKAGE (and therefore only have a build stage)
4114-REAL_PACKAGES = grub-common grub-emu grub-pc grub-coreboot grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-firmware-qemu grub-uboot grub-xen grub-yeeloong
4115+REAL_PACKAGES = grub-common grub-emu grub-pc grub-coreboot grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-efi-riscv64 grub-ieee1275 grub-firmware-qemu grub-uboot grub-xen grub-yeeloong
4116 EXTRA_PACKAGES = grub-rescue-pc grub-xen-host
4117
4118 ifneq (,$(filter amd64,$(DEB_HOST_ARCH_CPU)))
4119@@ -85,6 +85,8 @@ else ifeq (arm,$(DEB_HOST_ARCH_CPU))
4120 COMMON_PLATFORM := uboot
4121 else ifeq (arm64,$(DEB_HOST_ARCH_CPU))
4122 COMMON_PLATFORM := efi-arm64
4123+else ifeq (riscv64,$(DEB_HOST_ARCH_CPU))
4124+COMMON_PLATFORM := efi-riscv64
4125 else
4126 COMMON_PLATFORM := none
4127 BUILD_PACKAGES += grub-none
4128@@ -95,6 +97,8 @@ DEFAULT_CMDLINE := quiet splash
4129 DEFAULT_TIMEOUT := 10
4130 ifeq ($(DEB_HOST_ARCH_CPU),ppc64el)
4131 FLICKER_FREE_BOOT := no
4132+else ifeq ($(DEB_HOST_ARCH_CPU),riscv64)
4133+FLICKER_FREE_BOOT := no
4134 else
4135 FLICKER_FREE_BOOT := yes
4136 endif
4137@@ -263,7 +267,7 @@ debian/stamps/configure-grub-efi-amd64:
4138 mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@)
4139 dh_auto_configure -- $(confflags) --with-platform=efi --target=amd64-pe --program-prefix=""
4140 touch $@
4141-debian/stamps/configure-grub-efi-ia64 debian/stamps/configure-grub-efi-arm debian/stamps/configure-grub-efi-arm64:
4142+debian/stamps/configure-grub-efi-ia64 debian/stamps/configure-grub-efi-arm debian/stamps/configure-grub-efi-arm64 debian/stamps/configure-grub-efi-riscv64:
4143 mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@)
4144 dh_auto_configure -- $(confflags) --with-platform=efi
4145 touch $@
4146@@ -284,7 +288,7 @@ debian/stamps/configure-grub-firmware-qemu:
4147 dh_auto_configure -- $(confflags) --with-platform=qemu
4148 touch $@
4149
4150-debian/stamps/build-grub-none debian/stamps/build-grub-efi-ia64 debian/stamps/build-grub-efi-arm debian/stamps/build-grub-coreboot debian/stamps/build-grub-emu debian/stamps/build-grub-uboot debian/stamps/build-grub-xen-i386 debian/stamps/build-grub-xen-amd64 debian/stamps/build-grub-xen-pvh-i386 debian/stamps/build-grub-yeeloong: debian/stamps/build-%: debian/stamps/configure-%
4151+debian/stamps/build-grub-none debian/stamps/build-grub-efi-ia64 debian/stamps/build-grub-efi-arm debian/stamps/build-grub-efi-riscv64 debian/stamps/build-grub-coreboot debian/stamps/build-grub-emu debian/stamps/build-grub-uboot debian/stamps/build-grub-xen-i386 debian/stamps/build-grub-xen-amd64 debian/stamps/build-grub-xen-pvh-i386 debian/stamps/build-grub-yeeloong: debian/stamps/build-%: debian/stamps/configure-%
4152 dh_auto_build
4153 touch $@
4154
4155@@ -426,7 +430,7 @@ install/grub-none:
4156 # files.
4157 mkdir -p debian/tmp-$(package)/usr/share/locale
4158
4159-install/grub-pc install/grub-efi-ia32 install/grub-efi-amd64 install/grub-efi-ia64 install/grub-efi-arm install/grub-efi-arm64 install/grub-ieee1275 install/grub-coreboot install/grub-emu install/grub-uboot install/grub-xen install/grub-yeeloong:
4160+install/grub-pc install/grub-efi-ia32 install/grub-efi-amd64 install/grub-efi-ia64 install/grub-efi-arm install/grub-efi-arm64 install/grub-efi-riscv64 install/grub-ieee1275 install/grub-coreboot install/grub-emu install/grub-uboot install/grub-xen install/grub-yeeloong:
4161 set -e ; \
4162 if [ "$@" = "install/grub-xen" ] ; then \
4163 dh_auto_install -Bobj/grub-xen-i386 --destdir=debian/tmp-$(package); \
4164@@ -571,7 +575,7 @@ endif
4165
4166 NON_PLATFORM_PACKAGES = $(filter grub2 grub-linuxbios grub-efi grub-rescue-pc grub-firmware-qemu grub-xen-host,$(BUILD_PACKAGES))
4167 COMMON_PLATFORM_PACKAGES = $(filter grub-common grub2-common grub-theme-starfield grub-mount-udeb,$(BUILD_PACKAGES))
4168-PLATFORM_PACKAGES = $(filter grub-pc grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-coreboot grub-uboot grub-xen grub-yeeloong,$(BUILD_PACKAGES))
4169+PLATFORM_PACKAGES = $(filter grub-pc grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-efi-riscv64 grub-ieee1275 grub-coreboot grub-uboot grub-xen grub-yeeloong,$(BUILD_PACKAGES))
4170
4171 override_dh_install:
4172 ifneq (,$(NON_PLATFORM_PACKAGES))

Subscribers

People subscribed via source and target branches