summaryrefslogtreecommitdiff
path: root/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src')
-rw-r--r--kernel/src/boot.asm33
-rw-r--r--kernel/src/interrupts/exceptions.rs35
-rw-r--r--kernel/src/interrupts/table.rs4
-rw-r--r--kernel/src/lib.rs2
-rw-r--r--kernel/src/linker.ld8
5 files changed, 70 insertions, 12 deletions
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)
+ }
}