System initialization #
During boot, the kernel initializes the hardware and prepares the “init” task. The init process image (an ELF file) is provided to the kernel through the bootloader, such as (on x86_64) via multiboot modules, similar to an initramfs on Unix-like systems. The kernel will allocate an address space and physical pages to map the ELF sections into, as well as a capability space and various architecture-specific objects (such as an IOControl capability to manage I/O ports on x86_64). It places the capabilities for all of these objects into init’s own capability space, then enumerates remaining physical memory and places memory capabilities into this capability space as well, allowing init to make use of system resources at its discretion. The kernel additionally prepares a “bootinfo” structure, which provides the init task with some information about the system state, such as its command line arguments via the bootloader, the list and nature of memory regions on the system, and so on.
Thread-local storage #
The kernel’s init loader will load the userspace thread-local sections, if present, into memory. The relevant pages will be included in the bootinfo image capabilities. This is the TLS master structure, and is mapped read-only. Userspace should allocate a copy of the master area for the initial thread read/write, and can allocate additional copies as necessary. The task object provides a “write_segments” call which can be used to configure the architecture-specific TLS base register (i.e. %fsbase on x86_64).
Image format #
The init image is an ELF file. Essentially any configuration is permitted, with the following caveats:
- The TLS sections, if present, should have PHDRS set to PT_NULL and a base address of zero.
- Addresses 0x7fff80000000 and above are reserved for the kernel to allocate initial data structures (e.g. init’s IPC buffer, stack, etc)
A good starting point for preparing a suitable ELF file is vulcan’s hare.sc.