diff --git a/kernel-rs/src/arch/x86/device/mod.rs b/kernel-rs/src/arch/x86/device/mod.rs deleted file mode 100644 index 70b5b2e6..00000000 --- a/kernel-rs/src/arch/x86/device/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use x86::devices::pit; -use x86::devices::pic; -pub mod cpu; - -pub unsafe fn init() { - pic::init(); - pit::init(); -} diff --git a/kernel-rs/src/arch/x86/device/cpu.rs b/kernel-rs/src/arch/x86/devices/cpu.rs similarity index 100% rename from kernel-rs/src/arch/x86/device/cpu.rs rename to kernel-rs/src/arch/x86/devices/cpu.rs diff --git a/kernel-rs/src/arch/x86/devices/mod.rs b/kernel-rs/src/arch/x86/devices/mod.rs new file mode 100644 index 00000000..212805fd --- /dev/null +++ b/kernel-rs/src/arch/x86/devices/mod.rs @@ -0,0 +1,15 @@ +use x86::devices::pit; +use x86::devices::pic; +pub mod cpu; +use x86::instructions::interrupts; + +static CHAN0_DIVISOR: u16 = 2685; + +pub unsafe fn init() { + pic::init_cascade(); + pic::disable_irqs(); + pic::enable_irq(0); + pic::enable_irq(1); + pit::CHAN0.set_divisor(CHAN0_DIVISOR); + interrupts::enable(); +} diff --git a/kernel-rs/src/arch/x86/idt.rs b/kernel-rs/src/arch/x86/idt.rs index 4a511522..ec5ca5e4 100644 --- a/kernel-rs/src/arch/x86/idt.rs +++ b/kernel-rs/src/arch/x86/idt.rs @@ -47,12 +47,6 @@ lazy_static! { }; } -// pub fn init(memory_controller: &mut ::memory::MemoryController) { pub fn init() { - // let double_fault_stack = memory_controller.alloc_stack(1) - // .expect("could not allocate double fault stack"); - // println!("DF stack: {:#?}", double_fault_stack); - // flush!(); - IDT.load(); } diff --git a/kernel-rs/src/arch/x86/interrupt/irq.rs b/kernel-rs/src/arch/x86/interrupt/irq.rs index 2e5f553a..81817b7b 100644 --- a/kernel-rs/src/arch/x86/interrupt/irq.rs +++ b/kernel-rs/src/arch/x86/interrupt/irq.rs @@ -1,5 +1,6 @@ use x86::structures::idt::*; use x86::devices::pic; +use time; #[macro_export] macro_rules! interrupt { @@ -45,7 +46,21 @@ pub unsafe fn acknowledge(irq: usize) { } interrupt!(0, pit, { - fprintln!("got pit (irq0)"); + /// t = 1/f + /// pit freq = 1.193182 MHz + /// chan0 divisor = 2685 + /// PIT_RATE in us + const PIT_RATE: u32 = 2_251; + { + let mut offset = time::OFFSET.lock(); + let sum = offset.1 + PIT_RATE; + offset.1 = sum % 1_000_000; + offset.0 += sum / 1_000_000; + if sum > 1_000_000 { + fprintln!("uptime: {}s", offset.0); + } + } + unsafe { pic::MASTER.ack() }; }); interrupt!(1, keyboard, { diff --git a/kernel-rs/src/arch/x86/mod.rs b/kernel-rs/src/arch/x86/mod.rs index 496103c5..59b7f073 100644 --- a/kernel-rs/src/arch/x86/mod.rs +++ b/kernel-rs/src/arch/x86/mod.rs @@ -3,7 +3,7 @@ extern crate x86; #[macro_use] pub mod paging; pub mod interrupt; -pub mod device; +pub mod devices; pub mod consts; pub mod gdt; @@ -52,7 +52,7 @@ pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) { // } // set up pic, pit - device::init(); + devices::init(); // primary CPU entry point ::kmain(); diff --git a/kernel-rs/src/arch/x86/pti.rs b/kernel-rs/src/arch/x86/pti.rs deleted file mode 100644 index 91f488c1..00000000 --- a/kernel-rs/src/arch/x86/pti.rs +++ /dev/null @@ -1,73 +0,0 @@ -use core::ptr; - -use super::paging::ActivePageTable; -// use super::paging::entry::EntryFlags; - -#[thread_local] -pub static mut PTI_CPU_STACK: [u8; 256] = [0; 256]; - -#[thread_local] -pub static mut PTI_CONTEXT_STACK: usize = 0; - -#[inline(always)] -unsafe fn switch_stack(old: usize, new: usize) { - let old_esp: usize; - - // save the old esp - asm!("" : "={esp}"(old_esp) : : : "intel", "volatile"); - - let offset_esp = old - old_esp; - - let new_esp = new - offset_esp; - - ptr::copy_nonoverlapping(old_esp as *const u8, new_esp as *mut u8, offset_esp); - - // switch the esp with the new one - asm!("" : : "{esp}"(new_esp) : : "intel", "volatile"); -} - -#[inline(always)] -pub unsafe fn map() { - // { - // let mut active_table = unsafe { ActivePageTable::new() }; - // - // // Map kernel heap - // let address = active_table.p4()[::KERNEL_HEAP_PML4].address(); - // let frame = Frame::containing_address(address); - // let mut flags = active_table.p4()[::KERNEL_HEAP_PML4].flags(); - // flags.remove(EntryFlags::PRESENT); - // active_table.p4_mut()[::KERNEL_HEAP_PML4].set(frame, flags); - // - // // Reload page tables - // active_table.flush_all(); - // } - - // Switch to per-context stack - switch_stack( - PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(), - PTI_CONTEXT_STACK, - ); -} - -#[inline(always)] -pub unsafe fn unmap() { - // Switch to per-CPU stack - switch_stack( - PTI_CONTEXT_STACK, - PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(), - ); - - // { - // let mut active_table = unsafe { ActivePageTable::new() }; - // - // // Unmap kernel heap - // let address = active_table.p4()[::KERNEL_HEAP_PML4].address(); - // let frame = Frame::containing_address(address); - // let mut flags = active_table.p4()[::KERNEL_HEAP_PML4].flags(); - // flags.insert(EntryFlags::PRESENT); - // active_table.p4_mut()[::KERNEL_HEAP_PML4].set(frame, flags); - // - // // Reload page tables - // active_table.flush_all(); - // } -} diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index 377257e0..e7e0d974 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -26,6 +26,7 @@ fn dispatch(command: &str) -> Result<(), &'static str> { "cpu" => self::cpu(), "int3" => self::int3(), "overflow" => self::overflow(), + "page_fault" => self::page_fault(), _ => Err("Command unknown. (h|help for help)"), } @@ -46,12 +47,14 @@ fn help() -> Result<(), &'static str> { println!("help | h => Print this help"); // println!("memory => Print memory areas"); // println!("multiboot => Print multiboot information"); - println!("reboot => Reboot"); // println!("sections => Print elf sections"); + println!("reboot => Reboot"); println!("shutdown | halt | q => Kill a kitten, then shutdown"); println!("stack => Print kernel stack in a fancy way"); println!("regs => Print controle register"); println!("cpu => Print cpu information"); + println!("overflow => triggers a stack overflow"); + println!("page_fault => triggers a page fault on 0xdead"); flush!(); Ok(()) } @@ -213,7 +216,7 @@ pub fn regs() -> Result<(), &'static str> { /// Dump cpu info, should add power management info pub fn cpu() -> Result<(), &'static str> { - use arch::x86::device::cpu; + use arch::x86::devices::cpu; cpu::cpu_info().expect("cpu info not available"); flush!(); Ok(()) @@ -233,3 +236,10 @@ pub fn overflow() -> Result<(), &'static str> { stack_overflow(); Ok(()) } + +pub fn page_fault() -> Result<(), &'static str> { + unsafe { + *(0xdead as *mut u32) = 42; + }; + Ok(()) +} diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 39d31462..19039bac 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -45,36 +45,18 @@ pub mod arch; pub use arch::x86::consts::*; /// process scheduling pub mod process; +/// uptime counting +pub mod time; /// kernel entry point. arch module is responsible for /// calling this once the core has loaded pub fn kmain() -> ! { - // heap avalaible for tracking freed frames + // memory init after heap is available memory::init_noncore(); - // vga is *not* cpu specific + // vga is *not* cpu specific I think vga::init(); - // unsafe { - // *(0xdead as *mut u32) = 42; - // }; - - // x86::instructions::interrupts::int3(); - - // println!("flags: {:?}", x86::registers::flags::flags()); - // flush!(); - - // let sp = (::USER_STACK_OFFSET + ::USER_STACK_SIZE).as_u32(); - // let sp: u32; - // unsafe { - // asm!("mov %ebp, $0" : "=r" (sp)); - // } - - // unsafe { - // arch::x86::usermode(ip, sp, 0); - // } - // unreachable!() - process::schedule(); unreachable!(); } diff --git a/kernel-rs/src/process/mod.rs b/kernel-rs/src/process/mod.rs index e381568d..af270b35 100644 --- a/kernel-rs/src/process/mod.rs +++ b/kernel-rs/src/process/mod.rs @@ -66,10 +66,8 @@ pub fn fork() -> i32 { } pub fn init() { - println!("init first line"); - flush!(); + fprintln!("init first line"); // let i = self::fork(); // println!("fork={}", i); - println!("init last line"); - flush!(); + fprintln!("init last line"); } diff --git a/kernel-rs/src/time.rs b/kernel-rs/src/time.rs new file mode 100644 index 00000000..70d1819c --- /dev/null +++ b/kernel-rs/src/time.rs @@ -0,0 +1,17 @@ +use spin::Mutex; + +/// Kernel start time, measured in (seconds, microseconds) since Unix epoch +pub static START: Mutex<(u32, u32)> = Mutex::new((0, 0)); +/// Kernel up time, measured in (seconds, microseconds) since `START_TIME` +pub static OFFSET: Mutex<(u32, u32)> = Mutex::new((0, 0)); + +pub fn monotonic() -> (u32, u32) { + *OFFSET.lock() +} + +pub fn realtime() -> (u32, u32) { + let offset = monotonic(); + let start = *START.lock(); + let sum = start.1 + offset.1; + (start.0 + offset.0 + sum / 1_000_000, sum % 1_000_000) +} diff --git a/kernel-rs/x86 b/kernel-rs/x86 index 0da7a6b2..229c4acb 160000 --- a/kernel-rs/x86 +++ b/kernel-rs/x86 @@ -1 +1 @@ -Subproject commit 0da7a6b2bfafec479a990bb0dac8f4bd58b9fd79 +Subproject commit 229c4acbbe81bf4837bd05714b99614ada9dd2b3