Возможно ли реализовать небольшую дисковую ОС на C или С++?

Я не пытаюсь делать что-либо подобное, но мне было интересно узнать, можно ли реализовать "всю ОС" (не обязательно что-то вроде Linux или Microsoft Windows, но больше похоже на небольшую DOS-подобную операционную систему ) в C и/или С++, используя небольшую или небольшую сборку.

Внедряя ОС, я имею в виду создание операционной системы с нуля, начиная загрузчик и ядро ​​с графическими драйверами (и необязательно GUI) на C или С++. Я видел несколько низкоуровневых вещей, сделанных на С++, путем доступа к низкоуровневым функциям через компилятор. Это можно сделать для всей ОС?

Я не спрашиваю, хорошая ли это идея, я просто спрашиваю, возможно ли это даже отдаленно?

Ответ 1

Обязательная ссылка на wiki для OSDev, в которой описываются большинство шагов, необходимых для создания ОС, как описано на x86/x64.

Чтобы ответить на ваш вопрос, будет очень сложно/неприятно создать загрузчик и запустить защищенный режим, не прибегая ни к какой-либо сборке, хотя его можно свести к минимуму (особенно если вы на самом деле не считаете например, используя __asm__ ( "lidt %0\n" : : "m" (*idt) ); как "сборку" ).

Большим препятствием (опять же на x86) является то, что процессор запускается в 16-разрядном реальном режиме, поэтому вам нужен 16-разрядный код. Согласно это обсуждение, вы можете получить GCC 16-разрядный код, но вам все равно потребуется какой-то способ настройки памяти, загрузка кода с некоторых носителей и т.д., все из которых требуют взаимодействия с оборудованием таким образом, что стандарт C просто не имеет понятия (прерывания, порты ввода-вывода и т.д.).

Для архитектур, которые обмениваются данными с аппаратными средствами исключительно с помощью памяти, отображаемой в IO, вы, вероятно, могли бы уйти от написания всего, кроме кода запуска C (который устанавливает стек, инициализирует переменные и т.д.) в чистом C, хотя конкретные требования подпрограммы прерываний/исключающие или системные вызовы и т.д. могут быть трудно реализовать (поскольку вам необходимо получить доступ к специальным регистрам CPU).

Ответ 2

Я предполагаю, что у вас есть ОС для x86. В этом случае вам понадобится как минимум несколько страниц ассемблера для настройки защищенного режима и т.д. Кроме того, много знаний о всех вещах, таких как пейджинг, вызовы, кольца, исключения и т.д. Если вы собираетесь используйте форму системных вызовов, вам также понадобятся некоторые строки кода сборки для переключения между режимом ядра и пользовательского пространства.

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

Просто взгляните на Linux источник ядра, самый важный ассемблерный код (для x86) можно найти в arch/x86/boot, но вы заметите, что даже в этом каталоге большинство файлов написано на C. Кроме того, вы найдете несколько сборочных линий в каталоге arch/x86/kernel для обработки системных вызовов и т.д.

Вне директории arch вряд ли используется какой-либо ассемблер (поскольку ассемблер является машинным, этот машинный код принадлежит директории arch). Даже графические драйверы не используют ассемблер (например, драйвер nvidia в драйверах/gpu/drm/nouveau).

Ответ 3

Загрузочный загрузчик? Возможно, вы захотите пропустить этот бит. Например, Linux довольно часто запускается загрузчиками, отличными от Linux, такими как UBoot. В конце концов, как только система будет запущена, будет присутствовать ОС, но не загрузчик, который просто должен получить ОС в памяти.

И как только вы выберете достойный существующий загрузчик, остальная часть почти проста. Ну, вам приходится иметь дело с памятью и файлами самостоятельно; вы не можете полагаться на fopen. Но даже компилятор С++ имеет мало проблем, генерируя код, который может работать без поддержки ОС.