summaryrefslogtreecommitdiffstats
path: root/CONTEXT.md
blob: 00749699c4d4336738b790668380a9c91112d293 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# CONTEXT.md — raisernics Kernel Glossary

## raisernics

Custom x86_64 kernel for the RNG ecosystem.  Toy project — self-contained,
no strict userspace separation, TempleOS-inspired design philosophy.
Built in Rust, compiled for the `x86_64-unknown-uefi` target (nightly).

## Boot interface

The kernel is a **PE32+ EFI application** loaded via UEFI `LoadImage`/`StartImage`.
The existing bootloader (rsbl) loads us from `\bzImage` and passes the UEFI
system table.  No bootloader changes needed.

## Output strategy

Two-phase console model:

- **Phase 1 (boot services alive):** UEFI `con_out->OutputString()` — works
  with whatever UEFI firmware routes (serial + framebuffer).
- **Phase 2 (native):** Raw serial UART 16550 driver on COM1 (I/O port
  `0x3F8`).  Activated after `ExitBootServices` when we own the hardware.

## Dependency philosophy

Aligns with RNG philosophy: minimal dependencies.  Freestanding Rust,
no libc, no external crates at the kernel/core level.  UEFI protocol
structs are hand-defined (not from `uefi-rs` crate) to stay lightweight.

## Paging strategy

Long mode mandates paging (`CR0.PG = 1`), so we accept that tax but keep it
simple.  Identity-mapped 4-level tables, no higher-half, no demand paging,
no guard pages.  `paging.rs` provides identity map/unmap/query helpers.  At
boot the kernel runs on UEFI's tables; `adopt_tables()` rebuilds that map
into the kernel's own tables and switches CR3 — needed because UEFI maps its
page-table pages read-only, so the firmware tree can't be modified in place.
Firmware large pages (2 MB / 1 GB) are split into 4 KB tables on demand;
page-table pages come from the physical page allocator.

## Physical memory

Before `ExitBootServices`, the kernel reads the UEFI memory map to know
which physical regions are free.  The heap is a first-fit **free-list
allocator** with splitting and coalescing: blocks carry a 16-byte header
(size + free flag), free blocks are linked in address order, and an 8-byte
back-pointer before each payload lets `free` find its block even when
alignment left a gap.  When the free list is exhausted, the heap **grows**
by taking pages from the page allocator (proportional to the request),
keeping the two allocators cooperating.  A **bitmap page allocator** manages
physical pages: one bit per 4 KB page spanning the conventional regions, so
MMIO holes and firmware-reserved gaps are never handed out, and the heap
region itself is reserved to keep the allocators from double-allocating the
same RAM.  Contiguous runs with power-of-two alignment are supported
(`alloc_pages_aligned`).

## Input strategy

**PS/2 keyboard polling.** Port I/O to `0x60`/`0x64`.  Scancode set 1
(US QWERTY layout in the initial build).  No interrupts — polling loop
inside the shell.

## Display strategy

Two-phase model matching output:

- **Phase 1:** UEFI `con_out->OutputString()` (framebuffer + serial handled
  by firmware).
- **Phase 2:** GOP (Graphics Output Protocol) framebuffer obtained before
  `ExitBootServices`, driven by a built-in 8×16 bitmap font.  Text rendered
  by drawing glyphs directly into the framebuffer.

The framebuffer address stays valid after `ExitBootServices` — the GPU's
linear frame buffer is system memory that we own once boot services are gone.

## Keyboard layout

Scancode set 1, US QWERTY layout.  Hardcoded scancode→ASCII table.
Other layouts can be added later by swapping the translation table.

## Development loop

Standalone project — no integration with the RNG initramfs build system.
Testing via QEMU with OVMF.  The kernel PE binary is placed on a FAT
image as `\bzImage` (matching rsbl's expected path).

## Project layout

Single Rust crate (`x86_64-unknown-uefi` target).  Module breakdown:

- `main.rs` — entry point, panic handler, top-level init
- `uefi.rs` — UEFI protocol type definitions
- `serial.rs` — UART 16550 driver
- `paging.rs` — identity page table helpers
- `memory.rs` — UEFI memory map, free-list heap allocator (grows from page
  allocator), bitmap page allocator
- `paging.rs` — identity page-table helpers (map/unmap/query, large-page split)
- `power.rs` — `ResetSystem`-based shutdown, hlt loop fallback
- `gop.rs` — framebuffer access and text rendering
- `font.rs` — 8×16 bitmap font data
- `ps2.rs` — PS/2 keyboard driver (polling)
- `shell.rs` — command loop and built-in commands

## Milestone status (v0.1)

✅ **Booting** — kernel loads via rsbl, prints banner via UEFI console (verified on real hardware)
✅ **ExitBootServices** — memory map captured via static `.bss` buffer
  (see `docs/adr/0001-static-buffer-for-memory-map.md`)
✅ **Serial** — UART 16550 at COM1, 115200 8N1
✅ **Framebuffer** — GOP located, 8×16 bitmap font renders text
✅ **Keyboard** — PS/2 polling, scancode set 1, US QWERTY
✅ **Shell** — commands: `help`, `echo`, `clear`, `hello`, `info`, `mem`, `halt`, `poweroff`
✅ **Heap allocator** — first-fit free-list with splitting + coalescing, `alloc`/`free`
  (boot-time self-test verifies alignment, reuse, and full coalescing)
✅ **Physical pages** — bitmap allocator over conventional regions, contiguous
  runs, heap reservation, page-0 trap guard (boot-time self-test included)
✅ **Paging helpers** — identity map/unmap/query, 2 MB/1 GB large-page split,
  own tables adopted at boot (boot-time self-test included)
✅ **Heap growth** — heap expands into the page allocator when exhausted
✅ **Shell** — `mmap` dumps the UEFI map, `stress` exercises alloc/free + growth
✅ **Poweroff** — `poweroff`/`exit` shut down via UEFI `ResetSystem`
  (ACPI S5; `halt` keeps the plain hlt loop)

## Target audience

Learning exercise and toy.  Not a Linux replacement.  Not POSIX-compatible.