View previous topic :: View next topic |
Author |
Message |
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Sun Nov 03, 2024 3:55 pm Post subject: Grub cannot load image. How to prepare grub for shim? |
|
|
Hi, I managed to load gentoo uki kernel via shim without grub. Now I would like to try shim with grub between shim and uki. I tried two approaches, which ended in failure.
This is what my boot partition looks like in a nutshell:
/boot/EFI/gentoo/shim64.efi < - shim
/boot/EFI/gentoo/mmx64.efi < - signed MOK Manager
/boot/EFI/gentoo/grubx64.efi < - signed grub
/boot/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi < - signed UKI kernel
Approach 1:
I just signed grubx64.efi. Without secure boot option the system boots, but with secure boot there is a secure boot violation / invalid signature detected. For me this means that grub contains some unsigned components or is prepared inappropriately, maybe something with sbat etc. From what I understand, it is better to creat grub with ‘grub-mkstandalone’, so I would like to focus on the second approach where I did it.
Approach 2:
I created grub using mkstandalone. With the secure boot option, grub boots to the kernel selection window and then gives an error. So grub seems to be signed correctly, but there is still something wrong with the configuration.
Error after selecting kernel:
Code: | error: file `/boot/grub/grubenv’ not found
/EndEntire
file path: /ACPI(…
error: cannot load image.
Press any key to continue |
My steps:
Create menuentry for grub
Code: | nano /etc/grub.d/40_custom
menuentry 'Gentoo GNU/Linux' {
savedefault
uki_path=/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi
export uki_path
search --set=root --efidisk-only --file $uki_path
chainloader $uki_path
} |
Create standalone grub and sign it
This approach is based on signing from the grub package https://gitweb.gentoo.org/repo/gentoo.git/tree/sys-boot/grub/grub-2.12-r5.ebuild#n344
However, I'm definitely doing something wrong
Code: | mkdir workingdir
cd workingdir
echo 'configfile ${cmdpath}/grub.cfg' > workingdir/grub.cfg
/usr/bin/grub-mkstandalone --verbose --directory="/usr/lib/grub/x86_64-efi" --locale-directory="/usr/share/locale" --format="x86_64-efi" --modules="part_gpt part_msdos" --sbat="/usr/share/grub/sbat.csv" --output="workingdir/grub-x86_64.efi" "boot/grub/grub.cfg=workingdir/grub.cfg"
sbsign --key=file.key --cert=file.crt grub-x86_64.efi --output grub-x86_64.efi.signed |
Copy grub to boot partition
Code: | cp workingdir/grub-x86_64.efi.signed /boot/EFI/gentoo/grubx64.efi |
Make config inside /boot/EFI/gentoo
Code: | grub-mkconfig -o /boot/EFI/gentoo/grub.cfg |
Earlier, I installed grub, that's why I have files like grubenv inside /boot/grub/grubenv, but I have no idea how it all works with grub standalone and I don't understand everything. |
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 602
|
Posted: Sun Nov 03, 2024 4:29 pm Post subject: |
|
|
Maybe it helps you here is my command for installing grub, you have to sign it manually after this:
Code: | grub-install --no-nvram --efi-directory=/boot --boot-directory=/boot --bootloader-id Gentoo --disable-shim-lock --sbat=/usr/share/grub/sbat.csv --modules "boot.mod btrfs.mod cat.mod configfile.mod echo.mod efifwsetup.mod efinet.mod font.mod gettext.mod gzio.mod halt.mod help.mod jpeg.mod keystatus.mod loadenv.mod loopback.mod ls.mod lsefi.mod lsefimmap.mod lsefisystab.mod lssal.mod memdisk.mod minicmd.mod part_gpt.mod part_msdos.mod png.mod probe.mod reboot.mod regexp.mod search.mod search_fs_uuid.mod search_fs_file.mod search_label.mod sleep.mod smbios.mod squash4.mod test.mod true.mod video.mod xfs.mod iso9660.mod fat.mod chain.mod normal.mod linux.mod linux16.mod video.mod gfxmenu.mod gfxterm_background.mod gfxterm_menu.mod gfxterm.mod video_fb.mod efi_gop.mod efi_uga.mod video_fb.mod all_video.mod ntfs.mod" |
|
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 602
|
Posted: Sun Nov 03, 2024 6:19 pm Post subject: |
|
|
Since i use chainloader to start my Windows 11 through grub i would say it works.
Here's my snippet of grub.cfg:
Code: | menuentry 'Windows 11 x64' {
search --no-floppy --fs-uuid --set=root 67D3-2C0E
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
} |
|
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Sun Nov 03, 2024 11:26 pm Post subject: |
|
|
@Child_of_Sun_24: Your Approach 1 looks promising. This is more or less how it is also documented on the Arch wiki, to add modules directly during grub-install. Then you will probably avoid the problem with unsigned modules that I had in this case. On the other hand, it is a bit ugly that you have to manually list the modules to be added.
Do you use the grub-mkconfig command later? Can you copy your menuentry for gentoo?
Back to Approach 2.
I tried to move the kernel from
Code: | /boot/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi |
to
Code: | /boot/vmlinuz-6.6.58-gentoo-dist.efi |
and generate config
Code: | grub-mkconfig -o /boot/EFI/gentoo/grub.cfg | .
This causes grub to automatically detect the kernel and create an automatic menuentry.
An erros occurs after selecting kernel in grub window
Code: | Loading Linux 6.6.58-gentoo-dist.efi ...
error: invalid magic number
Press any key to continue... |
Of course, what I did is incorrect, because in this case grub adds various commands in the menuentry such as insmod, which is not allowed in the case of securebot.
In short, I am able to generate a signed standalone grub that boots, but I still don't know how to configure it to run my kernel correctly. |
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 602
|
Posted: Mon Nov 04, 2024 6:43 am Post subject: |
|
|
Here is the snippet from gentoo kernel:
Code: | menuentry "Gentoo" {
set gfxpayload=keep
linux /vmlinuz-6.11.6-gentoo root=PARTUUID=197f3c03-eb46-479d-82a6-1a3a701500e7 ro init=/usr/lib/systemd/systemd rootfstype=btrfs rootflags=ssd,thread_pool=10,compress=zstd amd_pstate=guided cpufreq.scaling_governor=schedutil cpufreq.default_governor=schedutil crypt=0 passdev=none
} |
|
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Mon Nov 04, 2024 8:38 am Post subject: Re: Grub cannot load image. How to prepare grub for shim? |
|
|
nxe9 wrote: | Approach 1:
I just signed grubx64.efi. Without secure boot option the system boots, but with secure boot there is a secure boot violation / invalid signature detected. For me this means that grub contains some unsigned components or is prepared inappropriately, maybe something with sbat etc. From what I understand, it is better to creat grub with ‘grub-mkstandalone’, so I would like to focus on the second approach where I did it. |
GRUB is a modular bootloader, and when secure boot is enabled it is not allowed to load modules. So a 'grub-install'ed grubx64.efi cannot work in a secureboot enabled configuration. You'll need to build in any modules you need, for example with grub-mkstandalone. The sbat is indeed also required.
Quote: | Approach 2:
I created grub using mkstandalone. With the secure boot option, grub boots to the kernel selection window and then gives an error. So grub seems to be signed correctly, but there is still something wrong with the configuration. |
You don't have to do all this manually, simply enable the secureboot USE flag on the grub package. It will build a standalone image with grub-mkstandalone, pre-load the modules required to find the configuration file on the disk, add the required sbat section, and sign the whole thing with the key you specify. This is documented in the handbook. Note that you will have to put the grub configuration file in a different spot then usual. _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Mon Nov 04, 2024 12:26 pm Post subject: |
|
|
@Nowa / Approach 2:
Secureboot flag doesn't work on grub package properly. That is the reason why I am trying to do it manually. See the following for details
https://forums.gentoo.org/viewtopic-t-1171516.html
https://bugs.gentoo.org/935733
I think grub finds the location of my kernel because in case "chainloader $uki_path" there is an error as I wrote in the first post
Code: | error: cannot load image. |
In turn, when I call the '"linux $uki_path" command, following error appears
Code: | error: invalid magic number |
If I enter another incorrect path I get
Code: | error: file '<path>' not found. |
It looks to me like there is something wrong with my grub standalone. It looks like grub couldn't load the uki kernel for some reason. |
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Mon Nov 04, 2024 12:39 pm Post subject: |
|
|
Could you try the workaround mentioned in the bug report (FEATURES="-pid-sandbox")? This way we can easily determine if there is something wrong with your method, or if something else is wrong.
The "invalid magic number" error is expected, grub's linux loading command expects a linux kernel image, it cannot load an UKI (https://bugs.gentoo.org/942201). The error from the chainload command may be caused by a missing sbat section, or possibly something else. How did you make this UKI? Could we see the output of "emerge --config gentoo-kernel" (or gentoo-kernel-bin)? When your boot was working without grub, was secureboot enabled or disabled? Overall the support for loading UKIs in grub is a bit experimental, you might have an easier time with refind or systemd-boot. _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Mon Nov 04, 2024 8:18 pm Post subject: |
|
|
@Nowa, thanks.
I make UKi installing gentoo-kernel with* uki and dracut flags.
*EDIT: gentoo-kernel doesn't contain uki and dracut. I mean 'installkernel' with uki and dracut. gentoo-kernel calls installkernel.
emerge --config gentoo-kernel output:
https://bpa.st/ZMRFQ
https://bpa.st/Y3GYY
The -pid-sandbox allows me to build grub with secureboot flag and generates signed grub but the result after reboot is the same.
Code: | error: file `/boot/grub/grubenv’ not found
/EndEntire
file path: /ACPI(…
error: cannot load image.
Press any key to continue |
My steps:
1. Add FEATURES="-pid-sandbox" inside make.conf.
2. Build grub with secureboot
3.
Code: | cp /usr/lib/grub/grub-x86_64.efi.signed /boot/EFI/gentoo/grubx64.efi |
4. /etc/grub.d/40_custom still contains
Code: | nano /etc/grub.d/40_custom
menuentry 'Gentoo GNU/Linux' {
savedefault
uki_path=/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi
export uki_path
search --set=root --efidisk-only --file $uki_path
chainloader $uki_path
} |
5.
Code: | grub-mkconfig -o /boot/EFI/gentoo/grub.cfg |
So it looks like standalone grub has a problem with my UKI for some reason.
Nowa wrote: | When your boot was working without grub, was secureboot enabled or disabled? |
Enabled.
Without grub it works both as enabled and disabled. |
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Tue Nov 05, 2024 2:42 am Post subject: |
|
|
I tried (approach 1):
Code: | grub-install--efi-directory=/boot --sbat=/usr/share/grub/sbat.csv --modules "boot.mod btrfs.mod cat.mod configfile.mod echo.mod efifwsetup.mod efinet.mod font.mod gettext.mod gzio.mod halt.mod help.mod jpeg.mod keystatus.mod loadenv.mod loopback.mod ls.mod lsefi.mod lsefimmap.mod lsefisystab.mod lssal.mod memdisk.mod minicmd.mod part_gpt.mod part_msdos.mod png.mod probe.mod reboot.mod regexp.mod search.mod search_fs_uuid.mod search_fs_file.mod search_label.mod sleep.mod smbios.mod squash4.mod test.mod true.mod xfs.mod iso9660.mod fat.mod chain.mod normal.mod linux.mod linux16.mod video.mod gfxmenu.mod gfxterm_background.mod gfxterm_menu.mod gfxterm.mod video_fb.mod efi_gop.mod efi_uga.mod video_fb.mod all_video.mod ntfs.mod"
+signing the output
grub-mkconfig -o /boot/grub/grub.cfg |
And it also fails with secureboot.
Interestingly, the system boots without secureboot.
Here is a summary of my observations.
secureboot on: shim + grub standalone + UKI => failure, cannot load image
secureboot off: shim + grub standalone + UKI => OK
secureboot on: shim + grub install + UKI => failure, cannot load image
secureboot off: shim + grub install + UKI => OK
secureboot on: shim + UKI => OK
secureboot off: shim + UKI => OK
So it seems that grub is not working properly with uki and secureboot.
@Child_of_Sun_24: You don't use UKI, right?
I found some more threads here. I don't know how reliable they are. However, UKI, grub and secureboot does not seem to be something trivial.
https://www.reddit.com/r/archlinux/comments/17dowj5/grub_not_booting_unified_kernel_image/
Quote: | I forgot to mention, I am using a grub image with in built fat and chain modules and various other modules, the grub binary I extracted from Ubuntu ISO is able to boot the uki, but when I build a binary with same modules it does not work. Now I am going to include all modules in the binary and try it. |
Quote: | Grub in arch repository does not support UKI with secure-boot.
To boot UKI from grub with secure-boot support ubuntu secure-boot patches are needed. |
https://www.reddit.com/r/archlinux/comments/10r03e9/is_it_possible_to_get_secure_boot_uki_luks/
Quote: |
Your main challenge could be that an Unified Kernel Image Always uses the embedded .cmdline and will (or might) ignore the options (which snapshot to boot and so on) provided by grub.
Maybe if you build an UKI completely omitting embedding the .cmdline it might do what you want to do. (I never tried) |
If it doesn't actually work, then so be it. I'm happy with the no-grub option, and now I'm just doing it out of curiosity. Perhaps I will try grub without UKI.
Last edited by nxe9 on Tue Nov 05, 2024 12:57 pm; edited 1 time in total |
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 602
|
Posted: Tue Nov 05, 2024 4:46 am Post subject: |
|
|
No i'm not using Uki. |
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Tue Nov 05, 2024 9:08 am Post subject: |
|
|
What is this "/boot/grub/grubenv"? Do you know where it comes from?
You should not need anything at /boot/grub at all, the grub.cfg and the standalone grubx64.efi should be enough to boot. Could you try moving the /boot/grub directory (if it exists) somewhere out of the way and then re-generating the grub.cfg? Is there something in your grub configuration files that references this "/boot/grub/grubenv"?
What is in the .cmdline section of your UKI? _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1709 Location: South America
|
Posted: Tue Nov 05, 2024 11:36 am Post subject: |
|
|
Nowa wrote: | What is this "/boot/grub/grubenv"? Do you know where it comes from? |
It's GRUB's environment block. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Tue Nov 05, 2024 12:15 pm Post subject: |
|
|
That makes me think grub wants to access that file because "savedefault" is executed. When secureboot is enabled nothing external can enter the boot chain so I expect that reading/writing this environment file is blocked for this reason.
What happens if you simplify your config snippet to:
Code: |
menuentry 'Gentoo GNU/Linux' {
chainloader (hd0,1)/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi
}
|
Replacing hd0,1 with the disk and partition number of your EFI System Partition. _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Tue Nov 05, 2024 12:50 pm Post subject: |
|
|
@Nowa
"/boot/grub/grubenv" error occurs only with grub standalone. In case of grub standalone and non secureboot when this error occurs I can still boot the system. I suppose this grubenv error is because standalone doesn't have <archive / own environment>/boot/grub/grubenv. The grubenv exist only inside <disk / partition>/boot/grub and standalone doesn't know anything about it. On the other hand, "grub install" (grub non standalone) knows this location and that's why the error doesn't appear there. See "12.3.1 Technical Information" for details https://wiki.archlinux.org/title/GRUB/Tips_and_tricks#Technical_information
I don't think this error is key here.
I also tried to execute
Code: | chainloader (hd0,gpt1)/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi |
inside the rescue grub, where (hd0,gpt1) is my location. The same "cannot load image." error occurred.
If you want I can change this menuentry, but everything indicates that this is not the problem.
Nowa wrote: | What is in the .cmdline section of your UKI? |
What is the best method to find it out? I use gentoo-kernel and I enter my luks command for encrypted root via dracut config.
Code: | cat /proc/cmdlline
root=UUID=<my root id> rs.luks.uuid=<my partition id> rd.lvm.vg=vg0 |
|
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Tue Nov 05, 2024 1:04 pm Post subject: |
|
|
nxe9 wrote: | Nowa wrote: | What is in the .cmdline section of your UKI? |
What is the best method to find it out? I use gentoo-kernel and I enter my luks command for encrypted root via dracut config.
Code: | cat /proc/cmdlline
root=UUID=<my root id> rs.luks.uuid=<my partition id> rd.lvm.vg=vg0 |
|
Code: |
objcopy /boot/EFI/Linux/gentoo-6.6.58-gentoo-dist.efi --dump-section .cmdline=/tmp/cmdline /tmp/dump.efi
cat /tmp/cmdline
|
I find this all very confusing, I'd expect the chainload command to not do anything different compared to when UEFI loads that efi file.
The grubenv problem is starting to make sense at least. I wonder if we need to modify something in the ebuild/documentation to make this less confusing. Obviously it cannot load $prefix/grubenv since it cannot know where $prefix is physically, but maybe we can make it use grubenv from the same location that the grub.cfg is in. _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
nxe9 Tux's lil' helper
Joined: 05 Jun 2021 Posts: 116
|
Posted: Tue Nov 05, 2024 1:24 pm Post subject: |
|
|
... cat /tmp/cmdlline gives the same result as cat /proc/cmdlline above.
Interestingly, chanload works, but only in the absence of secure mode. This is also not due to incorrect signing of the bootloader / UKI. Because if I don't sign grub, I get an error from the UEFI level "Secure boot violation" and my signed UKI works without any problem with secure boot option without grub.
In short, there is some problem in the following case:
secure boot + grub + UKI (+cmdline).
Maybe that's why someone on reddit also wrote about some Ubuntu patches.
At least I know I have alternatives for secure boot:
1. UKI without grub.
2. non UKI with grub |
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 429 Location: Nijmegen
|
Posted: Tue Nov 05, 2024 3:24 pm Post subject: |
|
|
nxe9 wrote: | Maybe that's why someone on reddit also wrote about some Ubuntu patches. |
Could be, but it's still strange/a bug. Maybe the problem is that the chainload command is not going through shim and instead the firmware is directly requested to load the efi file, which would of course fail because the UEFI generally does not accept the keys in the MOK list. At least that is the general idea I am getting when looking at Ubuntu's patches (I wish they had provided a more clear patch description, and/or sent more of this upstream).
Debian/Ubuntu's patches are here: https://git.launchpad.net/ubuntu/+source/grub2/tree/debian/patches
There's a secureboot directory there which presumably contains the patches you'd need, but I'm just speculating, I have no idea if those patches by themselves will resolve your problem.
[EDIT] Fedora seems to also have a patch for this: https://src.fedoraproject.org/rpms/grub2/blob/rawhide/f/0215-Add-secureboot-support-on-efi-chainloader.patch (their patch description is a bit better and confirms what I suspected) _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
|