]> 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..edb408a
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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..faa317f
--- /dev/null
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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..81da136
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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..aa62edd
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 976a49c96939b5eaab98b2cd7c30e6f5b0c41d8e..8051689408cd408cd78b5ccbc3ade58db899b05b 100644 (file)
@@ -26,8 +26,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
@@ -35,6 +36,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..12e940d
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 cf56a3a2861c6c46e1c7fceffd22efd74e2e2b12..f4086b8f3d48b53bccaf3826fea8a3b62995bff1 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:
@@ -39,6 +40,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..aa62edd
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 6f3b95fffbe15f01ba3c29cc7301ae30d4ae2009..2097b98575c5b1f50d4f37a626a1dd20584ee461 100644 (file)
@@ -24,8 +24,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
@@ -33,6 +34,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..eade7ce
--- /dev/null
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 ee61184e9ace41e2a51407792a3628914a26882c..c1f9068a2d9a8c23eb69bb6c2f6ab7e4ab45facb 100644 (file)
@@ -23,6 +23,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");
@@ -71,13 +60,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
@@ -90,30 +72,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