Я следил за этим:
( http://www.codeproject.com/KB/tips/boot-loader.aspx )
Но не знаю, что и как делать дальше.
Как в него загрузить самописное ядро? Или как сделать больше места, чем в одиночном сегменте?
А что делать с бинарниками? Мне нужно скопировать загрузчик в первый сектор, хорошо, но что с ядром и т. д., просто положить на дискету?
Как загрузить ядро или иметь возможность использовать больше места в собственном загрузчике?
Ответы (2)
«Как загрузить ядро» сводится к тому, чтобы узнать, где ядро находится на диске и где вы хотите его разместить в памяти, а затем использовать дисковые службы BIOS для его чтения. Если вы хотите, чтобы ядро загружалось выше 0x00100000, вам может потребоваться загрузить каждую часть во временный буфер (к которому BIOS может получить доступ в реальном режиме), а затем использовать либо защищенный режим, либо «нереальный режим», чтобы скопировать его из буфера в где вы на самом деле этого хотите. Если вы хотите поддерживать сжатие, вам может потребоваться загрузить файлы, а затем распаковать их. Если вы хотите, чтобы ядро использовало сложный формат файла (например, ELF или PE, а не простой плоский двоичный файл), вам может потребоваться проанализировать заголовки, переместить разделы и т. д.
Мои загрузчики обычно намного больше, чем 1 сектор. Код в первом секторе загружает второй сектор, а код в первом и втором секторах загружает оставшуюся часть загрузчика. Таким образом, загрузчик может иметь размер 20 КиБ (например), если вы будете осторожны и не попытаетесь использовать какой-либо код или данные, которые еще не были загружены. У вас также может быть второй этап (и третий, четвертый и т. д. этапы, если вам так хочется), где загрузчик загружает второй этап, а второй этап загружает следующий фрагмент и т. д.
Где хранить двоичные файлы, это зависит от того, какие файловые системы вы планируете использовать. Если вам не нужна никакая файловая система (или если файловая система, которую вы хотите использовать, имеет достаточно «зарезервированного» пространства в начале), вы можете просто объединить двоичные файлы вместе и сохранить их сразу после загрузчика. В противном случае загрузчику (и/или дополнительным этапам) потребуется найти файлы в той файловой системе, которую вы используете.
Примечание. Различные загрузчики работают по-разному. Для чего-то вроде загрузки из сети загрузчик может иметь размер 512 КиБ и должен загружать данные из сети с помощью PXE API. Для CD-ROM вы, вероятно, в конечном итоге будете использовать файловую систему ISO9660 (и сектора размером 2 КиБ). Для жестких дисков вам нужно будет обрабатывать разделы (и, возможно, иметь один загрузчик для «разделов MBR» и другой загрузчик для «разделов GPT»). В итоге вы получите несколько совершенно разных загрузчиков, которые загружают ядро (или, возможно, какой-то образ RAM-диска, если это микроядро) и оставляют компьютер в определенном состоянии при запуске ядра (например, определенный режим процессора, ядро по определенному адресу, другие файлы в определенных местах и т. д.), так что самому ядру не нужно заботиться о том, какой загрузчик его загрузил. Для дополнительной сложности в это «предопределенное состояние» можно включить гораздо больше (например, адрес таблиц ACPI, описание преднастроенного видеорежима и т. д.), чтобы можно было писать загрузчики для других типов систем, и ядро не могло «выиграть». Не нужно заботиться о том, загрузился ли он из «PC BIOS», UEFI, OpenFirmware или чего-то еще.
Как правило, основное, что нужно сделать вашему загрузочному сектору, это загрузить в память либо загрузчик второго уровня, либо ядро. Предполагая, что вы используете ПК, вы будете использовать функции чтения диска BIOS для загрузки секторов. Выполнение этого с дискеты, отформатированной в FAT, вполне возможно в 512b, который вы получаете для своего загрузочного сектора. Кроме того, загрузитесь с компакт-диска El-Torito без эмуляции, что даст вам больше места для вашего загрузчика.
Для получения дополнительной информации посетите OSDev.org или Добросовестный разработчик ОС.