]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
boot: introduce arch_start() and generic boot_info for multi-arch kernel entry
authorTulio A M Mendes <[email protected]>
Fri, 6 Feb 2026 11:42:18 +0000 (08:42 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 6 Feb 2026 11:42:18 +0000 (08:42 -0300)
include/arch/arch_boot_args.h [new file with mode: 0644]
include/arch/arch_start.h [new file with mode: 0644]
include/kernel/boot_info.h [new file with mode: 0644]
src/arch/arm/arch_start.c [new file with mode: 0644]
src/arch/arm/boot.S
src/arch/mips/arch_start.c [new file with mode: 0644]
src/arch/mips/boot.S
src/arch/riscv/arch_start.c [new file with mode: 0644]
src/arch/riscv/boot.S
src/arch/x86/arch_start.c [new file with mode: 0644]
src/kernel/main.c

diff --git a/include/arch/arch_boot_args.h b/include/arch/arch_boot_args.h
new file mode 100644 (file)
index 0000000..a3bcbf5
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef ARCH_BOOT_ARGS_H
+#define ARCH_BOOT_ARGS_H
+
+#include <stdint.h>
+
+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 (file)
index 0000000..10616da
--- /dev/null
@@ -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 (file)
index 0000000..af08602
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef KERNEL_BOOT_INFO_H
+#define KERNEL_BOOT_INFO_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+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 (file)
index 0000000..3ecafa8
--- /dev/null
@@ -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");
+    }
+}
index 8c66e3675e611cd78f99e0d01ab72563a0d66a4b..e09d8fb168242ce1eeecce1dc78a4762f512763e 100644 (file)
@@ -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 (file)
index 0000000..a938356
--- /dev/null
@@ -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");
+    }
+}
index ef79e427ea4b6351e1586e09c2c36d23a69dfb58..50addc74976dd3176e5e733998ca1f1a07016eaf 100644 (file)
 _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 (file)
index 0000000..3ecafa8
--- /dev/null
@@ -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");
+    }
+}
index d29dff867aab178c9b01c7b1698c706dd152d78b..0ce175587d475417403a89d364da53d7cf8315ec 100644 (file)
@@ -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 (file)
index 0000000..5c745fd
--- /dev/null
@@ -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");
+    }
+}
index ebd101a99e4df602a0141bfb0f5d0a4b7b8693f6..4b9fc7ca893d2005a2a6659ab46c0d0393ae4bf4 100644 (file)
@@ -14,6 +14,8 @@
 #include "initrd.h"
 #include "fs.h"
 
+#include "kernel/boot_info.h"
+
 #include "gdt.h"
 
 #include "syscall.h"
  * 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