osdev.orgРазработка операционных систем
ТЕОРИЯ - НАЧАЛЬНЫЙ ЗАГРУЗЧИК (9 августа 2012 года)

Оглавление | Оригинал 


 Начальный загрузчик (bootloader) - программа написаная для загрузки более сложного ядра. Детали его реализации описаны в статье Создание собственного загрузчика.

Содержание
1. Чем занимается начальный загрузчик
 1.1. Загрузка вашего ядра
 1.2. Предоставление информации ядру
 1.3. Создание окружения
2. Дизайн начального загрузчика
 2.1. Одностадийный начальный загрузчик
 2.2. Двухстадийный начальный загрузчик
 2.3. Смешанный загрузчик
3. Загрузка множества операционных систем
4. Смотрите так же
 4.1. Статьи
 4.2. Потоки
 4.3. Внешние ссылки

Чем занимается начальный загрузчик

 В конечном счёте, начальный загрузчик должен реализовать:

 На х86, начальный загрузчик запускается в реальном режиме. Следовательно, он имеет лёгкий доступ к ресурсам и функциям BIOS.  Это хорошее место, чтобы произвести тестирование карты памяти, определить доступные видеорежимы, загрузить дополнительные файлы и пр. Начальный загрузчик собирает эту информацию и предоставляет её ядру в доступной форме.

Загрузка вашего ядра
 Ваше ядро находится где-то на диске (предположим на загрузочном диске, что не суть важно). Вопрос: где на диске? Это регулярный файл на дискете отформатированной в FAT? Или это набор последовательных секторов в "зарезервированной области" на дискете FAT12 (в этом случае, вам может понадобиться специальный инструмент для форматирования диска и установки на него ядра)? Или просто оставить дискету не форматированной, а ядро вставить непосредственно в образ диска?

 Возможны все варианты. Выберите один из них (я бы предпочёл зарезервировать некоторое пространство на дискете FAT12 и хранить список секторов занимаемых ядром). "Преймущество" полного FAT12 - то, что вам нет необходимости переписывать загрузочный сектор каждый раз когда вы переписываете ядро.

 В основном способ загрузки зависит от вашего ядра. Например Linux требует дополнительный файл 'initrd' который будет содержать 'процесс инициализации' (на уровне пользователя). Если ваше ядро имеет модульный дизайн и если файловые системы являются модулями, вам необходимо загружать модули вместе с ядром. То же самое относится и к микроядерным сервисам, подобным дисковым сервисам, файловым сервисам и сервисам памяти, и пр.

Предоставление информации ядру
 Некоторые ядра требуют дополнительной информации для запуска. Например, вам необходимо сообщить Linux начало корневого раздела. Весьма полезной информацией является карта адресного пространства. Другой популярной полезной информацией являются поддерживаемые видеорежимы.

 В целом, всё указанное проще предоставить в реальном режиме.

Создание окружения
 Большинство ядер требует защищённого режима. Для таких ядер вам необходимо:
прежде чем передать управление ядру.

Для загрузчика характерно отключать прерывания (ядро будет включать их позже, когда соответственно настроит IDT).

Примечание: Необходимо потратить время на обдумывание того, следует ли или нет, на данном этапе, включать управление подкачкой. Имейте в виду, что отладка кода инициализации подкачки без помощи внешнего обработчика может быстро превратиться в кошмар!

Дизайн начального загрузчика
 Реально, любой загрузчик следует общему дизайну.

Одностадийный начальный загрузчик
 Одностадийный начальный загрузчик содержит единственный файл который полностью загружается BIOS. Затем, этот образ выполняет действия необходимые для запуска ядра, описанные выше.Тем не менее, на x86 вы, как правило, ограничены 512 байтами для одной стадии (исключение составляет не эмулируемый El-Torito), что вобщем то не так много. Кроме того, большая часть этого объёма может быть занята структурами BIOS и заголовками FAT, что ограничивает пространство для работы.

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

Смешанный загрузчик
 Другой путь преодоления 512-байтного барьера, заключается в разделении загрузчика на две части, где первая часть (512 байт) может загрузить остальные. Это может быть достигнуто путём вставки в в ассемблерный код '512-байтного' разрыва, утверждающего. что остальная часть загрузчика находится после загрузочного сектора.
 
Загрузка множества операционных систем
 Простейший путь загрузки других ОС - механизм назваемый последовательной загрузкой. Windows хранит что-то подобное двухстадийного загрузчика в загрузочном секторе раздела на который он установлен. Когда устанавливается Linux, он, например, пишет LILO или GRUB в загрузочный сектор раздела вместо MBR. Теперь, ваш загрузчик может заменять MBR (копироваться с 0x0000:0x7c00 на традиционный 0x0060:0x0000), отображать некоторые меню и позволять пользователю выбирать загрузочный раздел. Теперь ваш (переопределённый) загрузочный сектор MBR будет загружать загрузочный сектор раздела с 0x0000:0x7c00 и перепрыгивать туда. Загрузочный сектор раздела действительно может загрузить ещё один загрузочный сектор - именно по этому процесс называется последовательной загрузкой (chainloading).

З десь мы не касаемся вопросов загрузки с расширенных разделов, которые требуют перед выводом меню последовательного чтения и разбора нескольких таблиц расширенных разделов.

 В самом крайнем случае, начальный загрузчик может стать таким же сложным как простая операционная система, и GRUB может быть хорошим примером: чтение с различных файловых систем, загрузка мультизагрузочных ядер, последовательная загрузка, загрузка дисков памяти initrd и пр. и пр.

Смотрите так же
Статьи
Потоки

Внешние ссылки