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
|
Cargo.lock
|
||||||
|
build
|
||||||
target
|
target
|
||||||
|
|
11
Makefile
11
Makefile
|
@ -1,6 +1,10 @@
|
||||||
ARCH?=x86_64
|
ARCH?=x86_64
|
||||||
|
|
||||||
run: qemu
|
all: build/harddrive.bin
|
||||||
|
|
||||||
|
list: build/kernel.list
|
||||||
|
|
||||||
|
run: bochs
|
||||||
|
|
||||||
bochs: build/harddrive.bin
|
bochs: build/harddrive.bin
|
||||||
bochs -f bochs.$(ARCH)
|
bochs -f bochs.$(ARCH)
|
||||||
|
@ -11,12 +15,15 @@ qemu: build/harddrive.bin
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
build/libkernel.a: 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
|
#--target $(ARCH)-unknown-none.json
|
||||||
|
|
||||||
build/kernel.bin: build/libkernel.a
|
build/kernel.bin: build/libkernel.a
|
||||||
ld -m elf_$(ARCH) -o $@ -T bootloader/x86/kernel.ld -z max-page-size=0x1000 $<
|
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
|
build/harddrive.bin: build/kernel.bin
|
||||||
nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/x86/ -ibuild/ bootloader/x86/harddrive.asm
|
nasm -f bin -o $@ -D ARCH_$(ARCH) -ibootloader/x86/ -ibuild/ bootloader/x86/harddrive.asm
|
||||||
|
|
||||||
|
|
|
@ -67,21 +67,13 @@ long_mode:
|
||||||
mov gs, rax
|
mov gs, rax
|
||||||
mov ss, rax
|
mov ss, rax
|
||||||
|
|
||||||
; load long mode IDT
|
|
||||||
lidt [idtr]
|
|
||||||
|
|
||||||
mov rsp, 0x800000 - 128
|
mov rsp, 0x800000 - 128
|
||||||
|
|
||||||
mov rax, gdt.tss
|
|
||||||
ltr ax
|
|
||||||
|
|
||||||
;rust init
|
;rust init
|
||||||
|
xor rax, rax
|
||||||
mov eax, [kernel_base + 0x18]
|
mov eax, [kernel_base + 0x18]
|
||||||
mov [interrupts.handler], rax
|
mov rbx, gdtr
|
||||||
mov rax, gdtr
|
jmp rax
|
||||||
mov rbx, idtr
|
|
||||||
mov rcx, tss
|
|
||||||
int 0xFF
|
|
||||||
.lp:
|
.lp:
|
||||||
sti
|
sti
|
||||||
hlt
|
hlt
|
||||||
|
|
|
@ -183,8 +183,8 @@ vesa:
|
||||||
.minx dw 640
|
.minx dw 640
|
||||||
.miny dw 480
|
.miny dw 480
|
||||||
.required:
|
.required:
|
||||||
.requiredx dw 0 ;1024 ;USE THESE WITH CAUTION
|
.requiredx dw 1024 ;USE THESE WITH CAUTION
|
||||||
.requiredy dw 0 ;768
|
.requiredy dw 768
|
||||||
.requiredmode dw 0
|
.requiredmode dw 0
|
||||||
|
|
||||||
.noedidmsg db "EDID not supported.",10,13,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 is increcibly unsafe, and should be minimal in nature
|
||||||
/// It must create the IDT with the correct entries, those entries are
|
/// It must create the IDT with the correct entries, those entries are
|
||||||
/// defined in other files inside of the `arch` module
|
/// defined in other files inside of the `arch` module
|
||||||
|
|
||||||
|
use super::idt::{IDTR, IDT};
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn kmain() {
|
pub unsafe extern fn kmain() {
|
||||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
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
|
/// IRQ Handling
|
||||||
pub mod irq;
|
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.
|
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
|
||||||
|
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
#![feature(const_fn)]
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
Loading…
Reference in a new issue