Page 1 of 1

UEFI booting

Posted: Mon Jun 08, 2020 6:06 am
by PeterX
What are the (rough) differences between these x64 UEFI bootloaders:
- systemd-boot
- Shim
- Grub64.efi

And do you for your x64 UEFI kernel (if you have one) use a bootloader; or do you implement the kernel as an UEFI application?

Greetings
Peter

Re: UEFI booting

Posted: Mon Jun 08, 2020 9:31 am
by Octocontrabass
PeterX wrote:What are the (rough) differences between these x64 UEFI bootloaders:
- systemd-boot
- Shim
- Grub64.efi
systemd-boot is a simple menu that allows you to choose which EFI executable to load from your EFI system partition. It doesn't support multiboot or secure boot.

shim provides a way to securely load one signed EFI executable without installing non-Microsoft keys in your firmware. It doesn't provide a menu and it doesn't support multiboot. It can be used to load another loader if you want a menu.

GRUB is everything and the kitchen sink. The one thing it can't do is secure boot without a non-Microsoft key. If you want to use GRUB with secure boot and your firmware doesn't allow you to install non-Microsoft keys, you need something like shim to provide a bridge between the firmware's Microsoft keys and whichever keys were used to sign GRUB.

Re: UEFI booting

Posted: Mon Jun 08, 2020 4:14 pm
by bzt
PeterX wrote:What are the (rough) differences between these x64 UEFI bootloaders:
- systemd-boot
- Shim
- Grub64.efi
I know what's common in them: all are way too bloated to my taste :-D You should add elilo (not maintained any more, but its code is MUCH better than grub's) and rEFind (which is Mac-only, but very readable source code). And of course if you want to avoid bloatware, you can always use BOOTBOOT ;-)
PeterX wrote:And do you for your x64 UEFI kernel (if you have one) use a bootloader; or do you implement the kernel as an UEFI application?
I don't think implementing a kernel as an UEFI app is a good idea at all. It ties you to a certain platform, who's interface might not be available in the future (like UEFI already dropped UGA and many other protocols. What if they drop something that's essential to your kernel?)

Cheers,
bzt

Re: UEFI booting

Posted: Mon Jun 08, 2020 4:25 pm
by kzinti
bzt wrote: rEFind (which is Mac-only, but very readable source code).
Interesting. I've been using rEFind for over a year and I don't have a Mac.

Rest assured rEFind works just fine without a Mac.

Re: UEFI booting

Posted: Tue Jun 09, 2020 7:37 am
by PeterX
bzt wrote:I don't think implementing a kernel as an UEFI app is a good idea at all. It ties you to a certain platform, who's interface might not be available in the future (like UEFI already dropped UGA and many other protocols. What if they drop something that's essential to your kernel?)
Do I have to deal with a memory map exactly like when booting from Legacy BIOS? Or is there a C pointer to some other kind of mem map? (I've seen what seemed to be C pointers in texts about UEFI.)

I'm currently reading the UEFI specs 2.8 (final) but it has 2500 pages. So it's a bit hard to learn from it. And I had the book "Beyond BIOS" (which is about UEFI, too) but that was even worse to understand for me. Maybe the osdev.org wiki about UEFI is the best starting point for me; I will try that.

Greetings
Peter

Re: UEFI booting

Posted: Tue Jun 09, 2020 9:11 am
by bzt
kzinti wrote:Interesting. I've been using rEFind for over a year and I don't have a Mac.

Rest assured rEFind works just fine without a Mac.
My apology. It was rEFit from which rEFInd was forked from that was Mac only. You are correct!
PeterX wrote:Do I have to deal with a memory map exactly like when booting from Legacy BIOS? Or is there a C pointer to some other kind of mem map? (I've seen what seemed to be C pointers in texts about UEFI.)
Check out BOOTBOOT. It provides a platform independent memory map for your kernel. It uses E820 on Legacy BIOS, and EFIMemoryMap on UEFI (also VC MailBox messages on RaspberryPi), but your kernel doesn't need to know that. It gets the memory map in the same format regardless.

To answer your question, no, there's no simple pointer; you have to make calls to UEFI funtions, iterating on the list (the map might change during iteration, so it is a tricky thing. ExitBootServices will fail is the map changed, and PrintLn WILL change the map as it allocates memory for the string to print.).

Cheers,
bzt

Re: UEFI booting

Posted: Tue Jun 09, 2020 4:14 pm
by ajxs
PeterX wrote: Do I have to deal with a memory map exactly like when booting from Legacy BIOS? Or is there a C pointer to some other kind of mem map? (I've seen what seemed to be C pointers in texts about UEFI.)
There's a function available that will provide you a memory map. It's referred to as EFI_BOOT_SERVICES.GetMemoryMap() and a reference can be found on page 164 of the latest UEFI standard.
As bzt noted, just about any interaction with EFI services will change the memory map. The EFI_BOOT_SERVICES.ExitBootServices() function will actually authenticate your memory map, throwing an error if it has changed since you retrieved it. The specification states (emphasis theirs):
A UEFI OS loader must ensure that it has the system’s current memory map at the time it calls ExitBootServices(). This is done by passing in the current memory map’s MapKey value as returned by EFI_BOOT_SERVICES.GetMemoryMap() Care must be taken to ensure that the memory map does not change between these two calls. It is suggested that GetMemoryMap() be called immediately before calling ExitBootServices(). If MapKey value is incorrect, ExitBootServices() returns EFI_INVALID_PARAMETER and GetMemoryMap() with ExitBootServices() must be called again.