mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Begin work for exceptions post
This commit is contained in:
19
blog/post/exceptions.md
Normal file
19
blog/post/exceptions.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
+++
|
||||||
|
title = "CPU Exceptions"
|
||||||
|
date = "2016-05-10"
|
||||||
|
+++
|
||||||
|
|
||||||
|
## Interrupts
|
||||||
|
Whenever a device (e.g. the keyboard contoller) needs
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
An exception signals that something is wrong with the current instruction. For example, the CPU issues an exception when it should divide by 0. When an exception occurs, the CPU immediately calls a specific exception handler function, depending on the exception type.
|
||||||
|
|
||||||
|
We've already seen several types of exceptions in our kernel:
|
||||||
|
|
||||||
|
- **Illegal instruction**: TODO
|
||||||
|
- **Page Fault**: The CPU tried to perform an illegal read or write.
|
||||||
|
- **Double Fault**: TODO
|
||||||
|
- **Triple Fault**:
|
||||||
|
|
||||||
|
The full list of
|
||||||
26
src/interrupts/idt.rs
Normal file
26
src/interrupts/idt.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use x86::irq::IdtEntry;
|
||||||
|
|
||||||
|
pub struct Idt([IdtEntry; 16]);
|
||||||
|
|
||||||
|
impl Idt {
|
||||||
|
pub fn new() -> Idt {
|
||||||
|
Idt([IdtEntry::missing(); 16])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_handler(&mut self, entry: usize, handler: extern fn()->!) {
|
||||||
|
let ptr = handler as usize;
|
||||||
|
self.0[entry] = IdtEntry::interrupt_gate(0x8, ptr as *const _);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn load(&self) {
|
||||||
|
use x86::dtables::{DescriptorTablePointer, lidt};
|
||||||
|
use core::mem::size_of;
|
||||||
|
|
||||||
|
let ptr = DescriptorTablePointer{
|
||||||
|
base: self as *const _ as u64,
|
||||||
|
limit: (size_of::<Self>() - 1) as u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
lidt(&ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/interrupts/mod.rs
Normal file
41
src/interrupts/mod.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
mod idt;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref IDT: idt::Idt = {
|
||||||
|
let mut idt = idt::Idt::new();
|
||||||
|
|
||||||
|
idt.set_handler(0, divide_by_zero_handler);
|
||||||
|
idt.set_handler(8, double_fault_handler);
|
||||||
|
idt.set_handler(13, general_protection_fault_handler);
|
||||||
|
idt.set_handler(14, page_fault_handler);
|
||||||
|
|
||||||
|
idt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
assert_has_not_been_called!();
|
||||||
|
|
||||||
|
unsafe { IDT.load() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub extern fn divide_by_zero_handler() -> ! {
|
||||||
|
println!("EXCEPTION: DIVIDE BY ZERO");
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn double_fault_handler() -> ! {
|
||||||
|
println!("EXCEPTION: DOUBLE FAULT");
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn general_protection_fault_handler() -> ! {
|
||||||
|
println!("EXCEPTION: GENERAL PROTECTION FAULT");
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn page_fault_handler() -> ! {
|
||||||
|
println!("EXCEPTION: PAGE FAULT");
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
10
src/lib.rs
10
src/lib.rs
@@ -10,6 +10,7 @@
|
|||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![feature(const_fn, unique)]
|
#![feature(const_fn, unique)]
|
||||||
#![feature(alloc, collections)]
|
#![feature(alloc, collections)]
|
||||||
|
#![feature(asm)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate rlibc;
|
extern crate rlibc;
|
||||||
@@ -29,6 +30,7 @@ extern crate collections;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod vga_buffer;
|
mod vga_buffer;
|
||||||
mod memory;
|
mod memory;
|
||||||
|
mod interrupts;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main(multiboot_information_address: usize) {
|
pub extern "C" fn rust_main(multiboot_information_address: usize) {
|
||||||
@@ -50,6 +52,14 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
|
|||||||
format!("Some String");
|
format!("Some String");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interrupts::init();
|
||||||
|
|
||||||
|
unsafe { *(0xdeadbeaf as *mut u32) = 42};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
asm!("xor eax, eax; idiv eax" :::: "intel");
|
||||||
|
}
|
||||||
|
|
||||||
println!("It did not crash!");
|
println!("It did not crash!");
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
|
|||||||
Reference in New Issue
Block a user