--- /dev/null
+#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
--- /dev/null
+#ifndef ARCH_START_H
+#define ARCH_START_H
+
+#include "arch/arch_boot_args.h"
+
+void arch_start(const struct arch_boot_args* args);
+
+#endif
--- /dev/null
+#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
--- /dev/null
+#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");
+ }
+}
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
.section .bss
.align 16
+arch_boot_args:
+ .skip 16
stack_bottom:
.skip 16384
stack_top:
--- /dev/null
+#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");
+ }
+}
_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:
.section .bss
.align 16
+arch_boot_args:
+ .space 16
stack_bottom:
.space 16384
stack_top:
--- /dev/null
+#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");
+ }
+}
*/
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
.section .bss
.align 16
+arch_boot_args:
+ .skip 16
stack_bottom:
.skip 16384 /* 16KB Stack */
stack_top:
--- /dev/null
+#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");
+ }
+}
#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");
// 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
// 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