Files
Asuro/doc/src/arch/x86/arch.x86.gdt.md
T
t3hn3rd 2d190c221a feature: boot.mgr replace hardcoded init sequence with dependency-driven boot manager
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
2026-03-13 15:37:43 +00:00

119 lines
3.6 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.
# arch.x86.gdt
Global Descriptor Table (GDT) data structures, gate management, and loading.
## Overview
This unit defines the GDT data structures and provides procedures to set individual segment descriptors, flush the GDT into the CPU via LGDT, and reload it after modification. During `init`, five standard descriptors are installed: a null segment, a ring-0 code segment, a ring-0 data segment, a ring-3 code segment, and a ring-3 data segment. The GDT can hold up to 1024 entries; the GDT pointer limit is updated automatically as new gates are added.
## Dependencies
- `io.syslog`
## Boot Registration
Registered with `boot.mgr` as `arch.x86.gdt` at the `early` barrier.
## Types
### TGDT_Entry / PGDT_Entry
```pascal
TGDT_Entry = packed record
limit_low : uint16;
base_low : uint16;
base_middle : uint8;
access : uint8;
granularity : uint8;
base_high : uint8;
end;
```
An 8-byte x86 segment descriptor in the standard hardware layout.
| Field | Description |
|--------------|-------------|
| limit_low | Lower 16 bits of the segment limit |
| base_low | Lower 16 bits of the segment base address |
| base_middle | Bits 16–23 of the segment base address |
| access | Access byte: present, DPL, type flags |
| granularity | Upper 4 bits of limit plus granularity/size flags |
| base_high | Bits 24–31 of the segment base address |
### TGDT_Pointer
```pascal
TGDT_Pointer = packed record
limit : uint16;
base : uint32;
end;
```
The 6-byte structure passed to the LGDT instruction. `limit` is the byte size of the GDT minus one; `base` is the linear address of the first GDT entry.
## Variables
### gdt_entries
```pascal
var gdt_entries : array[0..1023] of TGDT_Entry;
```
Static array holding up to 1024 GDT descriptors.
### gdt_pointer
```pascal
var gdt_pointer : TGDT_Pointer;
```
The LGDT operand. `base` is set to the address of `gdt_entries`; `limit` grows as gates are added.
## Functions and Procedures
### init
```pascal
procedure init();
```
Initialises the GDT with five standard entries and calls `flush` to load it:
| Gate | Offset | Access | Description |
|------|--------|--------|-------------|
| 0 | 0x00 | 0x00 | Null descriptor |
| 1 | 0x08 | 0x9A | Ring-0 code (execute/read, 4 GB flat) |
| 2 | 0x10 | 0x92 | Ring-0 data (read/write, 4 GB flat) |
| 3 | 0x18 | 0xFA | Ring-3 code (execute/read, 4 GB flat) |
| 4 | 0x20 | 0xF2 | Ring-3 data (read/write, 4 GB flat) |
### set_gate
```pascal
procedure set_gate(Gate_Number : uint32; Base : uint32; Limit : uint32; Access : uint8; Granularity : uint8);
```
Writes a single GDT descriptor at index `Gate_Number`. Splits `Base` and `Limit` across the appropriate fields of the `TGDT_Entry` record. Automatically updates `gdt_pointer.limit` if the new gate extends beyond the current table boundary.
### flush
```pascal
procedure flush;
```
Loads the GDT via LGDT and reloads all data segment registers (DS, ES, FS, GS, SS) with selector 0x10 (ring-0 data). A far jump to selector 0x08 (ring-0 code) flushes the instruction pipeline and reloads CS.
### reload
```pascal
procedure reload;
```
Reissues LGDT without touching segment registers. Used after adding descriptors such as a TSS when the existing segment mappings remain valid.
## Notes
- The far jump in `flush_gdt` is hand-assembled using `db`/`dw` directives because the Free Pascal inline assembler does not support far-jump syntax directly.
- Gates are numbered from 0; the segment selector for gate N is N * 8 with the lower 3 bits encoding the requested privilege level.
- The table supports up to 1024 descriptors (8 KiB), which is the hardware maximum for a 32-bit protected-mode GDT.