Haiku Bootstrap Architecture
This article will describe current state of Haiku bootstrap architecture. It will unveil information about earliest boot stages, some hints to platform porters will be given. This can be interpreted as an extension to Haiku Article How to get Haiku booted.
Here we draw various boot scenarions that are independent from OS and depends only from hardware architecture. Current status on each platform and its perspectives will be discussed.
- x86 legacy systems has many options to load first stage loader. It can be boot within other loaders such as LILO, GRUB, U-Boot or directly via MBR tiny bootstrap code. x86 stage 1 boot code can be found in stage1.bin and is placed in the start of BFS partition. Other option for x86 new systems is to boot first stage Haiku loader from EFI firmware that is similar to wide known OpenFirmware hardware abstraction standard.
Currently Haiku on x86 can be booted from MBR or other boot loaders (LILO, GRUB, etc). It just hands control (chainload) to the stage 1 BFS Boot Code directly. Stage 1 and Stage 2 bootloaders are passed. Modern EFI boot process not supported but GUID Partition Table is. Newer version of GRUB2 does support BFS so it is possible with GRUB2 to load Stage 2 haiku_loader without BFS Boot Code, but it is untested, though.
- ARM boards usually have OpenFirmware or U-Boot on its ROM. Widely used in ARM development is U-Boot monitor that is also a kind of loader. It has support of loading images from ext2, JFFS, TFTP, NFS and other filesystems. But BFS support in U-Boot is definetly missing.
Currently stage 2 bootloader on ARM can be booted only from U-Boot directly within using special form of gzipped bootable image (uimage) prepared with U-Boot mkimage tool. This is temporary state of things as stage 1 bootloader (BFS Boot code) is not used. Stage 2 is passed though.
- PowerPC machines and development boards are also use both OpenFirmware ROMs and U-Boot ROMs (such as SAM440ep). But more common for PowerPC world is to use OpenFirmware (Pegasus, Apple, IBM).
Currently stage 2 bootloader on PowerPC can be booted as binary image only from OpenFirmware directly in a form of ISO 9660 image. Stage 1 bootloader (BFS Boot Code) is not used. Stage 2 is not passed.
BFS Boot Code
The main purpose of first stage boot loader is to load haiku_loader binary image that resides on BFS partition /system/haiku_loader. Normally BFS Boot Code is platform dependend and must be implemented for any supporting platform.
Pretty attractive case of loading stage 2 bootloader is to provide BFS access (searching by BFS nodes for haiku_loader) directly from ROM (stage 0 bootloader). This is already done for ext2 filesystems in U-Boot or ISO9660 in OpenFirmware. It is possible for hardware manufacturers provide modified version of ROM.
BFS Boot Code detects drive id, check if we have disk extension provided by the BIOS, load the rest of the stage 1 bootloader, validate the BFS superblock, search the stage 2 bootloader on disk, load the stage 2 bootloader into memory and run the stage 2 bootloader.
Stage 1 boot code can be found in /src/system/boot/platform/bios_ia32. The offset of the partition in 512 byte blocks must be written at position PARTITION_OFFSET_OFFSET or otherwise the code can't find the partition. The partition must be a BFS formatted. The stage 2 boot loader — /system/haiku_loader loaded into memory at 0x1000:0x0000 and entered at 0x:1000:0x0200 with EAX (partition offset in 512 byte blocks) and DL (BIOS ID of the boot drive).
makebootable binary utility makes the specified BFS partitions/devices bootable by writing BFS boot code into the first two sectors. It doesn't mark the partitions active. This utility can be compiled to run under BSD, Linux, Mac OS X, BeOS and Haiku hosts. In the case of a missing makebootable we never get to that stage 2 bootloader. You can read more about makebootable in Haiku Article about makebootable.
Haiku loader is second stage boot loader. It is presented as haiku_loader binary image that resides on BFS boot partition. The main purpose of second stage boot loader is to load relocated kernel. It draws Menu select boot device with BFS partition, collecting kernel startup settings and passes them to kernel.
The second stage boot loader divided onto two parts: platform dependent that is startup entry point itself and platform dependent functions and such as video framebuffer or video console platform dependent functions and platform independent menu, file system support and main platform independent function.
Hardware Abstraction Layer
All platform dependent functions (hardware abstraction layer) that is used in Haiku Loader can be divided into following groups: Menu, Devices, Memory, Serial Port, Keyboard, Video, Processor. Memory is about to manage basic mmu settings and second stage loader's heap. There are two MMU modes: one is for haiku loader and second is for kernel bootstrap.
For each hardware platform must be implemented following functions:
- Menu: platform_add_menus, platform_update_menu_item, platform_run_menu
- Devices: platform_add_boot_device, platform_get_boot_partition, latform_add_block_devices, platform_register_boot_device
- Memory: platform_init_heap, platform_release_heap, platform_allocate_region, platform_free_region, mmu_map_physical_memory, mmu_allocate, mmu_free, mmu_init, mmu_init_for_kernel
- Serial Port: serial_putc, serial_disable, serial_enable, serial_cleanup, serial_init
- Keyboard: clear_key_buffer, wait_for_key, check_for_boot_keys
- Processor: cpu_init
- Boot: platform_start_kernel
This hardware abstraction layer functions are resides in Haiku repository in haiku/src/system/boot/platform/* directories.
Platform Independent Code
Platform independent Haiku Loader code lives in /src/system/boot/platform/generic and /src/system/boot/loader directories. The platform dependent bootstrap code fires up main function in platform independent part of loader directly.
The main function of second stage loaders inits heap, video. Then its retrieve boot filesystem to boot up, if no found it shows user menu. Then it loads modules and kernel with elf_load_image and starts kernel by calling platform_start_kernel from HAL API.