Introduce boot.mgr - a self-registering, dependency-ordered boot initialization framework with barrier-based phasing and glob pattern matching. Units now declare their own init procedures and dependencies via registerBoot()/registerBarrier() in their initialization sections, boot.mgr.run() topologically sorts and executes them. - Add src/boot/boot.mgr.pas with topoSort, glob matching, barrier two-pass algorithm, and boot tree printer - Gut src/asuro.pas (kmain): now just stores multiboot info, calls System.init(), boot.mgr.run, and yield() - Add initialization sections with registerBoot() to 53 existing units - Add new units: core.pas, test.pas, driver.storage.boot.pas, app.wasm.pas, app.bsod.pas (factored out of asuro.pas) - Define 9 barrier phases: immediate -> early -> middle -> storage -> bus -> device -> bus.late -> late -> final - Fix xHCI ISR: exclude PRC/WRC from PORTSC change bit clearing to prevent race with port reset busy-wait - Fix driver.bus.usb.core fire_completion_hooks: guard against uint32 underflow when CompletionHookCount = 0 - Move auto_mount_volumes from device barrier to late barrier so it runs after PCI scan discovers storage controllers - Add toolchain/compile_initcalls.sh for boot entry extraction - Add Boot Registration sections to all 51 doc files; create 4 new doc files; rewrite boot.mgr.md; update mkdocs.yml nav
3.4 KiB
arch.x86.idt
Interrupt Descriptor Table (IDT) data structures, gate registration, and loading.
Overview
This unit defines the 256-entry IDT used by the x86 interrupt system. It provides constants for the four privilege-level gate flag bytes, a procedure to install individual interrupt gates, and an init routine that clears the table and loads it into the CPU via LIDT. Each call to set_gate immediately reloads the IDT so that the new handler is active as soon as the procedure returns.
Dependencies
core.utilarch.x86.utilio.syslog
Boot Registration
Registered with boot.mgr as arch.x86.idt, depending on arch.x86.gdt.
Constants
ISR_RING_0
$8E — Gate flags for a ring-0 interrupt gate (present, DPL 0, 32-bit interrupt gate type).
ISR_RING_1
$AE — Gate flags for a ring-1 interrupt gate (present, DPL 1, 32-bit interrupt gate type).
ISR_RING_2
$CE — Gate flags for a ring-2 interrupt gate (present, DPL 2, 32-bit interrupt gate type).
ISR_RING_3
$EE — Gate flags for a ring-3 interrupt gate (present, DPL 3, 32-bit interrupt gate type).
Types
TIDT_Entry / PIDT_Entry
TIDT_Entry = packed record
base_low : uint16;
selector : uint16;
always_0 : uint8;
flags : uint8;
base_high : uint16;
end;
An 8-byte x86 interrupt gate descriptor in the hardware layout.
| Field | Description |
|---|---|
| base_low | Lower 16 bits of the handler entry-point address |
| selector | Code segment selector for the handler |
| always_0 | Reserved byte, must be zero |
| flags | Gate type and privilege flags (use ISR_RING_* constants) |
| base_high | Upper 16 bits of the handler entry-point address |
TIDT_Pointer / PIDT_Pointer
TIDT_Pointer = packed record
limit : uint16;
base : uint32;
end;
The 6-byte operand passed to LIDT. limit is always (sizeof(TIDT_Entry) * 256) - 1; base is the linear address of IDT_Entries.
Variables
IDT_Entries
var IDT_Entries : Array [0..255] of TIDT_Entry;
Static array of 256 interrupt gate descriptors.
IDT_Pointer
var IDT_Pointer : TIDT_Pointer;
The LIDT operand, initialised during init.
Functions and Procedures
init
procedure init();
Sets up IDT_Pointer, zeroes the entire IDT_Entries array using core.util.memset, and loads the IDT via LIDT. Must be called before any interrupt gates are installed.
set_gate
procedure set_gate(Number : uint8; Base : uint32; Selector : uint16; Flags : uint8);
Installs an interrupt gate at index Number. Splits Base into base_low and base_high, sets the code segment Selector (typically $08 for the ring-0 code segment), writes the Flags byte, and zeroes always_0. Calls LIDT immediately after writing so the gate is live.
Parameters:
Number— IDT vector number (0–255).Base— Linear address of the ISR entry point.Selector— GDT code segment selector used when the handler is invoked.Flags— Gate type and DPL flags; use one of theISR_RING_*constants.
Notes
- The IDT is reloaded after every
set_gatecall. This is safe but slightly inefficient when installing many gates in sequence. - Vectors 0–31 are reserved for CPU exceptions; vectors 32–255 are available for hardware IRQs and software interrupts.