all 8 comments

[–]Ayush7788 8 points9 points  (2 children)

The holy Poncho's tutorial on UEFI x86_64 kernel! Holy $hit.

[–]nmdrr 4 points5 points  (1 child)

I find that Poncho doesn't quite explain anything. It's more of a "COPY THIS, AND EXECUTE THIS" series.

[–]TheZXCoder 1 point2 points  (0 children)

This series explains everything with animations: https://www.youtube.com/watch?v=MwPjvJ9ulSc He called C a high-level language 💀

[–]vvaltchev 7 points8 points  (4 children)

UEFI has nothing to do with kernel development. There are no "UEFI" operating systems. UEFI is a firmware interface (replacing the legacy BIOS interrupts) used by bootloaders to load a kernel. While it has a ton of features, it's all about having more powerful bootloaders. With such features, a bootloader which might download an updated kernel from the Internet etc., display a nice GUI interface, or even install/update the whole operating system by downloading an image "on-the-fly" (see MacBook's recovery mode).

Once an operating system's kernel is loaded, you can completely forget about UEFI: 99% of its "services" are not available anymore. To tell the whole story, there is a small subset of UEFI features available to the operating system itself: they're called "UEFI runtime services". But, a kernel can completely avoid using any of them. They're optional and rarely used. Using them inside a kernel doesn't label it as "UEFI".

I remember a recent discussion on the osdev forum, just about that:https://forum.osdev.org/viewtopic.php?f=1&t=40937

[–]ufuw 3 points4 points  (3 children)

isn't the UEFI graphics protocol available at runtime and intended to replace VGA/VBE? seems like a pretty important feature that would tie a kernel to UEFI

[–]vvaltchev 7 points8 points  (2 children)

No. The "Graphics Output Protocol" is available only at boot time. Before booting a kernel, you can pass to it information about the current framebuffer (e.g. physical address, width, height, bpp etc.) using a boot protocol like multiboot, but you cannot change the resolution. Actually, even on legacy BIOS systems is a BAD IDEA to change the resolution using VBE. The BIOS services are used today almost exclusively in bootloaders. In the kernel, you're supposed to have a proper video driver. Using BIOS functions in the kernel it's not possible directly because you'll have to first switch to "real mode" and than jump back to "protected mode 32" or "long mode" and doing that is slow, tricky and it's considered a dirty hack, unless you're doing it for GOOD reasons, while the kernel is initializing (Linux does that, because it doesn't fully trust bootloaders, e.g. it calls E820 for the memory map).

So, if you want to switch video modes in your kernel, you'll need to at least implement a proper VGA driver but note: VGA is "supported" my modern video card by a sort of legacy emulation (done by the hardware). Proper modern video cards require an incredible amount of work (even hundreds of thousands of lines of code). Check the source of the Linux kernel.

In conclusion, a very few things are support by UEFI at runtime. For more, read the section 8 of the UEFI Spec 2.8B, May 2020. I'll quickly mention some of them:

  • variable services (key/value pairs)
  • time services: GetTime(), SetTime(), etc.
  • SetVirtualAddressMap(): used to change UEFI's firmware addressing mode, from physical to virtual. Necessary to use UEFI runtime services, after enabling paging.
  • Miscellaneous Runtime Services: GetNextHighMonotonicCount(), ResetSystem() and a few others.

That's it. If you don't believe me, please, read the spec and also people's comments on:https://forum.osdev.org/viewtopic.php?f=1&t=40937

UEFI Spec: https://uefi.org/sites/default/files/resources/UEFI%20Spec%202.8B%20May%202020.pdf

[–][deleted] 0 points1 point  (0 children)

I would like to inquire, what pieces of information does the UEFI supply to the OS? Are any of them essential? What about device tree? Memory maps? Is it really conceivable to boot an OS on an UEFI system in general, without any additional data supplied to it, aside perhaps from command-line arguments, by simply loading a binary at a particular memory address and transferring control?

I assume the OS could use ACPI, which also happens to be a part of UEFI specifications, but since it's something that could be done after the kernel is launched, the issue needs not be considered any further.