-
Notifications
You must be signed in to change notification settings - Fork 3
Boot
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.
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:
-
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.
-
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.
-
The stack-pointer is loaded, to the top of a built-in stack of fixed size (2 or 4-KB).
-
The
LoadKernel
function is called, pushing the arguments passed by the bootloader in the registers. -
A temporary console is initialized at the 0xB8000 address, whose implementation is a copied subset of the
Console.cpp
used in theKernelHost
module in theGeneric/EarlyConsole.c
file of this module. -
Multiboot 2 utility functions are initialized by setting the pointer to the first tag and last tag.
-
All modules are scanned, and their segments sizes, symbol count, string-table size, and total module count parameters are noted down.
-
Based on these parameters, the total kernel environment buffer size is calculated.
-
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.
-
The kernel environment is zeroed out and the relocator is initialized based on the parameters noted.
-
All module-based work is done - copying segments, relocation, copying symbols and string tables, etc.
KernelModule
objects are also used in the process. -
The
"KernelHost"
module is found by its CMD_Line field in the multiboot table. -
The entry point of the module is called based on its signature (given in the
Initor
module wiki). -
The kernel-host's entry point
HostEntry
(@fileArch/IA32/Boot/Entry.S
) takes over and sets the new stack-pointer in the top of the AUTO_DAT buffer provided by theInitor
module (see theInitor
wiki), and the arguments passed by theInitor
module are copied onto the new stack. -
The
EarlyMain
function is called which locates the page-tables and then initializes page-protection. During this process, the execution control jumps to theCallMain
function afterHostEntry
. -
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 theModuleLoader
subsystem. -
From here, the HAL starts initialization of the hardware.