diff --git a/Makefile b/Makefile index 467673a..61cf316 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,13 @@ ASM_OBJ=$(subst src/, build/, ${ASM_SRC:.asm=.o}) all: $(KERNEL) run: $(ISO) - @qemu-system-x86_64 -drive format=raw,file=$(ISO) -serial stdio + @qemu-system-i386 -drive format=raw,file=$(ISO) -serial stdio + +rund: $(ISO) + @qemu-system-i386 -drive format=raw,file=$(ISO) -serial stdio -d int + +rundd: $(ISO) + @qemu-system-i386 -drive format=raw,file=$(ISO) -serial stdio -d int -s -S iso: $(ISO) diff --git a/src/arch/i686/gdt.asm b/src/arch/i686/gdt.asm new file mode 100644 index 0000000..c7a8691 --- /dev/null +++ b/src/arch/i686/gdt.asm @@ -0,0 +1,17 @@ +global _gdt_flush +extern _gp + +_gdt_flush: + lgdt [_gp] + + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + jmp 0x08:complete_flush + +complete_flush: + ret diff --git a/src/elsos.rs b/src/elsos.rs index 0f6ecc6..93cf69c 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -11,6 +11,7 @@ mod keyboard; mod tty; mod multiboot; mod serial; +mod gdt; use core::panic::PanicInfo; @@ -34,6 +35,8 @@ pub static mut SETTINGS: Settings = Settings #[no_mangle] pub extern "C" fn kernel_main(magic: u32, address: u32) { + + gdt::init_gdt(); init_vga(); vga::cursor::Cursor::init(0, 15); if multiboot::check_magic(magic) && multiboot::parse(address) diff --git a/src/gdt.rs b/src/gdt.rs new file mode 100644 index 0000000..274773c --- /dev/null +++ b/src/gdt.rs @@ -0,0 +1,123 @@ +use core::mem::size_of; + +#[repr(C, packed)] +struct gdt_ptr +{ + limit: u16, + base: u32 +} + +#[repr(C, packed)] +struct gdt_entry +{ + limit0: u16, + base0: u16, + base1: u8, + access_byte: u8, + limit1_flags: u8, + base2: u8 +} + +#[repr(C, packed)] +struct gdt +{ + null: gdt_entry, + kernel_code: gdt_entry, + kernel_data: gdt_entry, + kernel_stack: gdt_entry, + user_code: gdt_entry, + user_data: gdt_entry, + user_stack: gdt_entry, +} + +static mut GDT_TABLE: gdt = gdt +{ + null: gdt_entry + { + limit0: 0, + base0: 0, + base1: 0, + access_byte: 0x00, + limit1_flags: 0x00, + base2: 0 + }, + kernel_code: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x9a, + limit1_flags: 0xcf, + base2: 0 + }, + kernel_data: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x92, + limit1_flags: 0xcf, + base2: 0 + }, + kernel_stack: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x92, + limit1_flags: 0xcf, + base2: 0 + }, + user_code: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x9a, + limit1_flags: 0xcf, + base2: 0 + }, + user_data: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x92, + limit1_flags: 0xcf, + base2: 0 + }, + user_stack: gdt_entry + { + limit0: 0xffff, + base0: 0, + base1: 0, + access_byte: 0x92, + limit1_flags: 0xcf, + base2: 0 + }, +}; + +extern "C" +{ + fn _gdt_flush(); + fn memcpy(dst: *const u8, src: *const u8, size: usize); +} + +#[no_mangle] +static mut _gp: gdt_ptr = gdt_ptr +{ + limit: 0, + base: 0x800 +}; + +pub fn init_gdt() +{ + let size = size_of::() - 1; + unsafe + { + memcpy(0x800 as *const u8, (&GDT_TABLE as *const _) as *const u8, size); + _gp.limit = size as u16; + _gdt_flush(); + } +} +