WIP: IDT in rust
This commit is contained in:
parent
ae34f7b5db
commit
dea137be73
5 changed files with 152 additions and 16 deletions
31
src/arch/x86_64/gdt.rs
Normal file
31
src/arch/x86_64/gdt.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
pub const GDT_NULL: usize = 0;
|
||||
pub const GDT_KERNEL_CODE: usize = 1;
|
||||
pub const GDT_KERNEL_DATA: usize = 2;
|
||||
pub const GDT_USER_CODE: usize = 3;
|
||||
pub const GDT_USER_DATA: usize = 4;
|
||||
pub const GDT_USER_TLS: usize = 5;
|
||||
pub const GDT_TSS: usize = 6;
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct GdtDescriptor {
|
||||
pub size: u16,
|
||||
pub ptr: u64
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct GdtEntry {
|
||||
pub limitl: u16,
|
||||
pub basel: u16,
|
||||
pub basem: u8,
|
||||
pub attribute: u8,
|
||||
pub flags_limith: u8,
|
||||
pub baseh: u8
|
||||
}
|
||||
|
||||
impl GdtEntry {
|
||||
pub fn set_base(&mut self, base: usize) {
|
||||
self.basel = base as u16;
|
||||
self.basem = (base >> 16) as u8;
|
||||
self.baseh = (base >> 24) as u8;
|
||||
}
|
||||
}
|
||||
53
src/arch/x86_64/idt.rs
Normal file
53
src/arch/x86_64/idt.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use core::mem;
|
||||
|
||||
pub static mut IDTR: IdtDescriptor = IdtDescriptor {
|
||||
size: 0,
|
||||
offset: 0
|
||||
};
|
||||
|
||||
pub static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256];
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct IdtDescriptor {
|
||||
pub size: u16,
|
||||
pub offset: u64
|
||||
}
|
||||
|
||||
impl IdtDescriptor {
|
||||
pub fn set_slice(&mut self, slice: &'static [IdtEntry]) {
|
||||
self.size = (slice.len() * mem::size_of::<IdtEntry>() - 1) as u16;
|
||||
self.offset = slice.as_ptr() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
pub struct IdtEntry {
|
||||
pub offsetl: u16,
|
||||
pub selector: u16,
|
||||
pub zero: u8,
|
||||
pub attribute: u8,
|
||||
pub offsetm: u16,
|
||||
pub offseth: u32,
|
||||
pub zero2: u32
|
||||
}
|
||||
|
||||
impl IdtEntry {
|
||||
pub const fn new() -> IdtEntry {
|
||||
IdtEntry {
|
||||
offsetl: 0,
|
||||
selector: 0,
|
||||
zero: 0,
|
||||
attribute: 0,
|
||||
offsetm: 0,
|
||||
offseth: 0,
|
||||
zero2: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_offset(&mut self, base: usize) {
|
||||
self.offsetl = base as u16;
|
||||
self.offsetm = (base >> 16) as u16;
|
||||
self.offseth = (base >> 32) as u32;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,35 @@
|
|||
/// It is increcibly unsafe, and should be minimal in nature
|
||||
/// It must create the IDT with the correct entries, those entries are
|
||||
/// defined in other files inside of the `arch` module
|
||||
|
||||
use super::idt::{IDTR, IDT};
|
||||
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn kmain() {
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
loop{}
|
||||
for entry in IDT.iter_mut() {
|
||||
entry.attribute = 1 << 7 | 0xE;
|
||||
entry.selector = 8;
|
||||
entry.set_offset(&blank as *const _ as usize);
|
||||
entry.zero = 0;
|
||||
entry.zero2 = 0;
|
||||
}
|
||||
IDTR.set_slice(&IDT);
|
||||
asm!("lidt [rax]" : : "{rax}"(&IDTR as *const _ as usize) : : "intel", "volatile");
|
||||
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
asm!("int 0xFF" : : : : "intel", "volatile");
|
||||
|
||||
loop{
|
||||
asm!("hlt" : : : : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern fn blank() {
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
asm!("iretq" : : : : "intel", "volatile");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
/// Global descriptor table
|
||||
pub mod gdt;
|
||||
|
||||
/// Interrupt descriptor table
|
||||
pub mod idt;
|
||||
|
||||
/// IRQ Handling
|
||||
pub mod irq;
|
||||
|
||||
|
|
|
|||
20
src/arch/x86_64/tss.rs
Normal file
20
src/arch/x86_64/tss.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#[repr(packed)]
|
||||
pub struct Tss {
|
||||
pub reserved1: u32,
|
||||
pub sp0: u64,
|
||||
pub sp1: u64,
|
||||
pub sp2: u64,
|
||||
pub reserved2: u32,
|
||||
pub reserved3: u32,
|
||||
pub ist1: u64,
|
||||
pub ist2: u64,
|
||||
pub ist3: u64,
|
||||
pub ist4: u64,
|
||||
pub ist5: u64,
|
||||
pub ist6: u64,
|
||||
pub ist7: u64,
|
||||
pub reserved4: u32,
|
||||
pub reserved5: u32,
|
||||
pub reserved6: u16,
|
||||
pub iomap_base: u16,
|
||||
}
|
||||
Loading…
Reference in a new issue