now we have 2 tss's, still doesnt work properly
This commit is contained in:
parent
b3a1c5194a
commit
7e150e081b
8 changed files with 93 additions and 54 deletions
|
|
@ -2,55 +2,79 @@ use x86::structures::gdt;
|
||||||
use x86::structures::tss;
|
use x86::structures::tss;
|
||||||
use x86::instructions::segmentation::set_cs;
|
use x86::instructions::segmentation::set_cs;
|
||||||
use x86::instructions::tables::load_tss;
|
use x86::instructions::tables::load_tss;
|
||||||
|
use x86::registers::control;
|
||||||
use arch::x86::paging::ActivePageTable;
|
use arch::x86::paging::ActivePageTable;
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
// use io;
|
// use io;
|
||||||
|
|
||||||
static GDT: Once<gdt::Gdt> = Once::new();
|
static GDT: Once<gdt::Gdt> = Once::new();
|
||||||
static TSS: Once<tss::TaskStateSegment> = Once::new();
|
static TSS_MAIN: Once<tss::TaskStateSegment> = Once::new();
|
||||||
|
static TSS_INT: Once<tss::TaskStateSegment> = Once::new();
|
||||||
|
|
||||||
pub fn init(mut active_table: &mut ActivePageTable) {
|
pub fn init(mut active_table: &mut ActivePageTable) {
|
||||||
// let tss = tss::TaskStateSegment::new();
|
let tss_main = TSS_MAIN.call_once(|| {
|
||||||
let tss = TSS.call_once(|| {
|
|
||||||
let mut tss = tss::TaskStateSegment::new();
|
let mut tss = tss::TaskStateSegment::new();
|
||||||
match ::memory::allocate_stack(&mut active_table) {
|
// tss.esp0 = stack.top;
|
||||||
Some(stack) => {tss.esp0 = stack.top; tss.ss = 0x18},
|
tss.ss0 = 0x8;
|
||||||
// Some(stack) => {tss.esp = stack.top; tss.ebp = stack.bottom },
|
tss.cr3 = control::Cr3::read_u32();
|
||||||
_ => panic!("There is no stack available for tss"),
|
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
|
tss
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut code_selector = gdt::SegmentSelector(0);
|
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 gdt = GDT.call_once(|| {
|
||||||
let mut gdt = gdt::Gdt::new();
|
let mut gdt = gdt::Gdt::new();
|
||||||
code_selector = gdt.add_entry(gdt::Descriptor::kernel_code_segment());
|
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
|
gdt
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("gdt 0 upper: {:#x}", gdt.table[0] 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 0 lower: {:#x}", gdt.table[0] >> 32 as u32);
|
||||||
println!("gdt 1 upper: {:#x}", gdt.table[1] 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 1 lower: {:#x}", gdt.table[1] >> 32 as u32);
|
||||||
println!("gdt 2 upper: {:#x}", gdt.table[2] 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 2 lower: {:#x}", gdt.table[2] >> 32 as u32);
|
||||||
println!("gdt 3 upper: {:#x}", gdt.table[3] 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 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!();
|
flush!();
|
||||||
|
|
||||||
// io::halt();
|
|
||||||
gdt.load();
|
gdt.load();
|
||||||
unsafe {
|
unsafe {
|
||||||
// reload code segment register
|
// reload code segment register
|
||||||
|
println!("set_cs({:#x})", code_selector.0);
|
||||||
set_cs(code_selector);
|
set_cs(code_selector);
|
||||||
// load TSS
|
// load TSS
|
||||||
println!("loading tss {:?}", tss_selector);
|
println!("loading tss {:?}", tss_main_selector);
|
||||||
load_tss(tss_selector);
|
load_tss(tss_main_selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,24 @@ lazy_static! {
|
||||||
idt.debug.set_handler_fn(exception::debug);
|
idt.debug.set_handler_fn(exception::debug);
|
||||||
idt.non_maskable_interrupt.set_handler_fn(exception::non_maskable);
|
idt.non_maskable_interrupt.set_handler_fn(exception::non_maskable);
|
||||||
idt.breakpoint.set_handler_fn(exception::breakpoint);
|
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.overflow.set_handler_fn(exception::overflow);
|
||||||
idt.bound_range_exceeded.set_handler_fn(exception::bound_range);
|
idt.bound_range_exceeded.set_handler_fn(exception::bound_range);
|
||||||
idt.invalid_opcode.set_handler_fn(exception::invalid_opcode);
|
idt.invalid_opcode.set_handler_fn(exception::invalid_opcode);
|
||||||
idt.device_not_available.set_handler_fn(exception::device_not_available);
|
idt.device_not_available.set_handler_fn(exception::device_not_available);
|
||||||
idt.double_fault.set_handler_fn(exception::double_fault);
|
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.segment_not_present.set_handler_fn(exception::segment_not_present);
|
||||||
idt.stack_segment_fault.set_handler_fn(exception::stack_segment);
|
idt.stack_segment_fault.set_handler_fn(exception::stack_segment);
|
||||||
idt.general_protection_fault.set_handler_fn(exception::general_protection);
|
idt.general_protection_fault.set_handler_fn(exception::general_protection);
|
||||||
idt.page_fault.set_handler_fn(exception::page_fault);
|
idt.page_fault.set_handler_fn(exception::page_fault);
|
||||||
idt.page_fault.set_gate_type(GateType::TaskGate32);
|
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.x87_floating_point.set_handler_fn(exception::x87_fpu);
|
||||||
idt.alignment_check.set_handler_fn(exception::alignment_check);
|
idt.alignment_check.set_handler_fn(exception::alignment_check);
|
||||||
idt.machine_check.set_handler_fn(exception::machine_check);
|
idt.machine_check.set_handler_fn(exception::machine_check);
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
// https://wiki.osdev.org/Exceptions
|
// https://wiki.osdev.org/Exceptions
|
||||||
|
|
||||||
use arch::x86::pti;
|
|
||||||
use io;
|
|
||||||
|
|
||||||
macro_rules! exception {
|
macro_rules! exception {
|
||||||
($name:ident, $func:block) => {
|
($name:ident, $func:block) => {
|
||||||
pub extern "x86-interrupt" fn $name(stack_frame: &mut ExceptionStackFrame)
|
pub extern "x86-interrupt" fn $name(stack_frame: &mut ExceptionStackFrame)
|
||||||
{
|
{
|
||||||
// unsafe { pti::map(); }
|
|
||||||
|
|
||||||
println!("Exception: {}", stringify!($name));
|
println!("Exception: {}", stringify!($name));
|
||||||
println!("{:#?}", stack_frame);
|
println!("{:#?}", stack_frame);
|
||||||
flush!();
|
flush!();
|
||||||
|
|
@ -18,8 +13,6 @@ macro_rules! exception {
|
||||||
$func
|
$func
|
||||||
}
|
}
|
||||||
inner(stack_frame);
|
inner(stack_frame);
|
||||||
|
|
||||||
// unsafe { pti::unmap(); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +43,11 @@ exception!(divide_by_zero, {
|
||||||
|
|
||||||
exception!(debug, {});
|
exception!(debug, {});
|
||||||
exception!(non_maskable, {});
|
exception!(non_maskable, {});
|
||||||
exception!(breakpoint, {});
|
exception!(breakpoint, {
|
||||||
|
// unsafe {
|
||||||
|
// asm!("hlt");
|
||||||
|
// }
|
||||||
|
});
|
||||||
exception!(overflow, {});
|
exception!(overflow, {});
|
||||||
exception!(bound_range, {});
|
exception!(bound_range, {});
|
||||||
exception!(invalid_opcode, {});
|
exception!(invalid_opcode, {});
|
||||||
|
|
@ -60,7 +57,9 @@ exception!(coprocessor_segment_overrun, {});
|
||||||
exception_err!(invalid_tss, {});
|
exception_err!(invalid_tss, {});
|
||||||
exception_err!(segment_not_present, {});
|
exception_err!(segment_not_present, {});
|
||||||
exception_err!(stack_segment, {});
|
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(
|
pub extern "x86-interrupt" fn page_fault(
|
||||||
stack_frame: &mut ExceptionStackFrame,
|
stack_frame: &mut ExceptionStackFrame,
|
||||||
|
|
@ -70,6 +69,9 @@ pub extern "x86-interrupt" fn page_fault(
|
||||||
println!("Error code: {:?}", code);
|
println!("Error code: {:?}", code);
|
||||||
println!("{:#?}", stack_frame);
|
println!("{:#?}", stack_frame);
|
||||||
flush!();
|
flush!();
|
||||||
|
unsafe {
|
||||||
|
asm!("hlt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exception!(x87_fpu, {});
|
exception!(x87_fpu, {});
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ fn dispatch(command: &str) -> Result<(), &'static str> {
|
||||||
"stack" => self::print_stack(),
|
"stack" => self::print_stack(),
|
||||||
"regs" => self::regs(),
|
"regs" => self::regs(),
|
||||||
"cpu" => self::cpu(),
|
"cpu" => self::cpu(),
|
||||||
|
"int3" => self::int3(),
|
||||||
|
"overflow" => self::overflow(),
|
||||||
|
|
||||||
_ => Err("Command unknown. (h|help for help)"),
|
_ => Err("Command unknown. (h|help for help)"),
|
||||||
}
|
}
|
||||||
|
|
@ -198,3 +200,17 @@ pub fn cpu() -> Result<(), &'static str> {
|
||||||
flush!();
|
flush!();
|
||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,8 @@ pub fn kmain() -> ! {
|
||||||
// heap avalaible for tracking freed frames
|
// heap avalaible for tracking freed frames
|
||||||
memory::init_noncore();
|
memory::init_noncore();
|
||||||
|
|
||||||
// x86::instructions::interrupts::int3();
|
// vga is *not* cpu specific
|
||||||
// println!("size of idt entry: {}", mem::size_of::<IdtEntry<HandlerFunc>>());
|
vga::init();
|
||||||
// println!("size of i32 {}", mem::size_of::<i32>());
|
|
||||||
// flush!();
|
|
||||||
// unsafe {asm!("hlt");}
|
|
||||||
// let x = 0;
|
|
||||||
// let y = 5 /x;
|
|
||||||
// println!("x {} y {}", x, y);
|
|
||||||
|
|
||||||
// fn stack_overflow() {
|
// fn stack_overflow() {
|
||||||
// stack_overflow();
|
// stack_overflow();
|
||||||
|
|
@ -70,8 +64,7 @@ pub fn kmain() -> ! {
|
||||||
*(0xdead as *mut u32) = 42;
|
*(0xdead as *mut u32) = 42;
|
||||||
};
|
};
|
||||||
|
|
||||||
// vga is *not* cpu specific
|
// x86::instructions::interrupts::int3();
|
||||||
vga::init();
|
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ use x86::*;
|
||||||
|
|
||||||
use self::bump::BumpFrameAllocator;
|
use self::bump::BumpFrameAllocator;
|
||||||
use self::recycle::RecycleAllocator;
|
use self::recycle::RecycleAllocator;
|
||||||
use self::stack_allocator::{Stack,StackAllocator};
|
use self::stack_allocator::{Stack, StackAllocator};
|
||||||
|
|
||||||
|
|
||||||
pub trait FrameAllocator {
|
pub trait FrameAllocator {
|
||||||
fn allocate_frames(&mut self, size: usize) -> Option<PhysFrame>;
|
fn allocate_frames(&mut self, size: usize) -> Option<PhysFrame>;
|
||||||
|
|
@ -49,7 +48,7 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
boot_info.start_address(),
|
boot_info.start_address(),
|
||||||
boot_info.end_address(),
|
boot_info.end_address(),
|
||||||
memory_map_tag.memory_areas(),
|
memory_map_tag.memory_areas(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let frame_allocator = RecycleAllocator::new(bump_allocator);
|
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<Stack> {
|
pub fn allocate_stack(mut active_table: &mut ActivePageTable) -> Option<Stack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(ref mut controler) = MEMORY_CONTROLER {
|
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 {
|
} else {
|
||||||
panic!("frame allocator not initialized!");
|
panic!("frame allocator not initialized!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,9 @@ impl StackAllocator {
|
||||||
StackAllocator { range }
|
StackAllocator { range }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate_stack<FA: FrameAllocator>(
|
pub fn allocate_stack(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_table: &mut ActivePageTable,
|
active_table: &mut ActivePageTable,
|
||||||
frame_allocator: &mut FA,
|
|
||||||
size_in_pages: usize,
|
size_in_pages: usize,
|
||||||
) -> Option<Stack> {
|
) -> Option<Stack> {
|
||||||
if size_in_pages == 0 {
|
if size_in_pages == 0 {
|
||||||
|
|
@ -70,10 +69,7 @@ impl StackAllocator {
|
||||||
|
|
||||||
// create a new stack
|
// create a new stack
|
||||||
let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32;
|
let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32;
|
||||||
Some(Stack::new(
|
Some(Stack::new(top_of_stack, start.start_address().as_u32()))
|
||||||
top_of_stack,
|
|
||||||
start.start_address().as_u32(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
_ => None, /* not enough pages */
|
_ => None, /* not enough pages */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit c6636434cb64916c303c17c243c0e93830882248
|
Subproject commit b50a1f4f875be1ccd8a89cf0ae23e292630d414e
|
||||||
Loading…
Reference in a new issue