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.
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.
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.
For BOOTBOOT, no changes are required to boot in UEFI.
Worth noting that some BIOS-only facilities like text mode won't be available when using UEFI and therefore the kernel should request a linear framebuffer instead in its stivale header. Other than that, the stivale protocols are made in such a way as to make booting from BIOS or UEFI as unified and with as little differences as possible.
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.
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
- Multiboot header example in assembly