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.rs40
-rw-r--r--kernel/src/interrupts/mod.rs2
-rw-r--r--kernel/src/interrupts/table.rs20
-rw-r--r--kernel/src/lib.rs14
-rw-r--r--kernel/src/linker.ld8
6 files changed, 103 insertions, 14 deletions
diff --git a/kernel/src/boot.asm b/kernel/src/boot.asm
index 451e455..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
+ resb 4096 * 4
stack_top:
diff --git a/kernel/src/interrupts/exceptions.rs b/kernel/src/interrupts/exceptions.rs
new file mode 100644
index 0000000..08555c4
--- /dev/null
+++ b/kernel/src/interrupts/exceptions.rs
@@ -0,0 +1,40 @@
+use crate::io::vga_text::OStream;
+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/mod.rs b/kernel/src/interrupts/mod.rs
new file mode 100644
index 0000000..ae21761
--- /dev/null
+++ b/kernel/src/interrupts/mod.rs
@@ -0,0 +1,2 @@
+mod exceptions;
+pub mod table;
diff --git a/kernel/src/interrupts/table.rs b/kernel/src/interrupts/table.rs
new file mode 100644
index 0000000..6472014
--- /dev/null
+++ b/kernel/src/interrupts/table.rs
@@ -0,0 +1,20 @@
+use crate::io::vga_text::OStream;
+use lazy_static::lazy_static;
+use x86_64::structures::idt::InterruptDescriptorTable;
+
+lazy_static! {
+ static ref IDT: InterruptDescriptorTable = {
+ 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
+ };
+}
+
+pub fn init() {
+ IDT.load()
+}
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index cbc9915..8ec68e5 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -1,13 +1,13 @@
#![no_main]
#![feature(compiler_builtins_lib)]
#![feature(custom_test_frameworks)]
+#![feature(abi_x86_interrupt)]
#![feature(panic_info_message)]
#![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"]
#![no_std]
-extern crate compiler_builtins;
-
+mod interrupts;
mod io;
use core::fmt::Write;
@@ -26,6 +26,7 @@ pub fn test_runner(tests: &[&dyn Fn(&mut OStream)]) {
#[no_mangle]
pub extern "C" fn _start() -> ! {
+ interrupts::table::init();
if cfg!(test) {
#[cfg(test)]
test_main();
@@ -39,6 +40,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 {}
}
@@ -64,8 +66,12 @@ pub extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! {
vga_text::Color::Red,
));
stderr.set_centered(true);
- write!(&mut stderr, "{:?}", info.message()
- .unwrap_or(&format_args!("no panic information obtainable")));
+ write!(
+ &mut stderr,
+ "{:?}",
+ info.message()
+ .unwrap_or(&format_args!("no panic information obtainable"))
+ );
//loop{}
stderr.set_centered(false);
if cfg!(test) {
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)
+ }
}