diff --git a/kernel-rs/src/arch/x86/gdt.rs b/kernel-rs/src/arch/x86/gdt.rs index a5cb7ab7..cad1b356 100644 --- a/kernel-rs/src/arch/x86/gdt.rs +++ b/kernel-rs/src/arch/x86/gdt.rs @@ -2,55 +2,79 @@ use x86::structures::gdt; use x86::structures::tss; use x86::instructions::segmentation::set_cs; use x86::instructions::tables::load_tss; +use x86::registers::control; use arch::x86::paging::ActivePageTable; use spin::Once; // use io; static GDT: Once = Once::new(); -static TSS: Once = Once::new(); +static TSS_MAIN: Once = Once::new(); +static TSS_INT: Once = Once::new(); pub fn init(mut active_table: &mut ActivePageTable) { - // let tss = tss::TaskStateSegment::new(); - let tss = TSS.call_once(|| { + let tss_main = TSS_MAIN.call_once(|| { let mut tss = tss::TaskStateSegment::new(); -match ::memory::allocate_stack(&mut active_table) { - Some(stack) => {tss.esp0 = stack.top; tss.ss = 0x18}, - // Some(stack) => {tss.esp = stack.top; tss.ebp = stack.bottom }, - _ => panic!("There is no stack available for tss"), + // tss.esp0 = stack.top; + tss.ss0 = 0x8; + tss.cr3 = control::Cr3::read_u32(); + tss.reserved_iopb = 1; //T debug bit + tss + }); + + let tss_int = TSS_INT.call_once(|| { + let mut tss = tss::TaskStateSegment::new(); + match ::memory::allocate_stack(&mut active_table) { + Some(stack) => { + println!("int tss stack at {:#x}", stack.top); + tss.esp0 = stack.top; + tss.ss0 = 0x8; + tss.cr3 = control::Cr3::read_u32(); + // tss.esp = stack.top; + // tss.es = 0x8; + // tss.cs = 0x8; + // tss.ss = 0x8; + // tss.ds = 0x8; + // tss.fs = 0x8; + // tss.gs = 0x8; + // tss.link = 0x10; //main tss + tss.reserved_iopb = 1; //T debug bit + } + _ => panic!("There is no stack available for tss"), }; - // tss.esp = tss.esp0; - // tss.ebp = tss.esp; - // println!("tss on {:#x}", tss.esp0);flush!(); tss }); let mut code_selector = gdt::SegmentSelector(0); - let mut tss_selector = gdt::SegmentSelector(0); + let mut tss_main_selector = gdt::SegmentSelector(0); + let mut tss_int_selector = gdt::SegmentSelector(0); let gdt = GDT.call_once(|| { let mut gdt = gdt::Gdt::new(); code_selector = gdt.add_entry(gdt::Descriptor::kernel_code_segment()); - tss_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss)); + tss_main_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss_main)); + tss_int_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss_int)); gdt }); - println!("gdt 0 upper: {:#x}", gdt.table[0] as u32); - println!("gdt 0 lower: {:#x}", gdt.table[0] >> 32 as u32); - println!("gdt 1 upper: {:#x}", gdt.table[1] as u32); - println!("gdt 1 lower: {:#x}", gdt.table[1] >> 32 as u32); - println!("gdt 2 upper: {:#x}", gdt.table[2] as u32); - println!("gdt 2 lower: {:#x}", gdt.table[2] >> 32 as u32); - println!("gdt 3 upper: {:#x}", gdt.table[3] as u32); - println!("gdt 3 lower: {:#x}", gdt.table[3] >> 32 as u32); + // println!("gdt 0 upper: {:#x}", gdt.table[0] as u32); + // println!("gdt 0 lower: {:#x}", gdt.table[0] >> 32 as u32); + // println!("gdt 1 upper: {:#x}", gdt.table[1] as u32); + // println!("gdt 1 lower: {:#x}", gdt.table[1] >> 32 as u32); + // println!("gdt 2 upper: {:#x}", gdt.table[2] as u32); + // println!("gdt 2 lower: {:#x}", gdt.table[2] >> 32 as u32); + // println!("gdt 3 upper: {:#x}", gdt.table[3] as u32); + // println!("gdt 3 lower: {:#x}", gdt.table[3] >> 32 as u32); + // println!("gdt 4 upper: {:#x}", gdt.table[4] as u32); + // println!("gdt 4 lower: {:#x}", gdt.table[4] >> 32 as u32); flush!(); - // io::halt(); gdt.load(); unsafe { // reload code segment register + println!("set_cs({:#x})", code_selector.0); set_cs(code_selector); // load TSS - println!("loading tss {:?}", tss_selector); - load_tss(tss_selector); + println!("loading tss {:?}", tss_main_selector); + load_tss(tss_main_selector); } } diff --git a/kernel-rs/src/arch/x86/idt.rs b/kernel-rs/src/arch/x86/idt.rs index 7407f2c0..48ce7dd8 100644 --- a/kernel-rs/src/arch/x86/idt.rs +++ b/kernel-rs/src/arch/x86/idt.rs @@ -10,17 +10,24 @@ lazy_static! { idt.debug.set_handler_fn(exception::debug); idt.non_maskable_interrupt.set_handler_fn(exception::non_maskable); idt.breakpoint.set_handler_fn(exception::breakpoint); + idt.breakpoint.set_gate_type(GateType::TaskGate32); + idt.breakpoint.set_selector(0x18); + idt.overflow.set_handler_fn(exception::overflow); idt.bound_range_exceeded.set_handler_fn(exception::bound_range); idt.invalid_opcode.set_handler_fn(exception::invalid_opcode); idt.device_not_available.set_handler_fn(exception::device_not_available); idt.double_fault.set_handler_fn(exception::double_fault); - idt.double_fault.set_gate_type(GateType::TaskGate32); + // idt.double_fault.set_gate_type(GateType::TaskGate32); + // idt.double_fault.set_selector(0x18); + idt.segment_not_present.set_handler_fn(exception::segment_not_present); idt.stack_segment_fault.set_handler_fn(exception::stack_segment); idt.general_protection_fault.set_handler_fn(exception::general_protection); idt.page_fault.set_handler_fn(exception::page_fault); idt.page_fault.set_gate_type(GateType::TaskGate32); + idt.page_fault.set_selector(0x18); + idt.x87_floating_point.set_handler_fn(exception::x87_fpu); idt.alignment_check.set_handler_fn(exception::alignment_check); idt.machine_check.set_handler_fn(exception::machine_check); diff --git a/kernel-rs/src/arch/x86/interrupt/exception.rs b/kernel-rs/src/arch/x86/interrupt/exception.rs index 1eead757..a61d1642 100644 --- a/kernel-rs/src/arch/x86/interrupt/exception.rs +++ b/kernel-rs/src/arch/x86/interrupt/exception.rs @@ -1,14 +1,9 @@ // https://wiki.osdev.org/Exceptions -use arch::x86::pti; -use io; - macro_rules! exception { ($name:ident, $func:block) => { pub extern "x86-interrupt" fn $name(stack_frame: &mut ExceptionStackFrame) { - // unsafe { pti::map(); } - println!("Exception: {}", stringify!($name)); println!("{:#?}", stack_frame); flush!(); @@ -18,8 +13,6 @@ macro_rules! exception { $func } inner(stack_frame); - - // unsafe { pti::unmap(); } } } } @@ -50,7 +43,11 @@ exception!(divide_by_zero, { exception!(debug, {}); exception!(non_maskable, {}); -exception!(breakpoint, {}); +exception!(breakpoint, { + // unsafe { + // asm!("hlt"); + // } +}); exception!(overflow, {}); exception!(bound_range, {}); exception!(invalid_opcode, {}); @@ -60,7 +57,9 @@ exception!(coprocessor_segment_overrun, {}); exception_err!(invalid_tss, {}); exception_err!(segment_not_present, {}); exception_err!(stack_segment, {}); -exception_err!(general_protection, {}); +exception_err!(general_protection, { + panic!("general protection fault (#GP) can not recover"); +}); pub extern "x86-interrupt" fn page_fault( stack_frame: &mut ExceptionStackFrame, @@ -70,6 +69,9 @@ pub extern "x86-interrupt" fn page_fault( println!("Error code: {:?}", code); println!("{:#?}", stack_frame); flush!(); + unsafe { + asm!("hlt"); + } } exception!(x87_fpu, {}); diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index 9ec181d7..ae067a53 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -25,6 +25,8 @@ fn dispatch(command: &str) -> Result<(), &'static str> { "stack" => self::print_stack(), "regs" => self::regs(), "cpu" => self::cpu(), + "int3" => self::int3(), + "overflow" => self::overflow(), _ => Err("Command unknown. (h|help for help)"), } @@ -198,3 +200,17 @@ pub fn cpu() -> Result<(), &'static str> { flush!(); Ok(()) } + +pub fn int3() -> Result<(), &'static str> { + use x86; + x86::instructions::interrupts::int3(); + Ok(()) +} + +pub fn overflow() -> Result<(), &'static str> { + fn stack_overflow() { + stack_overflow(); + } + stack_overflow(); + Ok(()) +} diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 143320a0..b513ed0a 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -52,14 +52,8 @@ pub fn kmain() -> ! { // heap avalaible for tracking freed frames memory::init_noncore(); - // x86::instructions::interrupts::int3(); - // println!("size of idt entry: {}", mem::size_of::>()); - // println!("size of i32 {}", mem::size_of::()); - // flush!(); - // unsafe {asm!("hlt");} - // let x = 0; - // let y = 5 /x; - // println!("x {} y {}", x, y); + // vga is *not* cpu specific + vga::init(); // fn stack_overflow() { // stack_overflow(); @@ -70,8 +64,7 @@ pub fn kmain() -> ! { *(0xdead as *mut u32) = 42; }; - // vga is *not* cpu specific - vga::init(); + // x86::instructions::interrupts::int3(); loop {} } diff --git a/kernel-rs/src/memory/mod.rs b/kernel-rs/src/memory/mod.rs index d27633d8..017f86e6 100644 --- a/kernel-rs/src/memory/mod.rs +++ b/kernel-rs/src/memory/mod.rs @@ -10,8 +10,7 @@ use x86::*; use self::bump::BumpFrameAllocator; use self::recycle::RecycleAllocator; -use self::stack_allocator::{Stack,StackAllocator}; - +use self::stack_allocator::{Stack, StackAllocator}; pub trait FrameAllocator { fn allocate_frames(&mut self, size: usize) -> Option; @@ -49,7 +48,7 @@ pub fn init(boot_info: &multiboot2::BootInformation) { boot_info.start_address(), boot_info.end_address(), memory_map_tag.memory_areas(), - ); + ); let frame_allocator = RecycleAllocator::new(bump_allocator); @@ -94,7 +93,9 @@ pub fn deallocate_frames(frame: PhysFrame, count: usize) { pub fn allocate_stack(mut active_table: &mut ActivePageTable) -> Option { unsafe { if let Some(ref mut controler) = MEMORY_CONTROLER { - controler.stack_allocator.allocate_stack(&mut active_table, &mut controler.frame_allocator, 5) + controler + .stack_allocator + .allocate_stack(&mut active_table, 4) } else { panic!("frame allocator not initialized!"); } diff --git a/kernel-rs/src/memory/stack_allocator.rs b/kernel-rs/src/memory/stack_allocator.rs index f9aa0ed0..710932d9 100644 --- a/kernel-rs/src/memory/stack_allocator.rs +++ b/kernel-rs/src/memory/stack_allocator.rs @@ -34,10 +34,9 @@ impl StackAllocator { StackAllocator { range } } - pub fn allocate_stack( + pub fn allocate_stack( &mut self, active_table: &mut ActivePageTable, - frame_allocator: &mut FA, size_in_pages: usize, ) -> Option { if size_in_pages == 0 { @@ -70,10 +69,7 @@ impl StackAllocator { // create a new stack let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32; - Some(Stack::new( - top_of_stack, - start.start_address().as_u32(), - )) + Some(Stack::new(top_of_stack, start.start_address().as_u32())) } _ => None, /* not enough pages */ } diff --git a/kernel-rs/x86 b/kernel-rs/x86 index c6636434..b50a1f4f 160000 --- a/kernel-rs/x86 +++ b/kernel-rs/x86 @@ -1 +1 @@ -Subproject commit c6636434cb64916c303c17c243c0e93830882248 +Subproject commit b50a1f4f875be1ccd8a89cf0ae23e292630d414e