
Этой небольшой заметкой хотелось бы показать, что, если правильно начать, то в разработке собственной ОС нету ничего особо сложного. Под катом находится краткое и довольно общее руководство к действию по написанию ОС с нуля.
Как не надо начинать

Не надо писать загрузчик. Умные люди придумали Multiboot Specification, реализовали и подробно описали, что это такое и как его использовать. Не хочу повторяться, просто скажу, что это работает, облегчает жизнь, и его надо применять. Спецификацию, кстати, лучше прочесть полностью, она небольшая и даже содержит примеры.
Не надо писать ОС полностью на ассемблере. Это не так чтобы плохо, скорее наоборот — быстрые и маленькие программы всегда будут в почёте. Просто так как этот язык требует значительно больших усилий на разработку, то использование ассемблера приведёт только к уменьшению энтузиазма и, как следствие, к забрасыванию исходников ОС в долгий ящик.
Не надо загружать кастомный шрифт в видео память и выводить что-либо на русском. Толку от этого никакого. Гораздо проще и универсальнее использовать английский, а изменение шрифта оставить на потом, загружая его с жёсткого диска через драйвер файловой системы (заодно будет дополнительный стимул сделать больше, чем просто начать).
Подготовка

После начального ликбеза необходимо определиться с главными вопросами:
- целевая архитектура — x86 (real/protected/long mode), PowerPC, ARM, ...
- архитектура ядра/ОС — монолит, модульный монолит, микроядро, экзоядро, разные гибриды
- язык и его компилятор — C, C++, ...
- формат файла ядра — elf, a.out, coff, binary, ...
- среда разработки (да, это тоже играет не последнюю роль) — IDE, vim, emacs, ...
Далее следует углублять знания согласно выбранному и по следующим направлениям:
- видео память и работа с ней — вывод в качестве доказательства работы необходим с самого начала
- HAL (Hardware Abstraction layer) — даже если поддержка нескольких аппаратных архитектур и не планируется грамотное отделение самых низкоуровневых частей ядра от реализации таких абстрактных вещей как процессы, семафоры и так далее лишним не будет
- управление памятью — физической и виртуальной
- управление исполнением — процессы и потоки, их планирование
- управление устройствами — драйвера
- виртуальные файловые системы — для обеспечения единого интерфейса к содержимому различных ФС
- API (Application Programming Interface) — как именно приложения будут обращаться к ядру
- IPC (Interprocess Communication) — рано или поздно процессам придется взаимодействовать
Инструменты

- для сборки подойдут любые стандартные средства, как то make, cmake,… Тут в ход могут пойти скрипты для линкера и (специально написанные) утилиты для добавления Multiboot-заголовка, контрольных сумм или для каких-либо других целей.
- под подготовкой образа имеется ввиду его монтирование и копирование файлов. Соответственно, формат файла образа надо подбирать так, чтобы его поддерживала как утилита монтирования/копирования, так и виртуальная машина. Естественно, никто не запрещает совершать действия из этого пункта либо как финальную часть сборки, либо как подготовку к запуску эмулятора. Всё зависит от конкретных средств и выбранных вариантов их использования.
- запуск виртуальной машины труда не представляет, но нужно не забыть сначала отмонтировать образ (отмонтирование в этом пункте, так как до запуска виртуальной машины реального смысла в этой операции нет). Также не лишним будет скрипт для запуска эмулятора в отладочном режиме (если таковой имеется).
Hello, World!

На данном шаге необходимо проверить как можно больше возможностей средств разработки, которые планируется использовать в будущем. Например, загрузку модулей в GRUB или использование в виртуальной машине физического диска/раздела/флешки вместо образа.
После того как этот этап прошёл успешно, начинается настоящая разработка.
Обеспечение run-time поддержки

- функция для динамического выделения блока данных на стеке
- работа с heap
- функция копирования блока данных (memcpy)
- функция-точка входа в программу
- вызовы конструкторов и деструкторов глобальных объектов
- ряд функций для работы с исключениями
- стаб для нереализованных чисто-виртуальных функций
- ...
При написании «Hello, World!» отсутствие этих функций может никак не дать о себе знать, но по мере добавления кода, линкер начнёт жаловаться на неудовлетворённые зависимости.
Естественно, тут же следует упомянуть и о стандартной библиотеке. Полная реализация не является необходимой, но основное подмножество функций реализовать стоит. Тогда написание кода будет значительно привычнее и быстрее.
Отладка

Можно посоветовать следующее:
- само собой разумеющееся, отладочный вывод
- assert с немедленным выходом в «отладчик» (см. следующий пункт)
- некоторое подобие консольного отладчика
- проверить не позволяет ли эмулятор подключать отладчик, таблицы символов или ещё что-нибудь
Без встроенного в ядро отладчика поиск ошибок имеет вполне реальный шанс превратится в кошмар. Так что от его написания на некотором этапе разработки просто никуда не деться. А раз это неизбежно, то лучше начать его писать заранее и таким образом значительно облегчить себе разработку и сэкономить довольно много времени. Важно суметь реализовать отладчик независимым от ядра образом, чтобы отладка минимальным образом влияла на нормальную работу системы. Вот несколько типов команд, которые могут быть полезны:
- часть стандартных отладочных операций: точки останова, стек вызовов, вывод значений, печать дампа, ...
- команды вывода различной полезной информации, вроде очереди исполнения планировщика или различной статистики (она не так бесполезно как может показаться сначала)
- команды проверки непротиворечивости состояния различных структур: списков свободной/занятой памяти, heap или очереди сообщений
Развитие

Подобие SDK

Необходимости в документации, описывающей процесс написания того или другого типа программы, нет. Но сделать заготовку из типовых элементов стоит. Это не только упростит добавление программ (что можно делать и копированием существующих программ с их последующим изменением, но это потребует больше времени), но также позволит легче их обновлять при изменениях в интерфейсах, форматах или чем-то ещё. Понятно, что таких изменений в идеале быть не должно, но так как разработка ОС — вещь нетипичная, то есть достаточно много мест для потенциально неверных решений. А вот понимание ошибочности принятых решений как всегда придёт через некоторое время после их внедрения.
Дальнейшие действия

Полезные ссылки
На Хабре:
Пишем свою ОС: Выпуск 1
Пишем свою ОС: Выпуск 2
Продолжаем написание операционок. Шаг за шагом
Что такое Protected Mode и с чем его едят
Учим систему страничной адресации и обработке прерываний
Начинаем разговор о многозадачности
Память и задачи
Другие источники с большим количеством информации по разработке ОС:
wasm.ru
sysbin.com
wiki на osdev.org
iakovlev.org
Bona Fide OS