Skip to content

Commit 47634de

Browse files
committed
feat(interrupts): 实现IRQ请求机制并注册键盘和定时器中断处理程序
1 parent 3e9bfe5 commit 47634de

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

kernel/src/interrupts/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,21 @@ pub mod gdt;
33
pub mod handler;
44
pub mod idt;
55
pub mod pic;
6+
7+
use crate::interrupts::apic::registry::{IrqHandler, IRQ_REGISTRY};
8+
use crate::interrupts::idt::IRQ_BASE;
9+
10+
/// Request an IRQ and register its handler.
11+
/// This handles both I/O APIC routing and software registry.
12+
pub fn request_irq(irq_num: u8, name: &'static str, handler: IrqHandler) {
13+
let vector = IRQ_BASE + irq_num;
14+
15+
// 1. Route hardware IRQ to vector
16+
apic::ioapic::route_irq(irq_num, vector, 0);
17+
18+
// 2. Register software handler
19+
IRQ_REGISTRY
20+
.lock()
21+
.register(vector, name, handler)
22+
.expect("Failed to register IRQ handler");
23+
}

kernel/src/libs/shell.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ impl Shell {
110110
}
111111
}
112112
Ok(_) => {
113-
// No data, pause CPU until interrupt
114113
x86_64::instructions::hlt();
115114
}
116115
Err(_) => {

kernel/src/main.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,32 @@ pub extern "C" fn kernel_main() -> ! {
4242
proka_kernel::interrupts::apic::init();
4343
proka_kernel::interrupts::apic::ioapic::init();
4444

45-
// Route Keyboard IRQ
46-
proka_kernel::interrupts::apic::ioapic::route_irq(
47-
1,
48-
proka_kernel::interrupts::idt::IRQ_BASE + 1,
49-
0,
50-
);
51-
52-
// Register Keyboard Handler via Registry
45+
// Register Keyboard Handler (Simplified)
46+
proka_kernel::interrupts::request_irq(1, "Keyboard", |_context| {
47+
let mut port = x86_64::instructions::port::Port::<u8>::new(0x60);
48+
let scancode = unsafe { port.read() };
49+
proka_kernel::drivers::input::keyboard::KEYBOARD.handle_scancode(scancode);
50+
proka_kernel::interrupts::apic::registry::IrqResult::Handled
51+
});
52+
53+
// Register Timer Handler via Registry
5354
proka_kernel::interrupts::apic::registry::IRQ_REGISTRY
5455
.lock()
5556
.register(
56-
proka_kernel::interrupts::idt::IRQ_BASE + 1,
57-
"Keyboard",
57+
proka_kernel::interrupts::apic::TIMER_VECTOR,
58+
"Timer",
5859
|_context| {
59-
let mut port = x86_64::instructions::port::Port::<u8>::new(0x60);
60-
let scancode = unsafe { port.read() };
61-
proka_kernel::drivers::input::keyboard::KEYBOARD.handle_scancode(scancode);
60+
use core::sync::atomic::{AtomicU64, Ordering};
61+
static TICKS: AtomicU64 = AtomicU64::new(0);
62+
let t = TICKS.fetch_add(1, Ordering::Relaxed);
63+
if t > 0 && t % 100 == 0 {
64+
println!("System Tick: {}s", t / 100);
65+
}
66+
6267
proka_kernel::interrupts::apic::registry::IrqResult::Handled
6368
},
6469
)
65-
.expect("Failed to register keyboard handler");
70+
.expect("Failed to register timer handler");
6671

6772
proka_kernel::drivers::init_devices(); // Initialize devices
6873
proka_kernel::libs::time::init(); // Init time system
@@ -100,7 +105,9 @@ pub extern "C" fn kernel_main() -> ! {
100105

101106
let time = proka_kernel::libs::time::time_since_boot();
102107
println!("Time since boot: {time}");
103-
CONSOLE.lock().cursor_show();
108+
x86_64::instructions::interrupts::without_interrupts(|| {
109+
CONSOLE.lock().cursor_show();
110+
});
104111

105112
let shell = proka_kernel::libs::shell::Shell::new();
106113
shell.run("keyboard");

kernel/src/output/console/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ lazy_static! {
8383

8484
#[doc(hidden)]
8585
pub fn _print(args: fmt::Arguments) {
86-
CONSOLE
87-
.lock()
88-
.write_fmt(args)
89-
.expect("Failed to write to console");
86+
x86_64::instructions::interrupts::without_interrupts(|| {
87+
CONSOLE
88+
.lock()
89+
.write_fmt(args)
90+
.expect("Failed to write to console");
91+
});
9092
}
9193

9294
pub enum ConsoleType {

0 commit comments

Comments
 (0)