Files
claude-os/docs/interrupts.md
AI f2e7d6c5d7 Fix PMM: switch to Multiboot2 boot protocol and add documentation (AI)
- Changed grub.cfg from 'multiboot' to 'multiboot2' command. The PMM parses
  Multiboot2 tag structures, but GRUB was booting with Multiboot1 protocol,
  causing the memory map parsing to silently fail (all memory stayed marked
  as used, leading to OOM on every allocation).
- Fixed BITMAP_SIZE calculation to properly round up instead of truncating,
  ensuring the last few pages of the address space are covered.
- Fixed sign comparison warning in bitmap init loop.
- Added debug output to PMM init (mem_upper, region count) for diagnostics.
- Removed stale Multiboot1 magic constant and (void)addr cast from kernel.c.
- Added documentation for the interrupt subsystem and PMM in docs/.
- Checked off 'Implement a PIC handler' and 'Create a physical memory
  allocator' in the task list.

Tested: kernel boots in QEMU with both 4MB and 128MB RAM, PMM correctly
allocates from NORMAL zone (0x01000000) and DMA zone (0x00001000).
2026-02-23 10:57:56 +00:00

63 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Interrupt Subsystem
## Overview
The interrupt subsystem handles both CPU exceptions (faults, traps, aborts) and hardware interrupts (IRQs) from external devices. It consists of three cooperating components:
1. **IDT (Interrupt Descriptor Table)** — Maps interrupt vectors 0255 to handler entry points.
2. **ISR (Interrupt Service Routines)** — Assembly stubs and a C dispatcher that routes interrupts.
3. **PIC (Programmable Interrupt Controller)** — Manages the 8259A PIC chips that multiplex hardware IRQs onto CPU interrupt lines.
## Architecture
### Interrupt Vector Layout
| Vector Range | Purpose |
|---|---|
| 031 | CPU exceptions (Division by Zero, Page Fault, GPF, etc.) |
| 3247 | Hardware IRQs (remapped from default 015) |
| 48255 | Available for software interrupts / future use |
### Flow of an Interrupt
1. CPU or device raises an interrupt.
2. CPU looks up the vector in the IDT and jumps to the assembly stub.
3. The stub pushes a dummy error code (if the CPU didn't push one), the interrupt number, and all general-purpose registers onto the stack.
4. The stub loads the kernel data segment (0x10) and calls `isr_handler()` in C.
5. For hardware interrupts (vectors 3247), `isr_handler` sends an End-of-Interrupt (EOI) to the PIC.
6. For CPU exceptions (vectors 031), the handler prints the exception name and halts.
7. On return, the stub restores all registers and executes `iret`.
### PIC Remapping
The 8259A PIC ships with IRQ 07 mapped to vectors 815, which collide with CPU exceptions. During initialization, we remap:
- **Master PIC** (IRQ 07) → vectors 3239
- **Slave PIC** (IRQ 815) → vectors 4047
The PIC is initialized in cascade mode with ICW4 (8086 mode). Original IRQ masks are saved and restored after remapping.
## Key Files
- `src/idt.c` / `src/idt.h` — IDT setup and gate registration.
- `src/interrupts.S` — Assembly stubs for ISRs 031 and IRQs 015.
- `src/isr.c` / `src/isr.h` — C interrupt dispatcher and `registers_t` structure.
- `src/pic.c` / `src/pic.h` — PIC initialization, EOI, mask/unmask.
- `src/port_io.h` — Inline `inb`, `outb`, `io_wait` helpers.
## Register Save Frame
When an interrupt fires, the following is pushed onto the stack (from high to low address):
```
ss, useresp (only on privilege change)
eflags
cs, eip (pushed by CPU)
err_code (pushed by CPU or stub as 0)
int_no (pushed by stub)
eax..edi (pushed by pusha)
ds (pushed by stub)
```
This matches the `registers_t` struct in `isr.h`.