I am working on a UEFI Based Hypervisor for Intel x86 platform. The GRUB is being used to load both the VMM and OS images, for reducing the complexity I am currently loading only one GPOS through GRUB and obviously the VMM. However due to some design issues, I don't want to use EFI Services within Hypervisor. During my research regarding this topic, I came across a post or comment which stated that GRUB can call the ExitBootService which will solve my issue. But there is no proper documentation about how to actually call ExitBootService through the GRUB. Would be really helpful if someone could guide me a little about calling ExitBootService through the GRUB.
-
I think it will be a mistake to call ExitBootServices before the hypervisor starts. Usually the hypervisor will need to call EFI during initialization. For example, it will need to get the memory map. – prl May 24 '19 at 07:16
-
In any case, it might be easiest to call ExitBootServices from the startup code of the hypervisor rather than trying to get Grub to do it. – prl May 24 '19 at 07:17
-
Oh, I just realized that maybe you can get the memory map from Grub, so maybe you’re right that you don’t need to call EFI at all. – prl May 24 '19 at 07:20
-
@prl yes exactly. I want to get E820 Memory map and Graphics Frame Buffer HOB from the GRUB, actually I am implementing Virtualized UEFI Firmware which is being loaded by the Hypervisor. Since the design I am working on, is becoming a lot complex, So calling ExitBootService from the GRUB is my first priority. Do you know, how can GRUB call the ExitBootService ? – Ameer Hamza May 24 '19 at 07:33
-
1No, I have no idea how to do it from Grub. I would just do it from the hypervisor. – prl May 24 '19 at 07:51
-
While I've written a rudimentary reply, could you please update the question with the information you want/need to pass across from GRUB to your hypervisor? – unixsmurf May 24 '19 at 08:54
-
@AmeerHamza: If you have enough knowledge of UEFI to write your own UEFI firmware; why not just write your own boot code for UEFI and avoid the restrictions, bloat and install-time hassles of GRUB completely? – Brendan May 24 '19 at 12:14
2 Answers
For Multiboot2; the default behavior on UEFI systems is that the boot loader (e.g. maybe GRUB) calls ExitBootServices()
and the OS does nothing. To change that you need to use special tags in the multiboot header (see 3.1.12 EFI boot services tag
in the Multiboot2 spec) to inform the boot loader that you don't want it to call ExitBootServices()
.
For Multiboot1; there was no support for UEFI. In this case; if a boot loader supports being started from UEFI it must call ExitBootServices()
before starting an OS that complies with Multiboot1. Note that technically this violates the Multiboot1 spec which says that the boot loader must leave firmware in a usable state, but this is impossible to do (e.g. there's no way for boot loader to tell the OS where the EFI system table is) and not usable in practice (e.g. an OS designed for Multiboot1 is likely to assume "BIOS" and crash anyway because there's no way for the OS to guess what kind of firmware it was).
For other "OS specific" methods supported by GRUB; some aren't usable on UEFI systems at all (e.g. the old "chain-loading" de-facto standard from BIOS) and the others (if they work) would comply with the requirements of whichever OS invented it (e.g. the "Linux boot protocol" that Linux developers created for Linux, the "NetBSD boot protocol" that's used by NetBSD and FreeBSD, etc). I have no idea what happens for any of the OS specific cases (it's fairly unimportant unless you're working on an OS that uses it).
Note: Feel free to replace each occurrence of "OS" with "hyper-visor" (or "kernel" or whatever else GRUB might be passing control to).

- 35,656
- 2
- 39
- 66
I would agree with the comments saying it would be better to do this yourself in your hypervisor. The main reasons being that if you do it in GRUB:
- you end up writing a custom image loader for your hypervisor (which is no less effort than adding this support in your hypervisor)
- you create an ABI between that loader and your hypervisor (which you need to manage for any future changes)
E820 may work for some platforms, for a while, but it is a legacy from old-style BIOS and not something guaranteed to be available in a UEFI system.
Which is why Linux these days embeds a small "stub loader" in the kernel image to do the transition.
So you need to get the UEFI memory map and the Graphics Output Protocol across to your hypervisor.
If you still want to go down the route of your custom loader, have a look at the i386/bsd
or i386/xnu
loaders and their use of grub_efi_finish_boot_services
/grub_autoefi_finish_boot_services
.

- 5,852
- 1
- 33
- 40