summaryrefslogtreecommitdiff
path: root/efi-kernel/README.md
blob: dcbd2a059c256579469421f197dd195bcd0a4981 (plain)
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
# efi-kernel — EFI-загрузчик + amd64-ядро (Plan9 a.out)

Полная цепочка UEFI-загрузки на портированном тулчейне Plan9 (6c/6a/6l):
**bootx64.efi (PE32+, EFI-загрузчик)** грузит **amd64-ядро (Plan9 a.out)**, которое
пишет в VGA-текстбуфер **0xB8000**.

## Как работает
1. `kernel.c` + `kern64.s` → `6c`/`6a`/`6l` → `kernel.out` — amd64-ядро (Plan9 a.out,
   S_MAGIC `0x8A97`, entry `0x100000`). `kmain` пишет строку в `0xB8000`, затем halt.
2. Ядро встраивается байт-массивом (`kernel_blob.h`) в загрузчик.
3. `efi_load.c` (+ `pe64.s` из 9legacy) → `6c`/`6a`/`6l` → `dd skip=40` → `bootx64.efi`
   (PE32+). Под UEFI загрузчик: печатает статус через `ConOut`, разбирает встроенный
   a.out (big-endian заголовок, 40 байт), копирует сегменты `[text][data]` по `entry`
   (`0x100000`), зануляет bss и **прыгает** в ядро (long mode).

## Формат amd64 Plan9 a.out (S_MAGIC)
Заголовок 40 байт, big-endian: `magic(4) text(4) data(4) bss(4) syms(4) entry32(4)
spsz(4) pcsz(4) entry64(8@off32)`. Сегменты идут за заголовком.

## Сборка
```sh
BINDIR=../bin PLAN9SRC=../deps/plan9foundation ./mk.sh   # -> bootx64.efi
python3 ../efi/mkesp.py bootx64.efi esp.img              # загрузочный ESP
qemu-system-x86_64 -bios OVMF.fd -drive format=raw,file=esp.img
```
`pe64.s`/`efi.h`/`mem.h` — из 9legacy (`../efi/fetch_ref.sh`).

## Заметки
- `0xB8000` — легаси VGA-текст. Под чистым UEFI без CSM запись туда идёт в RAM, а не на
  экран; под QEMU с обычным VGA/CSM — видно. Ядро-болванка демонстрирует загрузку и прыжок.
- Загрузчик не делает `ExitBootServices` (болванка); настоящий — сделал бы перед прыжком.
- Проверено структурно: PE32+ x64 EFI_APPLICATION, встроенный a.out парсится, entry/сегменты сходятся.