Porting to UEFI
In recent years, UEFI has taken over firmware duties in PC-compatibles. Most modern machines use UEFI firmware. A goal for OS developers may be to have their OS boot using UEFI natively (as opposed to legacy BIOS or CSM). If you followed the legacy Bare Bones tutorial, and you want your OS to work on real hardware, then you may wish to know this information.
Changes
Most UEFI implementations do implement compatibility with legacy BIOS in the form of CSM (compatibility support module), so you may not need to make your OS UEFI compatible. However Intel already announced the removal of CSM by 2020, so relying on it is not future-proof. Just note that not all machines may support CSM and therefore it may be worth it to make your OS UEFI capable.
However, one breaking change that will definitely affect your OS is that UEFI does not support traditional CGA text mode. You are required to use graphics mode, and there is no text mode emulation in place.
Here are a few mandatory changes for legacy-BIOS OSes:
- You will need to write your own (new) terminal driver that uses bitmap fonts to draw text onto the screen.
- You will need to request a graphical framebuffer from your bootloader.
Porting
Boot Process
GRUB
For GRUB, you will need to specify that you wish to request a linear framebuffer in your multiboot header.
Worth noting that one may be wanting to use multiboot2 instead of multiboot as the latter does not provide the kernel with critical information such as the RSDP address.
BOOTBOOT
For BOOTBOOT, no changes are required to boot in UEFI.
Limine
The Limine boot protocol allows a kernel to run mostly unmodified on both UEFI and BIOS.
Custom Bootloaders
For custom bootloaders, you are on your own, obviously.
One starting point would be to figure out a standardised boot protocol to use to load your kernel from both a BIOS version of your loader and a UEFI one.
One could also decide to ditch BIOS compatibility entirely and have the kernel rely on UEFI facilities directly, although for the sake of portability this is discouraged.
Terminal
For your terminal driver, you can roll your own, or use a library.
Your options include:
- Using the Scalable Screen Font library
- Creating your own driver using PC Screen Fonts
- Creating your own driver using 8x8 fonts, stored as 64-bit unsigned integers (see section "Displaying a character" on VGA Fonts)
For a few examples of graphical terminal drivers, refer to the links section at the bottom.
What about 32-bit OSes?
Most UEFI firmware is designed for x86-64, so therefore if your kernel is designed for x86 or i386, you will need to either
- Port your OS to x86-64, or
- Create a trampoline at your kernel entry which drops you back down to protected mode from long mode
Links
Multiboot example
- Multiboot header example in assembly
Terminal drivers
- MultibootBasicGraphics
- BOOTBOOT's example Hello World kernel (bare minimum PC Screen Font driver)