Skip to content
Sukant Pal edited this page Jul 1, 2018 · 2 revisions

Boot Process

Due to the abstraction provided by the multiboot specification, the boot process in the Silcos kernel is relatively logical and simple compared to other kernels like Linux. It doesn't include basic and low-level hardware initialization like enabling the A20 gate. As per the multiboot-specification, the boot-loader loads the Initor module in physical memory which, in turn, allocates a kernel environment for rest of the modules.

Booting on the IA32 platform

On the IA32 architecture, the boot-loader will copy the Initor segments at the 0x100000 (1-MB) address. The Initor module is actually a static executable designed to be placed at this address, unlike all other kernel-modules which are shared-libraries or dynamic executable files.

The Initor module boot process goes as follows, starting from the IA32/LoadKernel.c file:

  1. All interrupts are disabled to check against any spurious interrupts/device-interrupts while the kernel is not ready to handle such advanced features at the moment.

  2. A default boot-GDT is loaded with three segments - null, kernel-code and kernel-data. Although the boot-loader guarantees that all segments (code & data) will be flat, this is just an extra step of stability - especially, if the kernel environment overwrites the unknown location of the boot-loader's GDT.

  3. The stack-pointer is loaded, to the top of a built-in stack of fixed size (2 or 4-KB).

  4. The LoadKernel function is called, pushing the arguments passed by the bootloader in the registers.

  5. A temporary console is initialized at the 0xB8000 address, whose implementation is a copied subset of the Console.cpp used in the KernelHost module in the Generic/EarlyConsole.c file of this module.

  6. Multiboot 2 utility functions are initialized by setting the pointer to the first tag and last tag.

  7. All modules are scanned, and their segments sizes, symbol count, string-table size, and total module count parameters are noted down.

  8. Based on these parameters, the total kernel environment buffer size is calculated.

  9. A continuous region in physical memory is allocated so that it can hold the kernel environment, and the page-frame entries required by the physical memory allocator (in the kernel-host module) at the next 2-MB boundary.

  10. The kernel environment is zeroed out and the relocator is initialized based on the parameters noted.

  11. All module-based work is done - copying segments, relocation, copying symbols and string tables, etc. KernelModule objects are also used in the process.

  12. The "KernelHost" module is found by its CMD_Line field in the multiboot table.

  13. The entry point of the module is called based on its signature (given in the Initor module wiki).

  14. The kernel-host's entry point HostEntry (@file Arch/IA32/Boot/Entry.S) takes over and sets the new stack-pointer in the top of the AUTO_DAT buffer provided by the Initor module (see the Initor wiki), and the arguments passed by the Initor module are copied onto the new stack.

  15. The EarlyMain function is called which locates the page-tables and then initializes page-protection. During this process, the execution control jumps to the CallMain function after HostEntry.

  16. The stack is adjust to the higher-half and from then Main is called. From there, the each subsystem is initialized - the debugger, console, physical memory allocator, virtual memory allocator, object/slab allcoator, and then the module-loader. Then the global object constructors are called, and the module-related data is imported by the ModuleLoader subsystem.

  17. From here, the HAL starts initialization of the hardware.

Clone this wiki locally