Почему загрузчики перемещаются в памяти?
-
05-07-2019 - |
Вопрос
Я пишу загрузчик, и у меня записано большинство деталей, но я не уверен, почему некоторые загрузчики перемещают себя в память перед началом основной части своего выполнения.
Кто-нибудь может это объяснить?
Примером такого поведения является оригинальный загрузчик ядра Linux версии 0.01 в котором содержится следующий комментарий:
boot.s загружается в 0x7c00 подпрограммами запуска bios и перемещается с пути к адресу 0x90000 и переходит туда.
Решение
Из связанной статьи:
На практике MBR обычно содержит загрузчик, целью которого является загрузка другого загрузчика, который находится в начале одного из разделов. Часто это очень простая программа, которая находит первый раздел, помеченный как Active, загружает свой первый сектор в ОЗУ и начинает его выполнение. Поскольку по договоренности новый загрузчик также загружается по адресу 7C00h, старому загрузчику может потребоваться переместить весь или часть себя в другое место, прежде чем делать это. Также ожидается, что ES: SI будет содержать адрес в ОЗУ таблицы разделов и DL номер загрузочного диска. Нарушение таких соглашений может сделать загрузчик несовместимым с другими загрузчиками.
Другие советы
CookieOfFortune по сути верен (потому что он хотел переместить что-то в то место, где находился первоначальный загрузчик), но это было не для второго загрузчика, а скорее для самого ядра.
Из его комментариев:
Затем он загружает систему со скоростью 0x10000, используя прерывания BIOS.После этого он отключает все прерывания, переводит систему в 0x0000, переходит в защищенный режим и вызывает запуск системы.Затем система должна ПОВТОРНО инициализировать защищенный режим в своих собственных таблицах и включить прерывания по мере необходимости.
Он хочет, чтобы ядро располагалось в 0x0000 ... 0xKERNEL_SIZE-1, однако начальный загрузчик в настоящее время находится в 0x7C00, поэтому, если бы ядро было больше ~ 32 КБ, оно перезаписало бы загрузчик при его перемещении.Тот факт, что ядро расположено по адресу 0x0000, также объясняет этот комментарий:
"ОБРАТИТЕ ВНИМАНИЕ!в настоящее время длина системы не превышает 8 * 65536 байт. "
Если бы он был длиннее 512 КБ, начиная с 0, это привело бы к попаданию в зарезервированную область адресного пространства x86.
Я полагаю, что этот раздел кода содержит фактический переход в ядро
mov ax,#0x0001 | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs)
Иногда загрузчик находится в ПЗУ, и в какой-то момент его необходимо скопировать в ОЗУ.