Writing an operating system kernel from scratch – RISC-V/OpenSBI/Zig
Разработка ядра операционной системы с нуля
Недавно я реализовал минимальное ядро ОС с разделением времени для RISC-V. В этой статье расскажу о деталях работы прототипа. Материал предназначен для всех, кто интересуется низкоуровневым ПО, драйверами, системными вызовами, и особенно полезен студентам, изучающим системное ПО и архитектуру компьютеров.
Это переработанная версия учебного проекта по операционным системам, но с фокусом на современные инструменты и архитектуру RISC-V. RISC-V — перспективная технология, которая проще для понимания по сравнению с другими архитектурами, оставаясь популярным выбором для новых систем.
Вместо традиционного C я использовал Zig, что упрощает воспроизведение эксперимента благодаря простой настройке и отсутствию необходимости установки дополнительных инструментов для кросс-компиляции под RISC-V.
Репозиторий и рекомендации
Исходный код доступен на GitHub. Перед изучением рекомендуется ознакомиться с основами программирования на RISC-V без ОС, процессом загрузки через SBI и обработкой прерываний.
Архитектура
Мы разрабатываем унике́рнел (unikernel), где приложение и ядро объединены в один исполняемый файл. Это исключает необходимость отдельной загрузки пользовательского кода во время выполнения.
В основе стека лежит слой SBI (OpenSBI), который управляет выводом на консоль и таймером. RISC-V использует уровни привилегий: M-режим (машинный), S-режим (супервизора) и U-режим (пользовательский). Наше ядро работает в S-режиме.
Цели ядра
- Статическое определение потоков (без динамического создания).
- Потоки выполняются в пользовательском режиме и могут делать системные вызовы к ядру.
- Время распределяется между потоками с помощью таймера, который прерывает выполнение каждые несколько миллисекунд.
- Разработка ведётся для одноядерной системы.
Виртуализация и потоки
Перед реализацией важно понять, что такое поток. В среде с разделением времени потоки позволяют эффективно использовать ресурсы системы.