frostbyte
Хобби-ядро операционной системы на x86_64, на C и ассемблере. Загружается через Multiboot2, переходит в 64-битный режим со своими таблицами страниц, имеет вытесняющий планировщик и запускает программы в ring 3 - реально стартует в QEMU.
Ядро операционной системы, написанное с нуля - от загрузчика до запуска собственных программ в пользовательском режиме. Оно по-настоящему загружается, в QEMU.
Обзор
frostbyte - это любительское ядро для x86_64, написанное на C и ассемблере. Целью было не написать "операционную систему" в обиходном смысле, а пройти весь путь, который обычно скрыт: от момента, когда прошивка отдаёт управление, до выполнения собственной программы в пользовательском режиме, изолированном от ядра.
Это один из самых беспощадных видов проекта, какой можно себе поставить. Здесь нет библиотек, которые что-либо делают за вас, ни слоя, который поймает ошибку. Есть голый процессор, руководство по архитектуре и вы. Именно поэтому это такая хорошая школа.
В обычной программе ошибка локальна: летит исключение, вы получаете стек вызовов, правите строку. В ядре нет ни одного из этих удобств. Один неверный бит в таблице страниц, и машина просто перезагружается - без сообщения, без лога, без ничего. Отладка превращается в чтение регистров и угадывание, какое из последних трёх движений было роковым.
Эта беспощадность вынуждает работать иначе. Каждый шаг нужно доводить до конца по отдельности и проверять в изоляции, прежде чем добавить следующий, иначе невозможно различить, какое из десяти изменений уронило всю машину. Дисциплина здесь не добродетель, а условие, чтобы вообще двигаться вперёд.
От прошивки до ring 3
Весь путь - это последовательность переходов между всё более высокими уровнями контроля. Прошивка загружает ядро через Multiboot2 и передаёт карту памяти. Затем нужно включить 64-битный режим, что требует предварительной начальной страничной организации. Далее ядро берёт на себя виртуальную память на собственных таблицах страниц, запускает планировщик, переключающий задачи по прерыванию таймера, и лишь в конце прыгает в ring 3.
загрузчик загружает ядро и передаёт карту памяти.
включение long mode требует предварительной начальной страничной организации.
ядро берёт на себя управление виртуальной памятью.
прерывание таймера переключает задачи без их согласия.
прыжок в пользовательский режим и запуск первой собственной программы.
Путь от включения до собственной программы
| Этап | Что происходит | Режим |
|---|---|---|
| Multiboot2 | прошивка отдаёт управление, есть карта памяти | ring 0 |
| Long mode | вход в 64-битный режим | ring 0 |
| Таблицы страниц | ядро берёт на себя виртуальную память | ring 0 |
| Планировщик | таймер переключает задачи без согласия | ring 0 |
| Ring 3 | первая программа, отрезанная от ядра | ring 3 |
Отладка, когда машина просто исчезает
Раз ошибка не оставляет следа, нужен был способ, чтобы ядро могло хоть что-то сказать, ещё не имея драйвера экрана. Ответ - QEMU с выводом на последовательный порт: ядро пишет логи текстом в serial, а тот идёт прямо в терминал. Благодаря этому видно последнюю строку перед перезагрузкой, а не чёрный экран.
В режиме ядра нет "почти работает". Ошибка в отображении памяти не роняет функцию - она роняет всю машину. Поэтому каждый шаг мы тестировали по отдельности в эмуляторе, прежде чем добавить следующий, а флаги no-reboot и no-shutdown держат машину замороженной на сбое, а не дают ей исчезнуть в цикле перезапусков.
Эффект: система, которая по-настоящему загружается
На выходе - ядро, которое реально загружается в QEMU и доходит до выполнения собственной программы в ring 3 - оно не останавливается на выводе "hello", а проходит весь путь до пользовательского режима. Это проект, построенный, чтобы понять компьютер до самого дна, и доведённый до точки, в которой это понимание доказано работой, а не декларацией.
Больше проектов
Другие работы из той же категории - посмотрите, как мы решаем похожие задачи.
Есть похожий проект?
Напишите нам - смета бесплатна и приходит в течение часа.



