use crate::riscv; extern "C" { fn cpuid() -> u64; fn consoleinit(); fn printfinit(); fn printf(msg: *const i8); fn kinit(); fn kvminit(); fn kvminithart(); fn procinit(); fn trapinit(); fn trapinithart(); fn plicinit(); fn plicinithart(); fn binit(); fn iinit(); fn fileinit(); fn virtio_disk_init(); fn userinit(); fn scheduler(); } pub static mut started: bool = false; pub unsafe fn kmain() { if cpuid() == 0 { consoleinit(); printfinit(); printf(c"\n".as_ptr()); printf(c"xv6 kernel is booting\n".as_ptr()); printf(c"\n".as_ptr()); kinit(); // physical page allocator kvminit(); // create kernel page table kvminithart(); // turn on paging procinit(); // process table trapinit(); // trap vectors trapinithart(); // install kernel trap vector plicinit(); // set up interrupt controller plicinithart(); // ask PLIC for device interrupts binit(); // buffer cache iinit(); // inode table fileinit(); // file table virtio_disk_init(); // emulated hard disk userinit(); // first user process riscv::barrier(); started = true; } else { while !started {} riscv::barrier(); // printf("hart %d starting\n", cpuid()); kvminithart(); // turn on paging trapinithart(); // install kernel trap vector plicinithart(); // ask PLIC for device interrupts } scheduler(); }