mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Create interrupt module with IDT submodule
This commit is contained in:
@@ -4,10 +4,11 @@ name = "blog_os"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bit_field = "0.1.0"
|
||||
bitflags = "0.7.0"
|
||||
once = "0.2.1"
|
||||
rlibc = "0.1.4"
|
||||
spin = "0.3.4"
|
||||
bitflags = "0.7.0"
|
||||
|
||||
[dependencies.hole_list_allocator]
|
||||
path = "libs/hole_list_allocator"
|
||||
@@ -17,7 +18,7 @@ git = "https://github.com/phil-opp/multiboot2-elf64"
|
||||
|
||||
[dependencies.x86]
|
||||
default-features = false
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
103
src/interrupts/idt.rs
Normal file
103
src/interrupts/idt.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
use x86::segmentation::{self, SegmentSelector};
|
||||
|
||||
pub struct Idt([Entry; 16]);
|
||||
|
||||
impl Idt {
|
||||
pub fn new() -> Idt {
|
||||
Idt([Entry::missing(); 16])
|
||||
}
|
||||
|
||||
pub fn set_handler(&mut self, entry: u8, handler: HandlerFunc) -> &mut EntryOptions {
|
||||
self.0[entry as usize] = Entry::new(segmentation::cs(), handler);
|
||||
&mut self.0[entry as usize].options
|
||||
}
|
||||
|
||||
pub fn load(&'static 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,
|
||||
};
|
||||
|
||||
unsafe { lidt(&ptr) };
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C, packed)]
|
||||
pub struct Entry {
|
||||
pointer_low: u16,
|
||||
gdt_selector: SegmentSelector,
|
||||
options: EntryOptions,
|
||||
pointer_middle: u16,
|
||||
pointer_high: u32,
|
||||
reserved: u32,
|
||||
}
|
||||
|
||||
type HandlerFunc = extern "C" fn() -> !;
|
||||
|
||||
impl Entry {
|
||||
fn new(gdt_selector: SegmentSelector, handler: HandlerFunc) -> Self {
|
||||
let pointer = handler as u64;
|
||||
Entry {
|
||||
gdt_selector: gdt_selector,
|
||||
pointer_low: pointer as u16,
|
||||
pointer_middle: (pointer >> 16) as u16,
|
||||
pointer_high: (pointer >> 32) as u32,
|
||||
options: EntryOptions::new(),
|
||||
reserved: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn missing() -> Self {
|
||||
Entry {
|
||||
gdt_selector: SegmentSelector::new(0),
|
||||
pointer_low: 0,
|
||||
pointer_middle: 0,
|
||||
pointer_high: 0,
|
||||
options: EntryOptions::minimal(),
|
||||
reserved: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use bit_field::BitField;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct EntryOptions(BitField<u16>);
|
||||
|
||||
impl EntryOptions {
|
||||
fn minimal() -> Self {
|
||||
let mut options = BitField::new(0);
|
||||
options.set_range(9..12, 0b111); // 'must-be-one' bits
|
||||
EntryOptions(options)
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
let mut options = Self::minimal();
|
||||
options.set_present(true).disable_interrupts(true);
|
||||
options
|
||||
}
|
||||
|
||||
fn set_present(&mut self, present: bool) -> &mut Self {
|
||||
self.0.set_bit(15, present);
|
||||
self
|
||||
}
|
||||
|
||||
fn disable_interrupts(&mut self, disable: bool) -> &mut Self {
|
||||
self.0.set_bit(8, !disable);
|
||||
self
|
||||
}
|
||||
|
||||
fn set_privilege_level(&mut self, dpl: u16) -> &mut Self {
|
||||
self.0.set_range(13..15, dpl);
|
||||
self
|
||||
}
|
||||
|
||||
fn set_stack_index(&mut self, index: u16) -> &mut Self {
|
||||
self.0.set_range(0..3, index);
|
||||
self
|
||||
}
|
||||
}
|
||||
1
src/interrupts/mod.rs
Normal file
1
src/interrupts/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
mod idt;
|
||||
@@ -20,6 +20,7 @@ extern crate bitflags;
|
||||
extern crate x86;
|
||||
#[macro_use]
|
||||
extern crate once;
|
||||
extern crate bit_field;
|
||||
|
||||
extern crate hole_list_allocator;
|
||||
extern crate alloc;
|
||||
@@ -30,6 +31,8 @@ extern crate collections;
|
||||
mod vga_buffer;
|
||||
mod memory;
|
||||
|
||||
mod interrupts;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_main(multiboot_information_address: usize) {
|
||||
// ATTENTION: we have a very small stack and no guard page
|
||||
|
||||
Reference in New Issue
Block a user