dev #4
Generated
+7
@@ -38,6 +38,7 @@ dependencies = [
|
|||||||
"lib_framebuffer",
|
"lib_framebuffer",
|
||||||
"lib_serial",
|
"lib_serial",
|
||||||
"limine",
|
"limine",
|
||||||
|
"pc-keyboard",
|
||||||
"pic8259",
|
"pic8259",
|
||||||
"spin",
|
"spin",
|
||||||
"x86_64",
|
"x86_64",
|
||||||
@@ -105,6 +106,12 @@ dependencies = [
|
|||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pc-keyboard"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0ca629cbb3f0d5b699c338f0129ff78c9bfd7ea8b1258ad529bff490dc8ed5a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pic8259"
|
name = "pic8259"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ lib_ascii = { path = "../lib/lib_ascii" }
|
|||||||
x86_64 = "0.15.2"
|
x86_64 = "0.15.2"
|
||||||
spin = "0.9.8"
|
spin = "0.9.8"
|
||||||
pic8259 = "0.11.0"
|
pic8259 = "0.11.0"
|
||||||
|
pc-keyboard = "0.8.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.2.14"
|
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;
|
use spin::Lazy;
|
||||||
|
|
||||||
@@ -16,3 +24,46 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
|||||||
};
|
};
|
||||||
tss
|
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 lib_serial::serial_println;
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
@@ -6,10 +6,18 @@ use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
|||||||
use pic8259::ChainedPics;
|
use pic8259::ChainedPics;
|
||||||
use spin::{Lazy, Mutex};
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
|
use super::gdt;
|
||||||
|
|
||||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
||||||
let mut idt = InterruptDescriptorTable::new();
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
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
|
idt.general_protection_fault
|
||||||
.set_handler_fn(general_protection_fault_handler);
|
.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) {
|
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 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 {
|
unsafe {
|
||||||
PICS.lock()
|
PICS.lock()
|
||||||
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ pub fn boot() -> Result<(), &'static str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lib_serial::init()?;
|
lib_serial::init()?;
|
||||||
|
arch::x86_64::gdt::init();
|
||||||
arch::x86_64::interrupts::init_idt();
|
arch::x86_64::interrupts::init_idt();
|
||||||
|
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
|
|||||||
Reference in New Issue
Block a user