Copy GDT Segments from xv6 x86_64. Split IRQ mod.

master
WangRunji 7 years ago
parent ab37e359ac
commit 2f24eefb1d

@ -1,3 +1,5 @@
use core::fmt;
use core::fmt::Debug;
use x86_64::structures::tss::TaskStateSegment; use x86_64::structures::tss::TaskStateSegment;
use x86_64::structures::gdt::SegmentSelector; use x86_64::structures::gdt::SegmentSelector;
use x86_64::PrivilegeLevel; use x86_64::PrivilegeLevel;
@ -85,11 +87,27 @@ impl Descriptor {
} }
bitflags! { bitflags! {
/// Reference: https://wiki.osdev.org/GDT
flags DescriptorFlags: u64 { flags DescriptorFlags: u64 {
const ACCESSED = 1 << 40,
const DATA_WRITABLE = 1 << 41,
const CODE_READABLE = 1 << 41,
const CONFORMING = 1 << 42, const CONFORMING = 1 << 42,
const EXECUTABLE = 1 << 43, const EXECUTABLE = 1 << 43,
const USER_SEGMENT = 1 << 44, const USER_SEGMENT = 1 << 44,
const USER_MODE = 1 << 45 | 1 << 46,
const PRESENT = 1 << 47, const PRESENT = 1 << 47,
const LONG_MODE = 1 << 53, const LONG_MODE = 1 << 53,
} }
} }
impl Debug for Descriptor {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
Descriptor::UserSegment(flags) =>
write!(f, "UserSegment( {:?} )", DescriptorFlags{bits: *flags}),
Descriptor::SystemSegment(low, high) =>
write!(f, "SystemSegment{:?}", (low, high)),
}
}
}

@ -0,0 +1,21 @@
use x86_64::structures::idt::*;
pub extern "x86-interrupt" fn breakpoint_handler(
stack_frame: &mut ExceptionStackFrame)
{
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
pub extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut ExceptionStackFrame, _error_code: u64)
{
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
loop {}
}
pub extern "x86-interrupt" fn page_fault_handler(
stack_frame: &mut ExceptionStackFrame, error_code: PageFaultErrorCode)
{
println!("\nEXCEPTION: PAGE FAULT\n{:#?}\n{:#?}", stack_frame, error_code);
loop {}
}

@ -1,13 +1,15 @@
use x86_64::VirtualAddress; use x86_64::VirtualAddress;
use x86_64::structures::idt::*; use x86_64::structures::idt::Idt;
use x86_64::structures::tss::TaskStateSegment; use x86_64::structures::tss::TaskStateSegment;
use memory::MemoryController; use memory::MemoryController;
use spin::Once; use spin::Once;
mod gdt; mod gdt;
mod irq;
lazy_static! { lazy_static! {
static ref IDT: Idt = { static ref IDT: Idt = {
use self::irq::*;
let mut idt = Idt::new(); let mut idt = Idt::new();
idt.breakpoint.set_handler_fn(breakpoint_handler); idt.breakpoint.set_handler_fn(breakpoint_handler);
idt.page_fault.set_handler_fn(page_fault_handler); idt.page_fault.set_handler_fn(page_fault_handler);
@ -19,12 +21,22 @@ lazy_static! {
}; };
} }
// Copied from xv6 x86_64
const GNULL: gdt::Descriptor = gdt::Descriptor::UserSegment(0);
const KCODE: gdt::Descriptor = gdt::Descriptor::UserSegment(0x0020980000000000); // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE
const UCODE: gdt::Descriptor = gdt::Descriptor::UserSegment(0x0020F80000000000); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE
const KDATA: gdt::Descriptor = gdt::Descriptor::UserSegment(0x0000920000000000); // DATA_WRITABLE | USER_SEGMENT | PRESENT
const UDATA: gdt::Descriptor = gdt::Descriptor::UserSegment(0x0000F20000000000); // DATA_WRITABLE | USER_SEGMENT | USER_MODE | PRESENT
static TSS: Once<TaskStateSegment> = Once::new(); static TSS: Once<TaskStateSegment> = Once::new();
static GDT: Once<gdt::Gdt> = Once::new(); static GDT: Once<gdt::Gdt> = Once::new();
const DOUBLE_FAULT_IST_INDEX: usize = 0; const DOUBLE_FAULT_IST_INDEX: usize = 0;
pub fn init(memory_controller: &mut MemoryController) { pub fn init(memory_controller: &mut MemoryController) {
test::print_flags();
use x86_64::structures::gdt::SegmentSelector; use x86_64::structures::gdt::SegmentSelector;
use x86_64::instructions::segmentation::set_cs; use x86_64::instructions::segmentation::set_cs;
use x86_64::instructions::tables::load_tss; use x86_64::instructions::tables::load_tss;
@ -43,7 +55,12 @@ pub fn init(memory_controller: &mut MemoryController) {
let mut tss_selector = SegmentSelector(0); let mut tss_selector = 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()); gdt.add_entry(GNULL);
kcode_selector =
gdt.add_entry(KCODE);
gdt.add_entry(UCODE);
gdt.add_entry(KDATA);
gdt.add_entry(UDATA);
tss_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss)); tss_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss));
gdt gdt
}); });
@ -59,22 +76,21 @@ pub fn init(memory_controller: &mut MemoryController) {
IDT.load(); IDT.load();
} }
extern "x86-interrupt" fn breakpoint_handler( pub mod test
stack_frame: &mut ExceptionStackFrame)
{
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut ExceptionStackFrame, _error_code: u64)
{ {
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); pub fn print_flags() {
loop {} use super::gdt::*;
} // The following 4 GDT entries were copied from xv6 x86_64
let list: [(&str, Descriptor); 4] = [
extern "x86-interrupt" fn page_fault_handler( ("KCODE", super::KCODE), // Code, DPL=0, R/X
stack_frame: &mut ExceptionStackFrame, error_code: PageFaultErrorCode) ("UCODE", super::UCODE), // Code, DPL=3, R/X
{ ("KDATA", super::KDATA), // Data, DPL=0, W
println!("\nEXCEPTION: PAGE FAULT\n{:#?}\n{:#?}", stack_frame, error_code); ("UDATA", super::UDATA), // Data, DPL=3, W
loop {} ];
// Let's see what that means
println!("GDT Segments from xv6 x86_64:");
for (name, desc) in list.iter() {
println!(" {}: {:?}", name, desc);
}
}
} }
Loading…
Cancel
Save