forked from LowLevelDevs/FoundryOS
setup GDT & fixed a deadlock
This commit is contained in:
Generated
+7
@@ -38,6 +38,7 @@ dependencies = [
|
||||
"lib_framebuffer",
|
||||
"lib_serial",
|
||||
"limine",
|
||||
"pc-keyboard",
|
||||
"pic8259",
|
||||
"spin",
|
||||
"x86_64",
|
||||
@@ -105,6 +106,12 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pc-keyboard"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0ca629cbb3f0d5b699c338f0129ff78c9bfd7ea8b1258ad529bff490dc8ed5a"
|
||||
|
||||
[[package]]
|
||||
name = "pic8259"
|
||||
version = "0.11.0"
|
||||
|
||||
@@ -11,6 +11,7 @@ lib_ascii = { path = "../lib/lib_ascii" }
|
||||
x86_64 = "0.15.2"
|
||||
spin = "0.9.8"
|
||||
pic8259 = "0.11.0"
|
||||
pc-keyboard = "0.8.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.2.14"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
use x86_64::{structures::tss::TaskStateSegment, VirtAddr};
|
||||
use x86_64::{
|
||||
instructions::tables::load_tss,
|
||||
registers::segmentation::{Segment, CS, DS, ES, SS},
|
||||
structures::{
|
||||
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
|
||||
tss::TaskStateSegment,
|
||||
},
|
||||
VirtAddr,
|
||||
};
|
||||
|
||||
use spin::Lazy;
|
||||
|
||||
@@ -16,3 +24,46 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
||||
};
|
||||
tss
|
||||
});
|
||||
|
||||
static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
|
||||
let mut gdt = GlobalDescriptorTable::new();
|
||||
let code_selector = gdt.append(Descriptor::kernel_code_segment());
|
||||
let data_selector = gdt.append(Descriptor::kernel_data_segment());
|
||||
|
||||
let user_code_selector = gdt.append(Descriptor::user_code_segment());
|
||||
let user_data_selector = gdt.append(Descriptor::user_data_segment());
|
||||
|
||||
let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
|
||||
|
||||
(
|
||||
gdt,
|
||||
Selectors {
|
||||
code_selector,
|
||||
data_selector,
|
||||
user_code_selector,
|
||||
user_data_selector,
|
||||
tss_selector,
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
struct Selectors {
|
||||
code_selector: SegmentSelector,
|
||||
data_selector: SegmentSelector,
|
||||
user_code_selector: SegmentSelector,
|
||||
user_data_selector: SegmentSelector,
|
||||
tss_selector: SegmentSelector,
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
GDT.0.load();
|
||||
|
||||
unsafe {
|
||||
CS::set_reg(GDT.1.code_selector);
|
||||
load_tss(GDT.1.tss_selector);
|
||||
|
||||
DS::set_reg(self::GDT.1.data_selector);
|
||||
ES::set_reg(self::GDT.1.data_selector);
|
||||
SS::set_reg(self::GDT.1.data_selector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use lib_ascii::println_log;
|
||||
use lib_ascii::{print, println_log};
|
||||
use lib_serial::serial_println;
|
||||
use x86_64::instructions::port::Port;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
@@ -6,10 +6,18 @@ use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
use pic8259::ChainedPics;
|
||||
use spin::{Lazy, Mutex};
|
||||
|
||||
use super::gdt;
|
||||
|
||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
||||
let mut idt = InterruptDescriptorTable::new();
|
||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
idt.double_fault.set_handler_fn(double_fault_handler);
|
||||
|
||||
unsafe {
|
||||
idt.double_fault
|
||||
.set_handler_fn(double_fault_handler)
|
||||
.set_stack_index(gdt::DOUBLE_FAULT_1ST_INDEX);
|
||||
}
|
||||
|
||||
idt.general_protection_fault
|
||||
.set_handler_fn(general_protection_fault_handler);
|
||||
|
||||
@@ -71,8 +79,31 @@ extern "x86-interrupt" fn double_fault_handler(
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
static KEYBOARD: Lazy<Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>>> = Lazy::new(|| {
|
||||
Mutex::new(Keyboard::new(
|
||||
ScancodeSet1::new(),
|
||||
layouts::Us104Key,
|
||||
HandleControl::Ignore,
|
||||
))
|
||||
});
|
||||
|
||||
let mut keyboard = KEYBOARD.lock();
|
||||
let mut port = Port::new(0x60);
|
||||
let _scancode: u8 = unsafe { port.read() };
|
||||
|
||||
let scancode: u8 = unsafe { port.read() };
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||
match key {
|
||||
DecodedKey::Unicode(character) => print!("{}", character),
|
||||
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
PICS.lock()
|
||||
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||
|
||||
@@ -53,6 +53,7 @@ pub fn boot() -> Result<(), &'static str> {
|
||||
}
|
||||
|
||||
lib_serial::init()?;
|
||||
arch::x86_64::gdt::init();
|
||||
arch::x86_64::interrupts::init_idt();
|
||||
|
||||
x86_64::instructions::interrupts::enable();
|
||||
|
||||
Reference in New Issue
Block a user