summaryrefslogtreecommitdiff
path: root/kernel/README.md
blob: 1e711aedb6faf338a2162e78a0b9b84b7278dd7f (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
33
34
35
36
37
38
39
40
# kernel — болваночное ядро + загрузчик (Plan9 a.out)

Ядро-болванка, которое пишет строку в VGA-текстбуфер **0xB8000**, и **загрузчик**,
который грузит его. Всё в формате **Plan9 a.out** (не ELF) — потому что наш kencc-выхлоп
именно a.out; загрузчик разбирает a.out-заголовок, а не ELF.

## Файлы
* `kern.s`      — энтрипоинт на 386-асме: ставит стек, зовёт `kmain`.
* `kernel.c`    — ядро: пишет `PLAN9 KERNEL STUB -> writes to 0xB8000` в 0xB8000.
* `loader.c`    — загрузчик Plan9 a.out: разбор заголовка (big-endian), загрузка
                  сегментов `[text][data]` по адресу линковки, обнуление bss, прыжок в entry.
* `loader_test.c` — хостовый тест: прогоняет `aout_parse` из настоящего загрузчика на
                  собранном ядре и печатает поля (magic/entry/размеры).
* `mkboot.sh`   — сборка: `8a`+`8c`+`8l` -> `kernel` (a.out), `8c` -> `loader.8`.

## Сборка
```sh
BINDIR=../bin ./mkboot.sh
```

## Формат Plan9 a.out (386)
32-байтный заголовок, **big-endian**, 8 полей по 4 байта:
```
magic text data bss syms entry spsz pcsz
```
`magic == I_MAGIC == 0x1EB` (intel 386). Сегменты идут сразу за заголовком:
`file[32 .. 32+text]` = text, дальше data. Загрузчик копирует их по `entry`
(равен `-T` линкера, тут `0x100000`), зануляет bss и прыгает в `entry`.

## Что проверено
```
kernel: Plan9 a.out, magic=0x1EB (I_MAGIC 386), entry=0x100000,
        константа 0xB8000 присутствует в коде.
loader: aout_parse на реальном kernel -> OK, entry=0x100000, text/data сходятся.
```
Реальный запуск в QEMU/Bochs не гонялся (в контейнере нет эмулятора), но kernel —
валидный a.out, а загрузчик корректно его разбирает и знает, куда грузить и куда прыгать.

> Хочешь под GRUB/multiboot — можно докинуть a.out→ELF-обёртку; здесь же честный
> a.out-путь под твоё «выхлоп у нас в а.аут».