Protected mode on i386 requires a valid Global Descriptor Table (GDT) before the CPU can execute code reliably, and a populated Interrupt Descriptor Table (IDT) before any interrupt or exception can be handled without a triple fault. CrisOS v2 initializes the GDT, IDT, and 8259 Programmable Interrupt Controller (PIC) as three of the first actions inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CRISTOP-bot/cris-os-v2/llms.txt
Use this file to discover all available pages before exploring further.
kmain, in that exact order, ensuring that exceptions are caught and hardware interrupts are controllable before any driver or subsystem is started.
GDT — Global Descriptor Table
Purpose
The GDT defines memory segments for the CPU. CrisOS v2 uses a flat memory model: all segments span the full 4 GB address space (base = 0, limit = 0xFFFFF with 4 KB granularity), so segmentation is effectively bypassed and all protection is done by the segment type and privilege level fields.
Header
Implementation
gdt_init() populates five GDT entries and calls gdt_load() to install them:
gdt_load() is implemented in assembly (src/asm_utils.S). It receives the address of the gdt_ptr_t structure, executes lgdt, reloads all data segment registers with selector 0x10 (entry 2 — ring-0 data), and performs a far jump to selector 0x08 (entry 1 — ring-0 code) to flush the instruction pipeline:
| Selector | Index | Privilege | Type | Description |
|---|---|---|---|---|
0x00 | 0 | — | Null | Required null descriptor |
0x08 | 1 | Ring 0 | Code | Kernel executable segment |
0x10 | 2 | Ring 0 | Data | Kernel read/write segment |
0x18 | 3 | Ring 3 | Code | User executable segment |
0x20 | 4 | Ring 3 | Data | User read/write segment |
IDT — Interrupt Descriptor Table
Header
Implementation
idt_init() registers 32 CPU exception handlers (isr0–isr31) and 16 hardware IRQ handlers (irq0–irq15) into the 256-entry IDT table, using code segment selector 0x08 and interrupt-gate flags 0x8E:
isr_no_err and isr_err macros in src/asm_utils.S. Each stub pushes a dummy error code (for exceptions that do not generate one) and the interrupt number, then jumps to a common stub that saves all registers and calls the C exception_handler():
irq_handler() through irq_common_stub.
IRQ Dispatch
The Cirq_handler() demultiplexes incoming IRQs by number and calls the appropriate driver handler:
PIC — 8259 Programmable Interrupt Controller
Why Remapping Is Necessary
On reset the 8259 PIC maps IRQs 0–7 to CPU interrupt vectors0x08–0x0F and IRQs 8–15 to 0x70–0x77. Vectors 0x00–0x1F are reserved for CPU exceptions in protected mode, so those default IRQ vectors would collide with exception handlers. pic_init() remaps both PICs before any IRQ can fire.
Header
pic_init() — Remapping Sequence
| IRQ Range | CPU Vector Range | Source |
|---|---|---|
| IRQ 0–7 | 0x20–0x27 | Master PIC (timer, keyboard, …) |
| IRQ 8–15 | 0x28–0x2F | Slave PIC (RTC, mouse, …) |
IRQ Masking
pic_mask() writes directly to the PIC data ports. A 1 bit masks (disables) the corresponding IRQ; a 0 bit enables it.
pic_mask twice during initialization:
After pic_init() — keyboard only
0xFD = 11111101b — only bit 1 (IRQ1, keyboard) is cleared (enabled). All other master IRQs and all slave IRQs (0xFF) are masked. This minimal mask is safe before the mouse driver is ready.PIT Timer — timer_init(100)
The 8253/8254 Programmable Interval Timer is configured by timer_init() in drivers/timer.c:
1 193 180 Hz. To achieve a target frequency the divisor is:
0x36 selects channel 0, access mode “lobyte/hibyte”, operating mode 3 (square wave), and binary counting. Each time the counter reaches zero it fires IRQ0, which irq_handler() routes to timer_handler(), incrementing the global timer_ticks counter.
CrisOS v2 operates in polling mode for most input. Keyboard interrupts are enabled (IRQ1 is unmasked), but the shell’s
keyboard_readline function spins waiting for the interrupt flag rather than using an interrupt-driven ring buffer. This means CPU time is consumed while waiting for user input, which is acceptable for a single-tasking educational kernel.