From c480e76433f9bb8ce8ce9d5802cdada8883db184 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 12 Jul 2026 01:31:26 +0000 Subject: 🌭 kernel/: болваночное ядро (пишет в 0xB8000) + загрузчик Plan9 a.out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - kernel.c + kern.s: 386-ядро, пишет строку в VGA-текстбуфер 0xB8000, halt. Собирается 8a+8c+8l в Plan9 a.out (I_MAGIC, entry 0x100000). - loader.c: загрузчик a.out (не ELF — выхлоп у нас a.out): разбор big-endian заголовка, загрузка сегментов по entry, зануление bss, прыжок. - проверено: kernel = валидный a.out с 0xB8000 в коде; loader.aout_parse корректно разбирает реальное ядро (entry/размеры сходятся). - bin/: добавлены 8a, 8l (386 ассемблер + линкер). Co-Authored-By: Claude Opus 4.8 --- kernel/README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 kernel/README.md (limited to 'kernel/README.md') diff --git a/kernel/README.md b/kernel/README.md new file mode 100644 index 0000000..1e711ae --- /dev/null +++ b/kernel/README.md @@ -0,0 +1,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-путь под твоё «выхлоп у нас в а.аут». -- cgit v1.2.3