From 12f26ec65b00c4dd8cf51b6f2e3eef7a8da2236d Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Fri, 6 Feb 2026 08:42:18 -0300 Subject: [PATCH] boot: introduce arch_start() and generic boot_info for multi-arch kernel entry --- include/arch/arch_boot_args.h | 13 ++++++ include/arch/arch_start.h | 8 ++++ include/kernel/boot_info.h | 17 ++++++++ src/arch/arm/arch_start.c | 26 +++++++++++ src/arch/arm/boot.S | 7 ++- src/arch/mips/arch_start.c | 26 +++++++++++ src/arch/mips/boot.S | 17 +++++--- src/arch/riscv/arch_start.c | 26 +++++++++++ src/arch/riscv/boot.S | 7 ++- src/arch/x86/arch_start.c | 81 +++++++++++++++++++++++++++++++++++ src/kernel/main.c | 53 ++++------------------- 11 files changed, 225 insertions(+), 56 deletions(-) create mode 100644 include/arch/arch_boot_args.h create mode 100644 include/arch/arch_start.h create mode 100644 include/kernel/boot_info.h create mode 100644 src/arch/arm/arch_start.c create mode 100644 src/arch/mips/arch_start.c create mode 100644 src/arch/riscv/arch_start.c create mode 100644 src/arch/x86/arch_start.c diff --git a/include/arch/arch_boot_args.h b/include/arch/arch_boot_args.h new file mode 100644 index 0000000..a3bcbf5 --- /dev/null +++ b/include/arch/arch_boot_args.h @@ -0,0 +1,13 @@ +#ifndef ARCH_BOOT_ARGS_H +#define ARCH_BOOT_ARGS_H + +#include + +struct arch_boot_args { + uintptr_t a0; + uintptr_t a1; + uintptr_t a2; + uintptr_t a3; +}; + +#endif diff --git a/include/arch/arch_start.h b/include/arch/arch_start.h new file mode 100644 index 0000000..10616da --- /dev/null +++ b/include/arch/arch_start.h @@ -0,0 +1,8 @@ +#ifndef ARCH_START_H +#define ARCH_START_H + +#include "arch/arch_boot_args.h" + +void arch_start(const struct arch_boot_args* args); + +#endif diff --git a/include/kernel/boot_info.h b/include/kernel/boot_info.h new file mode 100644 index 0000000..af08602 --- /dev/null +++ b/include/kernel/boot_info.h @@ -0,0 +1,17 @@ +#ifndef KERNEL_BOOT_INFO_H +#define KERNEL_BOOT_INFO_H + +#include +#include + +struct boot_info { + uintptr_t arch_magic; + uintptr_t arch_boot_info; + + uintptr_t initrd_start; + uintptr_t initrd_end; + + const char* cmdline; +}; + +#endif diff --git a/src/arch/arm/arch_start.c b/src/arch/arm/arch_start.c new file mode 100644 index 0000000..3ecafa8 --- /dev/null +++ b/src/arch/arm/arch_start.c @@ -0,0 +1,26 @@ +#include "arch/arch_start.h" +#include "kernel/boot_info.h" + +#include "uart_console.h" + +extern void kernel_main(const struct boot_info* bi); + +void arch_start(const struct arch_boot_args* args) { + (void)args; + + uart_init(); + uart_print("\n[AdrOS] Booting...\n"); + + struct boot_info bi; + bi.arch_magic = 0; + bi.arch_boot_info = 0; + bi.initrd_start = 0; + bi.initrd_end = 0; + bi.cmdline = NULL; + + kernel_main(&bi); + + for(;;) { + __asm__ volatile("wfi"); + } +} diff --git a/src/arch/arm/boot.S b/src/arch/arm/boot.S index 8c66e36..e09d8fb 100644 --- a/src/arch/arm/boot.S +++ b/src/arch/arm/boot.S @@ -17,8 +17,9 @@ _start: ldr x0, =stack_top mov sp, x0 - /* Jump to C kernel */ - bl kernel_main + /* Build arch_boot_args (in .bss) and call arch_start(args) */ + ldr x0, =arch_boot_args + bl arch_start /* Hang */ 1: wfi @@ -26,6 +27,8 @@ _start: .section .bss .align 16 +arch_boot_args: + .skip 16 stack_bottom: .skip 16384 stack_top: diff --git a/src/arch/mips/arch_start.c b/src/arch/mips/arch_start.c new file mode 100644 index 0000000..a938356 --- /dev/null +++ b/src/arch/mips/arch_start.c @@ -0,0 +1,26 @@ +#include "arch/arch_start.h" +#include "kernel/boot_info.h" + +#include "uart_console.h" + +extern void kernel_main(const struct boot_info* bi); + +void arch_start(const struct arch_boot_args* args) { + (void)args; + + uart_init(); + uart_print("\n[AdrOS] Booting...\n"); + + struct boot_info bi; + bi.arch_magic = 0; + bi.arch_boot_info = 0; + bi.initrd_start = 0; + bi.initrd_end = 0; + bi.cmdline = NULL; + + kernel_main(&bi); + + for(;;) { + __asm__ volatile("nop"); + } +} diff --git a/src/arch/mips/boot.S b/src/arch/mips/boot.S index ef79e42..50addc7 100644 --- a/src/arch/mips/boot.S +++ b/src/arch/mips/boot.S @@ -13,13 +13,14 @@ _start: la $sp, stack_top - /* kernel_main(unsigned long magic, unsigned long addr) - * For now, pass 0, 0 (no multiboot on MIPS) - */ - move $a0, $zero - move $a1, $zero - - jal kernel_main + /* Build arch_boot_args (in .bss) and call arch_start(args) */ + la $a0, arch_boot_args + sw $zero, 0($a0) + sw $zero, 4($a0) + sw $zero, 8($a0) + sw $zero, 12($a0) + + jal arch_start nop 1: @@ -30,6 +31,8 @@ _start: .section .bss .align 16 +arch_boot_args: + .space 16 stack_bottom: .space 16384 stack_top: diff --git a/src/arch/riscv/arch_start.c b/src/arch/riscv/arch_start.c new file mode 100644 index 0000000..3ecafa8 --- /dev/null +++ b/src/arch/riscv/arch_start.c @@ -0,0 +1,26 @@ +#include "arch/arch_start.h" +#include "kernel/boot_info.h" + +#include "uart_console.h" + +extern void kernel_main(const struct boot_info* bi); + +void arch_start(const struct arch_boot_args* args) { + (void)args; + + uart_init(); + uart_print("\n[AdrOS] Booting...\n"); + + struct boot_info bi; + bi.arch_magic = 0; + bi.arch_boot_info = 0; + bi.initrd_start = 0; + bi.initrd_end = 0; + bi.cmdline = NULL; + + kernel_main(&bi); + + for(;;) { + __asm__ volatile("wfi"); + } +} diff --git a/src/arch/riscv/boot.S b/src/arch/riscv/boot.S index d29dff8..0ce1755 100644 --- a/src/arch/riscv/boot.S +++ b/src/arch/riscv/boot.S @@ -15,8 +15,9 @@ _start: */ la sp, stack_top - /* Call C kernel */ - call kernel_main + /* Build arch_boot_args (in .bss) and call arch_start(args) */ + la a0, arch_boot_args + call arch_start /* Hang if return */ 1: wfi @@ -24,6 +25,8 @@ _start: .section .bss .align 16 +arch_boot_args: + .skip 16 stack_bottom: .skip 16384 /* 16KB Stack */ stack_top: diff --git a/src/arch/x86/arch_start.c b/src/arch/x86/arch_start.c new file mode 100644 index 0000000..5c745fd --- /dev/null +++ b/src/arch/x86/arch_start.c @@ -0,0 +1,81 @@ +#include "arch/arch_start.h" + +#include "kernel/boot_info.h" + +#include "gdt.h" +#include "idt.h" +#include "uart_console.h" + +#include "multiboot2.h" + +extern void kernel_main(const struct boot_info* bi); + +static uint8_t multiboot_copy[65536]; +static uint32_t multiboot_copy_size; + +void arch_start(const struct arch_boot_args* args) { + uart_init(); + uart_print("\n[AdrOS] Booting...\n"); + + uint32_t magic = (uint32_t)(args ? args->a0 : 0); + uintptr_t mbi_phys = (uintptr_t)(args ? args->a1 : 0); + + if (magic != 0x36d76289) { + uart_print("[ERR] Invalid Multiboot2 Magic!\n"); + } else { + uart_print("[OK] Multiboot2 Magic Confirmed.\n"); + } + + uart_print("[AdrOS] Initializing GDT/TSS...\n"); + gdt_init(); + + uart_print("[AdrOS] Initializing IDT...\n"); + idt_init(); + + struct boot_info bi; + bi.arch_magic = magic; + bi.arch_boot_info = 0; + bi.initrd_start = 0; + bi.initrd_end = 0; + bi.cmdline = NULL; + + if (mbi_phys) { + uint32_t total_size = *(volatile uint32_t*)mbi_phys; + if (total_size >= 8) { + multiboot_copy_size = total_size; + if (multiboot_copy_size > sizeof(multiboot_copy)) { + uart_print("[WARN] Multiboot2 info too large, truncating copy.\n"); + multiboot_copy_size = sizeof(multiboot_copy); + } + + for (uint32_t i = 0; i < multiboot_copy_size; i++) { + multiboot_copy[i] = *(volatile uint8_t*)(mbi_phys + i); + } + bi.arch_boot_info = (uintptr_t)multiboot_copy; + } + } + + if (bi.arch_boot_info) { + struct multiboot_tag* tag; + for (tag = (struct multiboot_tag*)((uint8_t*)bi.arch_boot_info + 8); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag*)((uint8_t*)tag + ((tag->size + 7) & ~7))) { + if (tag->type == MULTIBOOT_TAG_TYPE_MODULE) { + struct multiboot_tag_module* mod = (struct multiboot_tag_module*)tag; + bi.initrd_start = mod->mod_start; + bi.initrd_end = mod->mod_end; + break; + } + if (tag->type == MULTIBOOT_TAG_TYPE_CMDLINE) { + struct multiboot_tag_string* s = (struct multiboot_tag_string*)tag; + bi.cmdline = s->string; + } + } + } + + kernel_main(&bi); + + for(;;) { + __asm__ volatile("hlt"); + } +} diff --git a/src/kernel/main.c b/src/kernel/main.c index ebd101a..4b9fc7c 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -14,6 +14,8 @@ #include "initrd.h" #include "fs.h" +#include "kernel/boot_info.h" + #include "gdt.h" #include "syscall.h" @@ -29,25 +31,12 @@ * Kernel Entry Point * Arguments are passed from boot.S (architecture specific) */ -void kernel_main(unsigned long magic, unsigned long addr) { +void kernel_main(const struct boot_info* bi) { - // 1. Initialize Console (UART works everywhere) - uart_init(); - uart_print("\n[AdrOS] Booting...\n"); - -#if defined(__i386__) || defined(__x86_64__) - // Check Multiboot2 Magic - if (magic != 0x36d76289) { - uart_print("[ERR] Invalid Multiboot2 Magic!\n"); - } else { - uart_print("[OK] Multiboot2 Magic Confirmed.\n"); - } -#endif - uart_print("[AdrOS] Initializing PMM...\n"); // 2. Initialize Physical Memory Manager - pmm_init((void*)addr); + pmm_init((void*)(bi ? bi->arch_boot_info : 0)); // 3. Initialize Virtual Memory Manager uart_print("[AdrOS] Initializing VMM...\n"); @@ -62,13 +51,6 @@ void kernel_main(unsigned long magic, unsigned long addr) { // 4. Initialize Kernel Heap kheap_init(); - uart_print("[AdrOS] Initializing GDT/TSS...\n"); - gdt_init(); - - // 5. Initialize Interrupts (x86) - uart_print("[AdrOS] Initializing IDT...\n"); - idt_init(); - syscall_init(); // 6. Initialize Drivers @@ -81,30 +63,11 @@ void kernel_main(unsigned long magic, unsigned long addr) { // 8. Start Timer (Preemption!) - 50Hz timer_init(50); + hal_cpu_enable_interrupts(); + // 9. Load InitRD (if available) - struct multiboot_tag *tag; - // addr is physical. In Higher Half, we might need to convert it? - // boot.S mapped 0-4MB identity, so if multiboot struct is there, we are good. - // Let's assume addr is accessible. - - for (tag = (struct multiboot_tag *)((uint8_t *)addr + 8); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_tag *)((uint8_t *)tag + ((tag->size + 7) & ~7))) - { - if (tag->type == MULTIBOOT_TAG_TYPE_MODULE) { - struct multiboot_tag_module *mod = (struct multiboot_tag_module *)tag; - - uart_print("[INITRD] Module found at: "); - // TODO: Print Hex - uart_print("\n"); - - // mod->mod_start is Physical Address. - // We need to access it. Assuming Identity Map covers it or we use P2V logic. - // Let's rely on P2V macro logic if it was available here, or just cast. - // For now, let's assume it's low memory and identity mapped. - - fs_root = initrd_init(mod->mod_start); - } + if (bi && bi->initrd_start) { + fs_root = initrd_init((uint32_t)bi->initrd_start); } // Start Shell as the main interaction loop -- 2.43.0