feat: docs & ARCH 2.2, 2.3, 2.4
This commit is contained in:
115
kernel/docs/cpu/idt.md
Normal file
115
kernel/docs/cpu/idt.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Interrupt Descriptor Table: `idt.rs`
|
||||
|
||||
## Аппаратная модель
|
||||
|
||||
IDT (Interrupt Descriptor Table) — это таблица из 256 entry (по 16 байт каждая),
|
||||
которая сообщает CPU, куда передавать управление при прерываниях и исключениях.
|
||||
|
||||
```
|
||||
IDT:
|
||||
┌──────┬──────────────────────────────────────────────────────┐
|
||||
│ 0 │ #DE — Divide Error │
|
||||
│ 1 │ #DB — Debug │
|
||||
│ 2 │ #NMI — Non-Maskable Interrupt │
|
||||
│ 3 │ #BP — Breakpoint │
|
||||
│ 4 │ #OF — Overflow │
|
||||
│ 5 │ #BR — Bound Range Exceeded │
|
||||
│ 6 │ #UD — Undefined Opcode │
|
||||
│ 7 │ #NM — Device Not Available │
|
||||
│ 8 │ #DF — Double Fault │
|
||||
│ 9 │ #MF — Coprocessor Segment Overrun │
|
||||
│ 10 │ #TS — Invalid TSS │
|
||||
│ 11 │ #NP — Segment Not Present │
|
||||
│ 12 │ #SS — Stack-Segment Fault │
|
||||
│ 13 │ #GP — General Protection Fault │
|
||||
│ 14 │ #PF — Page Fault │
|
||||
│ 15-31│ Reserved / CPU exceptions │
|
||||
│ 32-255│ User-defined (hardware interrupts) │
|
||||
└──────┴──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Загрузка IDT: инструкция `lidt [idtr_ptr]`, где `idtr_ptr` — это
|
||||
6-байтовая структура `IdtPtr`:
|
||||
```
|
||||
IdtPtr:
|
||||
┌──────────┬──────────┐
|
||||
│ limit:16 │ base:48 │
|
||||
└──────────┴──────────┘
|
||||
```
|
||||
|
||||
## IdtEntry — 16-байтовая запись
|
||||
|
||||
```rust
|
||||
#[repr(C, packed)]
|
||||
pub struct IdtEntry {
|
||||
offset_low: u16, // Бит 0:15 адреса обработчика
|
||||
selector: u16, // Селектор сегмента кода (0x28 для ядра)
|
||||
ist: u8, // Interrupt Stack Table
|
||||
type_attr: u8, // Тип вентиля + флаги
|
||||
offset_mid: u16, // Бит 16:31 адреса обработчика
|
||||
offset_high: u32, // Бит 32:63 адреса обработчика
|
||||
ignore: u32, // Зарезервировано
|
||||
}
|
||||
```
|
||||
|
||||
**type_attr:**
|
||||
- Бит 7: Present (должен быть 1)
|
||||
- Бит 6-5: DPL (Descriptor Privilege Level)
|
||||
- Бит 4: Reserved (0)
|
||||
- Бит 3-0: Gate Type (0xE = Interrupt Gate, 0xF = Trap Gate)
|
||||
|
||||
`set_handler(handler, selector, flags)`:
|
||||
```rust
|
||||
pub fn set_handler(&mut self, handler: u64, selector: u16, flags: u8) {
|
||||
self.offset_low = handler as u16;
|
||||
self.selector = selector;
|
||||
self.ist = 0;
|
||||
self.type_attr = flags | 0x80; // Present bit forced on
|
||||
self.offset_mid = (handler >> 16) as u16;
|
||||
self.offset_high = (handler >> 32) as u32;
|
||||
}
|
||||
```
|
||||
|
||||
## InterruptDescriptorTable — 256 entry
|
||||
|
||||
```rust
|
||||
pub struct InterruptDescriptorTable {
|
||||
entries: [IdtEntry; 256], // 256 × 16 = 4096 байт
|
||||
}
|
||||
```
|
||||
|
||||
**Методы:**
|
||||
- `set_handler(vector, handler)` — устанавливает обработчик с
|
||||
селектором 0x28 (GDT code segment) и type_attr 0x8E
|
||||
(Interrupt Gate, Ring 0, Present).
|
||||
- `load()` — `lidt` инструкция.
|
||||
|
||||
```rust
|
||||
pub unsafe fn load(&'static self) {
|
||||
let ptr = IdtPtr {
|
||||
limit: (size_of::<Self>() - 1) as u16, // 4095
|
||||
base: self as *const _ as u64,
|
||||
};
|
||||
asm!("lidt [{}]", in(reg) &ptr);
|
||||
}
|
||||
```
|
||||
|
||||
## Глобальная IDT
|
||||
|
||||
```rust
|
||||
pub static mut IDT: InterruptDescriptorTable = InterruptDescriptorTable::new();
|
||||
```
|
||||
|
||||
`static mut` — потому что IDT модифицируется в ранней инициализации,
|
||||
до включения прерываний. Потенциально может быть заменён на `static`
|
||||
с `UnsafeCell`.
|
||||
|
||||
## Детали конфигурации
|
||||
|
||||
- **Selector**: `0x28` — это GDT entry для ring 0 code segment
|
||||
(дескриптор 5, 5 × 8 = 0x28). Селектор сегмента кода в long mode.
|
||||
- **Type 0x8E**: `1000_1110` = бит 7 (Present) + бит 3:0 = 1110
|
||||
(Interrupt Gate, 32-bit). В 64-bit режиме все вентили — 64-bit,
|
||||
флаг 0xE остаётся корректным.
|
||||
- **IST**: 0 — не используем Interrupt Stack Table (один стек для
|
||||
всех обработчиков).
|
||||
Reference in New Issue
Block a user