diff options
author | Dennis Kobert <dennis@kobert.dev> | 2019-11-08 07:28:08 +0100 |
---|---|---|
committer | Dennis Kobert <dennis@kobert.dev> | 2019-11-08 07:28:08 +0100 |
commit | d261a0f15a350d81430d3937d3c02118c395d27c (patch) | |
tree | 78cba47d4e7a31fdde64dc7b483ed5fd7d183aca | |
parent | a9d39fdb56526c4146d92e6af68cc175ec4da7c2 (diff) |
Implement guarding page
-rwxr-xr-x | kernel/run | 4 | ||||
-rw-r--r-- | kernel/src/boot.asm | 33 | ||||
-rw-r--r-- | kernel/src/interrupts/exceptions.rs | 35 | ||||
-rw-r--r-- | kernel/src/interrupts/table.rs | 4 | ||||
-rw-r--r-- | kernel/src/lib.rs | 2 | ||||
-rw-r--r-- | kernel/src/linker.ld | 8 |
6 files changed, 72 insertions, 14 deletions
@@ -8,7 +8,7 @@ onerr() { trap onerr ERR name="uff" -build_mode=debug +build_mode=release action=help target=x86_64 test_mode=false @@ -80,7 +80,7 @@ build() { # cargo xbuild #fi if ! $test_mode; then - cargo xbuild + cargo xbuild "--$build_mode" fi build_iso } diff --git a/kernel/src/boot.asm b/kernel/src/boot.asm index 95b699a..1c0b3da 100644 --- a/kernel/src/boot.asm +++ b/kernel/src/boot.asm @@ -5,14 +5,16 @@ section .text bits 32 start: mov esp, stack_top - + call check_multiboot call check_cpuid call check_long_mode call setup_page_tables call enable_paging - ; load the 64-bit GDT + + + ; load the 64-bit GDT lgdt [gdt64.pointer] jmp gdt64.code:long_mode_start @@ -96,21 +98,27 @@ setup_page_tables: .map_p2_table: ; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx + mov ebx, eax + cmp eax, stack_bottom + 0b10000011 - 0x400000 + jne .hit_stack + and ebx, ~1 mov [p2_table + ecx ], eax ; map ecx-th entry - add eax, 0x200000 ; 2MiB - mov [p2_table + ecx + 8 ], eax ; map ecx-th entry - add eax, 0x200000 ; 2MiB - mov [p2_table + ecx + 16], eax ; map ecx-th entry - add eax, 0x200000 ; 2MiB - mov [p2_table + ecx + 24], eax ; map ecx-th entry + add ecx, 8 + +.hit_stack: + mov [p2_table + ecx ], ebx ; map ecx-th entry add eax, 0x200000 ; 2MiB - add ecx, 32 + add ecx, 8 + ;add ecx, 32 cmp ecx, 4096 ; if counter == 512, the whole P2 table is mapped jne .map_p2_table ; else map the next entry ret + + + enable_paging: mov eax, p4_table mov cr3, eax @@ -131,6 +139,10 @@ enable_paging: or eax, 1 << 31 mov cr0, eax + ; move stack pointer to accommodate for the guard page + add esp, 0x200000 + + ret section .rodata @@ -159,6 +171,7 @@ p3_table: resb 4096 p2_table: resb 4096 +alignb 4096 * 512 stack_bottom: - resb 4096 * 8 + resb 4096 * 4 stack_top: diff --git a/kernel/src/interrupts/exceptions.rs b/kernel/src/interrupts/exceptions.rs index 5ec7588..08555c4 100644 --- a/kernel/src/interrupts/exceptions.rs +++ b/kernel/src/interrupts/exceptions.rs @@ -1,7 +1,40 @@ use crate::io::vga_text::OStream; -use x86_64::structures::idt::InterruptStackFrame; +use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode}; pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) { let mut stdout = OStream::new(); stdout.print(b"EXCEPTION: BREAKPOINT\n"); } + +pub extern "x86-interrupt" fn page_fault_handler( + stack_frame: &mut InterruptStackFrame, + error_code: PageFaultErrorCode, +) { + use x86_64::registers::control::Cr2; + + let mut stdout = OStream::new(); + stdout.print(b"EXCEPTION: PAGEFAULT\n"); + loop {} + panic!("PAGE FAULT"); + //println!("Accessed Address: {:?}", Cr2::read()); + //println!("Error Code: {:?}", error_code); + //println!("{:#?}", stack_frame); +} + +pub extern "x86-interrupt" fn segment_not_present_handler( + stack_frame: &mut InterruptStackFrame, + error_code: u64, +) { + loop {} + let mut stdout = OStream::new(); + stdout.print(b"EXCEPTION: SEGMENT NOT PRESENT\n"); +} + +extern "x86-interrupt" fn double_fault_handler( + stack_frame: &mut InterruptStackFrame, + _error_code: u64, +) { + let mut stdout = OStream::new(); + stdout.print(b"EXCEPTION: DOUBLE FAULT"); + loop {} +} diff --git a/kernel/src/interrupts/table.rs b/kernel/src/interrupts/table.rs index 47d6ead..6472014 100644 --- a/kernel/src/interrupts/table.rs +++ b/kernel/src/interrupts/table.rs @@ -7,6 +7,10 @@ lazy_static! { let mut idt = InterruptDescriptorTable::new(); idt.breakpoint .set_handler_fn(super::exceptions::breakpoint_handler); + idt.page_fault + .set_handler_fn(super::exceptions::page_fault_handler); + idt.segment_not_present + .set_handler_fn(super::exceptions::segment_not_present_handler); idt }; } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 45ba8e1..b36d731 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -39,6 +39,7 @@ pub extern "C" fn _start() -> ! { core::iter::successors(Some(0), |n| Some(n + 1)) .for_each(|n| write!(&mut stdout, "hello world {}!", n).unwrap()); + x86_64::instructions::interrupts::int3(); loop {} } @@ -72,6 +73,5 @@ pub extern "C" fn panic_handler(_info: &core::panic::PanicInfo) -> ! { write!(serial::SerialStream::new(), "Testing failed\n").unwrap(); qemu::exit_qemu(qemu::QemuExitCode::Failed); } - x86_64::instructions::interrupts::int3(); loop {} } diff --git a/kernel/src/linker.ld b/kernel/src/linker.ld index 9b5355c..d187fd2 100644 --- a/kernel/src/linker.ld +++ b/kernel/src/linker.ld @@ -13,4 +13,12 @@ SECTIONS { { *(.text) } + rodata : + { + *(.rodata) + } + .bss : + { + *(.bss) + } } |