diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 16:28:44 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 16:28:44 +0800 |
| commit | 67cc7598da3a1cd02f06f9c0fd3f60ae2e7dc02f (patch) | |
| tree | 68f8e8fe5b31dea4033a71123ec3e576c736b54a | |
| parent | 8cbf571e56fd5ef631b51f4e5e3f181df1a529ff (diff) | |
| download | lume-67cc7598da3a1cd02f06f9c0fd3f60ae2e7dc02f.tar.gz lume-67cc7598da3a1cd02f06f9c0fd3f60ae2e7dc02f.tar.xz | |
feat: reorganize kernel_main initialization sequence and add syscall initialization
| -rw-r--r-- | na/kernel/main.cc | 252 |
1 files changed, 153 insertions, 99 deletions
diff --git a/na/kernel/main.cc b/na/kernel/main.cc index f566ecf..f28d078 100644 --- a/na/kernel/main.cc +++ b/na/kernel/main.cc @@ -13,13 +13,23 @@ * Reference: docs/specs/global_init.md */ -#include <lume/types.h> +#include <arch/cpu.h> #include <lume/atomic.h> -#include <lume/panic.h> +#include <lume/boot_params.h> +#include <lume/console.h> +#include <lume/driver.h> #include <lume/fdt.h> +#include <lume/irq.h> +#include <lume/klog.h> +#include <lume/kprintf.h> +#include <lume/memblock.h> #include <lume/pmm.h> -#include <lume/console.h> -#include <arch/cpu.h> +#include <lume/random.h> +#include <lume/sched.h> +#include <lume/trap.h> +#include <lume/types.h> +#include <arch/config.h> +#include <arch/extable.h> // ============================================================ // Forward declarations for subsystem init functions. @@ -28,25 +38,23 @@ // ============================================================ // BSP global init (strict order) -void console_init(); // 1. UART ready; kprintf/panic can output -void fdt_init(uint64 fdt_paddr); // 2. Parse FDT, build device node table -void pmm_init(); // 3. Buddy allocator ready -void slab_init(); // 4. kmem_cache ready; operator new usable -void vmm_init(); // 5. Fine-grained kernel page table; retire early_pgdir -void trap_init(); // 6. Set trap vector, register IRQ dispatcher -void plic_init(); // 7. Configure PLIC (threshold, priority, enable) -void timer_init(); // 8. Configure timer interrupt (scheduler tick) -void sched_init(); // 9. Create BSP Idle Task, init ready queues +void console_init(); // 1. UART ready; kprintf/panic can output +void fdt_init(uint64 fdt_paddr); // 2. Parse FDT, build device node table +void pmm_init(); // 3. Buddy allocator ready +void slab_init(); // 4. kmem_cache ready; operator new usable +void vmm_init(); // 5. Fine-grained kernel page table; retire early_pgdir +void task_init(); // 7. PID allocator + global task list +void timer_init(); // 8. Configure timer interrupt (scheduler tick) +void sched_init(); // 9. Create BSP Idle Task, init ready queues +void syscall_init(); // 10. Register syscall jump table // Boot self-test runner void selftest_run_all(); // AP per-CPU init -void vmm_init_ap(); // Switch to BSP-built kernel page table -void trap_init_ap(); // Set this CPU's trap vector -void plic_init_ap(); // Enable this CPU's PLIC context -void timer_init_ap(); // Start this CPU's timer interrupt -void sched_init_ap(); // Init per-CPU ready queue, create Idle Task +void vmm_init_ap(); // Switch to BSP-built kernel page table +void timer_init_ap(); // Start this CPU's timer interrupt +void sched_init_ap(); // Init per-CPU ready queue, create Idle Task // ============================================================ // Second-stage synchronization barrier (C++ layer) @@ -54,112 +62,158 @@ void sched_init_ap(); // Init per-CPU ready queue, create Idle Tas // ============================================================ static lume::atomic<uint32> ap_boot_sync; -// Early UART output functions, defined in lib/panic.cc -// They are safe to use before console_init(). -extern "C" void early_putc(char c); -extern "C" void early_puts(const char* s); - // ============================================================ // kernel_main — C++ entry point for all CPUs // ============================================================ extern "C" [[noreturn]] void kernel_main(uint64 cpu_id, uint64 fdt_paddr) { - if (cpu_id == 0) { - // ======================================================== - // BSP: Absolute single-core period — no locks needed. - // APs are spinning on ap_boot_sync. - // ======================================================== + if (cpu_id == 0) { + // ======================================================== + // BSP: Absolute single-core period — no locks needed. + // APs are spinning on ap_boot_sync. + // ======================================================== + + boot_params_init_fdt(fdt_paddr); + const BootParams* bp = boot_params_get(); + uint64 fdt_pa = bp ? bp->fdt_ptr : fdt_paddr; + + // Early console setup: discover UART via FDT before ANY output. + console_early_init(fdt_pa); + klog_init(); + + printk("\n"); + printk(KERN_INFO "LumeOS Kernel v0.1\n"); + printk(KERN_INFO "boot: BSP online, cpu_id=0\n"); + printk(KERN_INFO "boot: higher-half kernel active\n"); + + BOOT_STAGE(0, "firmware handoff"); + BOOT_STAGE(1, "bootloader handoff"); + BOOT_STAGE(2, "arch early asm complete"); + if (bp) { + if (bp->kimage_flags & BOOT_IMAGE_DECOMP_FAILED) { + BOOT_STAGE(3, "decompress failed"); + } else if (bp->kimage_flags & BOOT_IMAGE_COMPRESSED) { + BOOT_STAGE(3, "decompress ok"); + } else { + BOOT_STAGE(3, "decompress skipped"); + } + + if (bp->kimage_flags & BOOT_IMAGE_RELOC_FAILED) { + BOOT_STAGE(3, "relocate failed"); + } else if (bp->kimage_flags & BOOT_IMAGE_RELOCATED) { + BOOT_STAGE(3, "relocate ok"); + } else { + BOOT_STAGE(3, "relocate skipped"); + } + + printk(KERN_INFO "boot: kimage phys=0x%llx size=%llu reloc=%llu\n", + bp->kimage_phys_base, + static_cast<unsigned long long>(bp->kimage_size), + static_cast<unsigned long long>(bp->kimage_reloc_size)); + } else { + BOOT_STAGE(3, "decompress/relocate unknown"); + } + BOOT_STAGE(4, "early c init"); + + // --- Subsystem init DAG (strict top-down order) --- - // Early console setup: discover UART via FDT before ANY output. - console_early_init(fdt_paddr); + // 1. FDT parsing — make device tree available + fdt_init(fdt_pa); + printk(KERN_INFO "init: fdt_init done\n"); + // 2. KASLR — seed PRNG and randomise VA layout. + // MUST happen before vmm_init() builds the kernel page table. + { + uint64 kaslr_seed = 0; + fdt_early_get_kaslr_seed(&kaslr_seed); + random_early_init(kaslr_seed); + arch::kaslr_init(); + } - early_puts("\n\n"); - early_puts("====================================\n"); - early_puts(" LumeOS Kernel v0.1\n"); - early_puts("====================================\n"); - early_puts("[boot] BSP online, cpu_id=0\n"); - early_puts("[boot] Higher-half kernel active\n"); + // Sort exception table before setting RO permissions in vmm_init() + extable_init(); - // --- Subsystem init DAG (strict top-down order) --- + // 3. Memblock allocator (Early boot PA allocator) + memblock_init(fdt_pa); + printk(KERN_INFO "init: memblock_init done\n"); + // 4. Virtual memory manager — builds page table with KASLR'd bases + vmm_init(); + printk(KERN_INFO "init: vmm_init done\n"); - // 2. FDT parsing - fdt_init(fdt_paddr); - early_puts("[init] fdt_init done\n"); + // 5. Physical memory manager (Buddy) + pmm_init(); + printk(KERN_INFO "init: pmm_init done\n"); - // 3. Physical memory manager (Buddy) - pmm_init(); - early_puts("[init] pmm_init done\n"); + // 6. Slab allocator — operator new usable after this + slab_init(); + printk(KERN_INFO "init: slab_init done\n"); - // 4. Slab allocator — operator new usable after this - slab_init(); - early_puts("[init] slab_init done\n"); + // 7. FDT Phase 2 — build DeviceNode object tree (needs Slab) + fdt_unflatten(); + printk(KERN_INFO "init: fdt_unflatten done\n"); - // 4.5. FDT Phase 2 — build DeviceNode object tree (needs Slab) - fdt_unflatten(); - early_puts("[init] fdt_unflatten done\n"); + // 6. Trap handler — set trap vector + trap_init(); + printk(KERN_INFO "init: trap_init done\n"); - // 5. Virtual memory manager — retire early_pgdir - vmm_init(); - - // 5.5 Drivers MMIO mapping Registration - // MUST BE CALLED IMMEDIATELY AFTER vmm_init! Otherwise UART is lost. - console_init(); + // 6.5 Task management (PID allocator + global task list) + task_init(); - early_puts("[init] vmm_init & console mapped\n"); + // 7. Hardware Drivers Discovery (Interrupt Controllers, etc) + driver_probe_all(); + printk(KERN_INFO "init: driver_probe_all done\n"); - // 6. Trap handler — set trap vector - // trap_init(); - early_puts("[init] trap_init (stub)\n"); + // 8. Timer interrupt (scheduler tick source) + timer_init(); + printk(KERN_INFO "init: timer_init done\n"); - // 7. PLIC interrupt controller - plic_init(); - early_puts("[init] plic_init done (mapped)\n"); + // 9. Scheduler — create Idle Task 0, init ready queues + sched_init(); + printk(KERN_INFO "init: sched_init done\n"); - // 8. Timer interrupt (scheduler tick source) - // timer_init(); - early_puts("[init] timer_init (stub)\n"); + // 10. Syscall jump table + syscall_init(); - // 9. Scheduler — create Idle Task 0, init ready queues - // sched_init(); - early_puts("[init] sched_init (stub)\n"); + // 10. Boot self-tests — verify subsystem correctness + selftest_run_all(); + // kernel_panic("Manual Panic Test", "triggered by developer"); // VERIFIED + // OK - // 10. Boot self-tests — verify subsystem correctness - selftest_run_all(); + BOOT_STAGE(5, "core kernel init"); + printk(KERN_INFO "boot: BSP init complete, releasing APs\n"); - early_puts("[boot] BSP init complete, releasing APs\n"); + // Release APs with RELEASE semantics: + // guarantees all global data is visible to APs. + ap_boot_sync.store(1, __ATOMIC_RELEASE); - // Release APs with RELEASE semantics: - // guarantees all global data is visible to APs. - ap_boot_sync.store(1, __ATOMIC_RELEASE); + // BSP enables interrupts — first timer tick will preempt + // into the scheduler loop. + // arch::cpu::intr_on(); - // BSP enables interrupts — first timer tick will preempt - // into the scheduler loop. - // arch::cpu::intr_on(); + printk(KERN_INFO "boot: BSP entering idle loop\n"); - early_puts("[boot] BSP entering idle loop\n"); + } else { + // ======================================================== + // AP: spin until BSP finishes global init + // ======================================================== + while (ap_boot_sync.load(__ATOMIC_ACQUIRE) == 0) + ; - } else { - // ======================================================== - // AP: spin until BSP finishes global init - // ======================================================== - while (ap_boot_sync.load(__ATOMIC_ACQUIRE) == 0) - ; - - // --- Per-CPU init only (no global data mutation) --- - // vmm_init_ap(); - // trap_init_ap(); - // plic_init_ap(); - // timer_init_ap(); - // sched_init_ap(); - - // AP enables interrupts — becomes Idle Task on this CPU - // arch::cpu::intr_on(); - } + printk(KERN_INFO "boot: AP online, cpu_id=%llu\n", cpu_id); - // All CPUs: idle loop (wfi until interrupt) - while (true) { - arch::cpu::halt_until_interrupt(); - } + // --- Per-CPU init only (no global data mutation) --- + // vmm_init_ap(); + // arch_irq_chip_init_ap(); + // timer_init_ap(); + // sched_init_ap(); + + // AP enables interrupts — becomes Idle Task on this CPU + // arch::cpu::intr_on(); + } + + // All CPUs: idle loop (wfi until interrupt) + while (true) { + arch::cpu::halt_until_interrupt(); + } } |
