GSoC'24: Linux x86 Boot Protocol Support

The Linux boot protocol plays an important role in the initialization of the Linux operating system, emphasizing the importance of system optimization and scalability.

Project overview#

The Linux boot protocol plays an important role in the initialization of the Linux operating system, emphasizing the importance of system optimization and scalability. This system ensures a seamless transfer of control from the bootloader to the Linux kernel by providing essential information including memory map, command line parameters, and device specifications. By adhering to a uniform boot protocol, Linux achieves a level of versatility across the hardware spectrum of architectures and bootloader functions. Essentially, this protocol is a commitment to a standardized approach that is not only stable but also facilitates bootloader development, improving compatibility and reliability. In particular, the Linux boot protocol greatly contributes to the overall robustness and reliability of the bootstrapping process on Linux-based systems. Almost, if not all, widely available bootloaders that exist on the market are able to speak this protocol and Unikraft, being unable to be detected by these bootloaders as a Linux Boot Protocol compliant system, is hindering the ability to boot on a very large amount of platforms.

Current Progress#

I already compiled qemu 9.0.1 using the following flags: --enable-debug --extra-cflags="-g3" --extra-ldflags="-g3" --disable-strip --enable-kvm --enable-avx2 --enable-avx512bw --enable-avx512f to help me debug. At the moment, I am looking into creating support/scripts/ using as inspiration the already existing and the ARM64 PR. The script mainly contains functions that help parse and set certain fields of the image header.

The header will look as follows:

01F1/1ALL(1)setup_sectsThe size of the setup in sectors
01F2/2ALLroot_flagsIf set, the root is mounted readonly
01F4/42.04+(2)syssizeThe size of the 32-bit code in 16-byte paras
01F8/2ALLram_sizeDO NOT USE - for bootsect.S use only
01FA/2ALLvid_modeVideo mode control
01FC/2ALLroot_devDefault root device number
01FE/2ALLboot_flag0xAA55 magic number
0200/22.00+jumpJump instruction
0202/42.00+headerMagic signature “HdrS”
0206/22.00+versionBoot protocol version supported
0208/42.00+realmode_swtchBoot loader hook (see below)
020C/22.00+start_sys_segThe load-low segment (0x1000) (obsolete)
020E/22.00+kernel_versionPointer to kernel version string
0210/12.00+type_of_loaderBoot loader identifier
0211/12.00+loadflagsBoot protocol option flags
0212/22.00+setup_move_sizeMove to high memory size (used with hooks)
0214/42.00+code32_startBoot loader hook (see below)
0218/42.00+ramdisk_imageinitrd load address (set by boot loader)
021C/42.00+ramdisk_sizeinitrd size (set by boot loader)
0220/42.00+bootsect_kludgeDO NOT USE - for bootsect.S use only
0224/22.01+heap_end_ptrFree memory after setup end
0226/12.02+(3)ext_loader_verExtended boot loader version
0227/12.02+(3)ext_loader_typeExtended boot loader ID
0228/42.02+cmd_line_ptr32-bit pointer to the kernel command line
022C/42.03+initrd_addr_maxHighest legal initrd address
0230/42.05+kernel_alignmentPhysical addr alignment required for kernel
0234/12.05+relocatable_kernelWhether kernel is relocatable or not
0235/12.10+min_alignmentMinimum alignment, as a power of two
0236/22.12+xloadflagsBoot protocol option flags
0238/42.06+cmdline_sizeMaximum size of the kernel command line
023C/42.07+hardware_subarchHardware subarchitecture
0240/82.07+hardware_subarch_dataSubarchitecture-specific data
0248/42.08+payload_offsetOffset of kernel payload
024C/42.08+payload_lengthLength of kernel payload
0250/82.09+setup_data64-bit physical pointer to linked list of struct setup_data
0258/82.10+pref_addressPreferred loading address
0260/42.10+init_sizeLinear memory required during initialization
0264/42.11+handover_offsetOffset of handover entry point

For more details about certain fields, read here.

Next Steps#

Once everything works for QEMU, I will move onto GRUB2 and look into making lxboot x86 work with it as ISO and as Disk. Boot loaders have unique reserved identifiers, placed in the type_of_loader field. The type_of_loader field will contain 0xTV, where T is the loader's ID and V is its version. If a boot loader does not have a ID, use 0xFF.

Assigned boot loader ids (hexadecimal):

0LILO (0x00 reserved for pre-2.00 bootloader)
2bootsect-loader (0x20, all other values reserved)
CArcturus Networks uCbootloader
EExtended (see ext_loader_type)
FSpecial (0xFF = undefined)
11Minimal Linux Bootloader
12OVMF UEFI virtualization stack

About Me#

I am Mihnea Firoiu, a second year Computer Science and Engineering student at University POLITEHNICA of Bucharest. My main interests are operating systems, low-level programming and cyber security.

Edit this page on GitHub

Connect with the community

Feel free to ask questions, report issues, and meet new people.

Join us on Discord!

Getting Started

What is a unikernel?Install CLI companion toolUnikraft InternalsRoadmap

© 2024  The Unikraft Authors. All rights reserved. Documentation distributed under CC BY-NC 4.0.