Skip to content

Рабочее ядро: ASM + C + C++ + Rust, загрузка до GUI и интерактивного шелла - #10

Merged
KEYTRON merged 1 commit into
mainfrom
claude/custom-os-kernel-d31vqf
Jul 3, 2026
Merged

Рабочее ядро: ASM + C + C++ + Rust, загрузка до GUI и интерактивного шелла#10
KEYTRON merged 1 commit into
mainfrom
claude/custom-os-kernel-d31vqf

Conversation

@KEYTRON

@KEYTRON KEYTRON commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Ядро доведено до рабочего состояния

Ядро теперь полностью загружается в QEMU: инициализация → графический рабочий стол 1024×768 → интерактивная оболочка. Как и просилось, в основе четыре языка: ASM, C, C++, Rust.

Почему ядро не работало

  1. #UD сразу после kernel_main — код собирался без -mno-sse, компилятор генерировал movdqa при выключенном SSE. Добавлены -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -fno-stack-protector -fno-pic.
  2. Клавиатура не работалаirq_handler не диспетчеризовал зарегистрированные обработчики; теперь вызывает таблицу interrupt_handlers.
  3. VESA-драйвер писал по захардкоженному адресу 0xE0000000 при замапленных всего 2 MiB → page fault. Теперь framebuffer берётся из multiboot info, а entry.S маппит первые 4 GiB.
  4. CI-выход из QEMU происходил в первой строке kernel_main — смок-тест ничего не проверял. Выход перенесён после полной инициализации, лог проверяется на маркеры.

Что добавлено по языкам

Язык Компонент
ASM multiboot-заголовок с запросом видеорежима, identity map 4 GiB, передача multiboot info в C
C драйвер PIT-таймера (100 Гц), клавиатура с кольцевым буфером и Shift/CapsLock/Ctrl, VGA со скроллингом/курсором, printf с %lx/%p, диагностика исключений (rip/err/cr2)
C++ куча ядра 16 MiB (lib/cxx/kheap.cpp): free-list first-fit со слиянием, kmalloc/kfree/krealloc, operator new/delete, минимальный рантайм
Rust kernel/rust — no_std staticlib (x86_64-unknown-none): оболочка myos> с командами help/about/langs/mem/alloc/uptime/echo/clear/reboot/halt; GlobalAlloc поверх C++ кучи (String/Vec работают); selftest при старте

Проверено в QEMU

  • Загрузка по serial-логу: GDT → IDT → куча → PIT → клавиатура → прерывания → Rust runtime selftest: OK → GUI 1024×768×32 → шелл
  • Интерактивность: команды набраны через эмуляцию клавиатуры (sendkey), шелл отвечает; alloc 1000000 выделяет и проверяет 1 МБ, после освобождения mem показывает 0 занятых
  • GUI: окна с заголовками, панель задач, иконки — текст читаем (добавлены строчные глифы)
  • CI-сценарий (QEMU_EXIT=1 ./utils/build_iso.sh + isa-debug-exit) прогнан локально — проходит

Сборка

rustup target add x86_64-unknown-none
./utils/build_iso.sh
qemu-system-x86_64 -cdrom kernel/myos.iso -m 256 -serial stdio

🤖 Generated with Claude Code

https://claude.ai/code/session_01BAZ4LHbL24XrDLrcyNZeUY


Generated by Claude Code

Загрузка (ASM, entry.S):
- multiboot-заголовок запрашивает видеорежим 1024x768x32
- identity map первых 4 GiB 2-МиБ страницами (было 2 MiB — VESA
  framebuffer по 0xFD000000 вызывал page fault)
- передача multiboot magic/info в kernel_main

Критические исправления (C):
- сборка с -mno-red-zone -mno-mmx -mno-sse: компилятор генерировал
  SSE-инструкции (movdqa) при выключенном SSE — ядро падало с #UD
  сразу после kernel_main
- irq_handler теперь диспетчеризует зарегистрированные обработчики
  (клавиатура раньше вообще не получала прерываний)
- убран sti перед iretq в заглушках прерываний
- VESA-драйвер берёт framebuffer из multiboot info вместо
  захардкоженного адреса; текстовый режим как fallback
- VGA: скроллинг, backspace, tab, аппаратный курсор
- новый драйвер PIT-таймера (100 Гц, uptime)
- клавиатура: кольцевой буфер, Shift/CapsLock/Ctrl, keyboard_getchar()
- printf: %lx/%lu/%ld/%p/%z, вывод одновременно на VGA и serial
- обработчик исключений печатает rip/err/cr2 и останавливает ядро
- GUI-шрифт: глиф '_', строчные буквы (маппинг на заглавные)

Новое — C++ (lib/cxx):
- куча ядра 16 MiB: free-list аллокатор first-fit со слиянием,
  kmalloc/kfree/krealloc/kmalloc_aligned/kheap_stats
- operator new/delete, минимальный C++ рантайм (freestanding,
  -fno-exceptions -fno-rtti)
- gui_widgets использует настоящую кучу вместо bump-заглушки 64 KiB

Новое — Rust (kernel/rust):
- staticlib no_std для x86_64-unknown-none, линкуется в ядро
- интерактивная оболочка myos>: help/about/langs/mem/alloc/uptime/
  echo/clear/reboot/halt, редактирование строки, Ctrl+C
- GlobalAlloc поверх C++ кучи (String/Vec работают в ядре)
- rust_selftest() проверяет аллокатор при старте

Сборка/CI:
- Makefile: правила для C++ (g++) и Rust (cargo), флаги freestanding
- build_iso.sh работает из любого каталога (в CI запускался из корня
  и делал cd в несуществующий каталог)
- kernel-smoke.yml: установка rust-таргета, QEMU-выход только после
  полной инициализации, проверка маркеров в serial-логе

Проверено в QEMU: загрузка до GUI-рабочего стола 1024x768, оболочка
отвечает на команды с клавиатуры, куча выделяет/освобождает 1 МБ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BAZ4LHbL24XrDLrcyNZeUY
@KEYTRON
KEYTRON marked this pull request as ready for review July 3, 2026 10:31
@KEYTRON
KEYTRON merged commit 89f11e8 into main Jul 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants