//! AbleOS Kernel Entrypoint use { crate::{alloc::string::ToString, arch::logging::SERIAL_CONSOLE, device_tree::DeviceTree}, clparse::Arguments, log::{debug, trace}, spin::{Lazy, Mutex}, xml::XMLElement, }; pub fn kmain(cmdline: &str, bootstrap: Option<&'static [u8]>) -> ! { debug!("Entered kmain"); let mut cmdline = cmdline.to_string(); cmdline.pop(); cmdline.remove(0); let kcmd = Arguments::parse(cmdline.to_string()).unwrap(); trace!("Cmdline: {kcmd:?}"); let mut kcl = XMLElement::new("Kernel Command Line"); for (key, value) in kcmd.arguments { kcl.set_attribute(key, value); } debug!("kernel command line object: {:?}", kcl); let bootstrap = bootstrap/*.expect("no bootstrap found")*/; match bootstrap { Some(bootstrap_mod) => { debug!("Bootstrap Module: {:?}", bootstrap_mod); } None => { debug!("No bootstrap module loaded.") } } let dt = DEVICE_TREE.lock(); log::info!("Device Tree{}", dt); log::info!("Boot complete. Moving to init_system"); // TODO: schedule the disk driver from the initramfs // TODO: schedule the filesystem driver from the initramfs // TODO: schedule the init system from the initramfs let code = "li r1, 8 li r2, 10 add r1, r1, r2 ecall" .to_string(); let mut prog = alloc::vec![]; // TODO: Port hbasm to be fully nostd if let Err(e) = hbasm::assembly(&code, &mut prog) { log::error!( "Error {:?} at {:?} (`{}`)", e.kind, e.span.clone(), &code[e.span], ); } use hbvm::validate::validate; #[allow(clippy::redundant_else)] if let Err(e) = validate(&prog) { log::error!("Program validation error: {e:?}"); } else { log::info!("valid program"); unsafe { use {crate::host::TrapHandler, hbvm::vm::Vm}; let mut vm = Vm::new_unchecked(&prog, TrapHandler); vm.memory.insert_test_page(); log::info!("Program interrupt: {:?}", vm.run()); log::info!("{:?}", vm.registers); } } // TODO: change this to a driver { let _buf = [8; 128 * 4]; let mut sc = SERIAL_CONSOLE.lock(); loop { // TODO: Implement an API for sending and recieving serial stuff { fn read_ipc_buff() {} fn write_ipc_buff() {} // TODO: read from the IPC buffer and push to serial stream let _msg = read_ipc_buff(); for byte in 0..0 { sc.send(byte); } } match sc.receive() { b'\r' => { sc.send(b'\n'); } byte => { sc.send(byte); } } } } } pub static DEVICE_TREE: Lazy> = Lazy::new(|| { let dt = DeviceTree::new(); Mutex::new(dt) }); #[test_case] fn trivial_assertion() { trace!("trivial assertion... "); assert_eq!(1, 1); info!("[ok]"); }