From a9fb6013db52e231fa2446fd8c512f5e5e92e4d3 Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Sat, 26 Sep 2026 23:11:30 -0500 Subject: add boot_args support --- website-emu/src/lib.rs | 75 ++++++++++++++++++++++++++++++++++++++++++- website-kernel/arch/kernel.c | 35 +++++++++++++++++++- website-kernel/arch/linker.ld | 2 +- website-kernel/arch/start.S | 4 +-- website-src/index.html | 4 ++- website-src/style.css | 2 +- 6 files changed, 115 insertions(+), 7 deletions(-) diff --git a/website-emu/src/lib.rs b/website-emu/src/lib.rs index b29c901..9abffa0 100644 --- a/website-emu/src/lib.rs +++ b/website-emu/src/lib.rs @@ -21,6 +21,22 @@ extern "C" { fn uart_push_line(line: &str); } +#[repr(C)] +#[derive(Clone,Copy)] +struct BootArgs { + cmd_line: u32, + devices: u32 +} + +#[repr(C)] +#[derive(Clone,Copy)] +struct Device { + device_type: u8, + start: u32, + size: u32, + next: u32 +} + pub struct Uart { pub addr: u32, pub value: u8, @@ -36,6 +52,7 @@ impl MemoryDevice for Uart { } } + //noinspection ALL fn write(&mut self, address: u32, value: u8) -> Result<(), ()> { if address == self.addr { self.value = value; @@ -105,10 +122,66 @@ pub fn boot(image: &[u8], initrd: &[u8], memory: &[u8]) { ); let mut state = CpuState::new(cpu_memory); + let cmd_line = format!( + "mmu=false initrd=initramfs.cpio,{} image=vmwebkrnl.bin,{} iomem=relaxed", + INITRD_LOAD, + OS_LOAD + ); + + + let args_size = size_of::() as u32; + let device_size = size_of::() as u32; + + let dram_device = Device { + device_type: 0, // DRAM + start: DRAM_LOAD, + size: memory_len as u32, + next: DRAM_LOAD + args_size + device_size + }; + let uart_device = Device { + device_type: 1, // UART + start: CONSOLE_LOAD, + size: 1, + next: 0 + }; + let args = BootArgs { + cmd_line: DRAM_LOAD + args_size + device_size * 2, + devices: DRAM_LOAD + args_size + }; + + let args_bytes: &[u8] = unsafe { + std::slice::from_raw_parts( + &args as *const BootArgs as *const u8, + size_of::(), + ) + }; + let dram_bytes: &[u8] = unsafe { + std::slice::from_raw_parts( + &dram_device as *const Device as *const u8, + size_of::(), + ) + }; + let uart_bytes: &[u8] = unsafe { + std::slice::from_raw_parts( + &uart_device as *const Device as *const u8, + size_of::(), + ) + }; + let cmd_line_bytes = cmd_line.as_bytes(); + for i in 0..args_size { + state.memory.write(DRAM_LOAD + i, args_bytes[i as usize]).unwrap(); + } + for i in 0..device_size { + state.memory.write(DRAM_LOAD + args_size + i, dram_bytes[i as usize]).unwrap(); + state.memory.write(DRAM_LOAD + args_size + device_size + i, uart_bytes[i as usize]).unwrap(); + } + for i in 0..cmd_line.len() as u32 { + state.memory.write(DRAM_LOAD + args_size + device_size * 2 + i, cmd_line_bytes[i as usize]).unwrap(); + } state.pc = 0x80000000; state.registers[10] = 0; - state.registers[2] = DRAM_LOAD + memory_len as u32; + state.registers[11] = DRAM_LOAD; while state.on { { diff --git a/website-kernel/arch/kernel.c b/website-kernel/arch/kernel.c index fe771ec..32d9dbd 100644 --- a/website-kernel/arch/kernel.c +++ b/website-kernel/arch/kernel.c @@ -4,12 +4,45 @@ #define SERIAL_PORT 0x70000000 +#define DRAM_DEVICE 0 +#define UART_DEVICE 1 + void serial_write(char value) { *(char *)SERIAL_PORT = value; } -void kernel_main() { +void kernel_main(int hart, struct boot_args *args) { + if (hart != 0) { + return; + } register_console_callback(serial_write); printk("webkernel version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME); + printk("Command line: %s\n", args->cmd_line); + + printk("BIOS provided device map:\n"); + struct device *root = args->devices; + + while (root != NULL) { + printk("....Device at 0x%x to 0x%x is ", + (uintptr_t)root->start, + (uintptr_t)root->start + root->size + ); + switch(root->device_type) { + case DRAM_DEVICE: + printk("generic DRAM device, usable\n"); + break; + case UART_DEVICE: + printk("Web OS UART character device, not ns16550a compatible, MMIO device\n"); + break; + default: + printk("unknown\n"); + + } + root = root->next; + } +} + +void panic(char *cause) { + printk("PANIC: %s\n", cause); } diff --git a/website-kernel/arch/linker.ld b/website-kernel/arch/linker.ld index 52a3a05..ce8b9c6 100644 --- a/website-kernel/arch/linker.ld +++ b/website-kernel/arch/linker.ld @@ -4,7 +4,7 @@ ENTRY(_start) MEMORY { ROM (rx) : ORIGIN = 0x80000000, LENGTH = 1M - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4M + RAM (rwx) : ORIGIN = 0x80100000, LENGTH = 1M } SECTIONS diff --git a/website-kernel/arch/start.S b/website-kernel/arch/start.S index 8248ab9..3bb704c 100644 --- a/website-kernel/arch/start.S +++ b/website-kernel/arch/start.S @@ -5,8 +5,8 @@ .extern user_regs _start: - csrw sstatus, zero - csrw sie, zero + csrw mstatus, zero + csrw mie, zero la sp, __stack_top diff --git a/website-src/index.html b/website-src/index.html index 7fa24ee..b2eefd0 100644 --- a/website-src/index.html +++ b/website-src/index.html @@ -15,7 +15,9 @@ return; } - const vmwebkrnl = new Uint8Array(await response.arrayBuffer()); + const image = new Uint8Array(await response.arrayBuffer()); + const vmwebkrnl = new Uint8Array(2 * 1024 * 1024); + vmwebkrnl.set(image); const initrd = new Uint8Array(8); const dram = new Uint8Array(1024 * 1024); diff --git a/website-src/style.css b/website-src/style.css index cc43cde..f0d263e 100644 --- a/website-src/style.css +++ b/website-src/style.css @@ -1,6 +1,6 @@ /* Monitor container styling */ body { - margin: 0; + margin: 10%; padding: 0; background: #1a1a1a; min-height: 100vh; -- cgit v1.2.3