WIP: IDT in rust
This commit is contained in:
parent
ae34f7b5db
commit
dea137be73
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
Cargo.lock
|
||||
build
|
||||
target
|
||||
|
|
11
Makefile
11
Makefile
|
@ -1,6 +1,10 @@
|
|||
ARCH?=x86_64
|
||||
|
||||
run: qemu
|
||||
all: build/harddrive.bin
|
||||
|
||||
list: build/kernel.list
|
||||
|
||||
run: bochs
|
||||
|
||||
bochs: build/harddrive.bin
|
||||
bochs -f bochs.$(ARCH)
|
||||
|
@ -11,12 +15,15 @@ qemu: build/harddrive.bin
|
|||
FORCE:
|
||||
|
||||
build/libkernel.a: FORCE
|
||||
rustc --crate-type staticlib src/lib.rs -o $@
|
||||
rustc --crate-type staticlib -C lto -O src/lib.rs -o $@
|
||||
#--target $(ARCH)-unknown-none.json
|
||||
|
||||
build/kernel.bin: build/libkernel.a
|
||||
ld -m elf_$(ARCH) -o $@ -T bootloader/x86/kernel.ld -z max-page-size=0x1000 $<
|
||||
|
||||
build/kernel.list: build/kernel.bin
|
||||
objdump -C -M intel -D $< > $@
|
||||
|
||||
build/harddrive.bin: build/kernel.bin
|
||||
nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/x86/ -ibuild/ bootloader/x86/harddrive.asm
|
||||
|
||||
|
|
|
@ -67,21 +67,13 @@ long_mode:
|
|||
mov gs, rax
|
||||
mov ss, rax
|
||||
|
||||
; load long mode IDT
|
||||
lidt [idtr]
|
||||
|
||||
mov rsp, 0x800000 - 128
|
||||
|
||||
mov rax, gdt.tss
|
||||
ltr ax
|
||||
|
||||
;rust init
|
||||
xor rax, rax
|
||||
mov eax, [kernel_base + 0x18]
|
||||
mov [interrupts.handler], rax
|
||||
mov rax, gdtr
|
||||
mov rbx, idtr
|
||||
mov rcx, tss
|
||||
int 0xFF
|
||||
mov rbx, gdtr
|
||||
jmp rax
|
||||
.lp:
|
||||
sti
|
||||
hlt
|
||||
|
|
|
@ -183,8 +183,8 @@ vesa:
|
|||
.minx dw 640
|
||||
.miny dw 480
|
||||
.required:
|
||||
.requiredx dw 0 ;1024 ;USE THESE WITH CAUTION
|
||||
.requiredy dw 0 ;768
|
||||
.requiredx dw 1024 ;USE THESE WITH CAUTION
|
||||
.requiredy dw 768
|
||||
.requiredmode dw 0
|
||||
|
||||
.noedidmsg db "EDID not supported.",10,13,0
|
||||
|
|
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,
|
||||
}
|
|
@ -65,6 +65,7 @@
|
|||
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
|
||||
|
||||
#![feature(asm)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(naked_functions)]
|
||||
#![no_std]
|
||||
|
|
Loading…
Reference in a new issue