Multiarch 64 bit Kernel in development
Targets:
- x86_64
- aarch64
Design in order of initialization
- Limine Bootloader loads kernel and sets entry point to _start in arch_entry.c
- arch_entry processes Limine requests, formats it to fit Arx boot protocol in boot.h then passes it to kmain in kernel.c
- Arx boot protocol needs
- Memory map
- Framebuffer
- Higher half direct memory
- Paging with no user access and RWX
- ACPI rsdp address
- SMP setup
- kmain will initialize kernel subsystems
- Global dispatcher variable which stores important global and per cpu data structures
- index by arch cpu id
Physical memory managment
- Zone is built from boot memory map
- Currently only one Numa node and zone but gives us space to scale into suporting Non Uniform Memory Access and different memory zones
Allocations | pmm_alloc(size)
Frees | pmm_free(addr)
Virtual memory managment
- page table managment apis (map/unmap/protect)
- each arch implements paging api
- also implement arch_map/unmap/protect_range functions
- optimization to avoid redundant page table walks , cache flushes and batching flushes
- instead of calling arch_map/unmap/protect_page on each page in a range which would be much slower
- vmm paging apis are wrappers over arch specific implmentation that lock on address space
Virtual address space management
- uses canonical addressing
- on vmm init we init the initial address space by subtracting hhdm, framebuffer, and kernel form the kernel address space
Virtual address space structure
Reserve region in address space
Free region in address space
Klib allocations
- vmalloc and vfree
- uses pmm and vmm api to allocate large contiguous virtual memory chunks
- slow due to needing to map pages
- Limine provides SMP cpu list and bsp id through the boot info
- BSP runs arch_smp_init(boot_info) after base kernel init in kmain
- arch_smp_init walks all cpus and skips the BSP
- each AP gets goto_address = smp_entry set from its Limine SMP record
- AP enters smp_entry and then calls smp_kmain
- smp_kmain runs per-core arch init
ran on each smp core
- x86_64
- build and install 64 bit GDT for kernel and user segments including a TSS
- build and install IDT all isrs call a common isr handler and jumps to c code ISRHANDLER passing regs
- get mdat from acpi using uacpi
- get per core lapic info from mdat
- init lapic per core
- init per core lapic timer
- init global ioapic (masking all entries)
- get iso overides from mdat
- route legacy irqs to bsp lapic
- expose api to mask/unmask vectors, register new vectors, and route vectors
- Limine - Bootloader/protocol used to load the kernel and provide boot info.
- printf - Small freestanding printf implementation used for kernel logging output.
- uACPI - ACPI implementation used for table parsing and ACPI support.
All third-party components retain their original licenses.
- Build system and scripts are AI generated
- selftest.c is AI generated testing of kernel subsystems