Причина моего вопроса в том, что Starman seems to believe the GRUB Legacy author's explanation (см следующий необъяснимого код:Не является 07C0: 0000, тот же физический адрес на машинах x86, что и 0000: 7C00?
7C4B EA507C0000 JMP 0000:7C50 ; Long Jump to the next instruction
; because some bogus BIOSes jump to
; 07C0:0000 instead of 0000:7C00.
Когда я выполняю Intel-заданный алгоритм для построения эффективных адресов на первой ссылки памяти, я умножать 07C0: на 16 (эффективно левый сдвиг его на четыре бита или один полубайт). Затем я добавляю смещение: 0000 и получаю десятичный адрес 31,744.
Если я оставил смену сегмента второй записи памяти четыре бита, у меня все еще есть 0000: и смещение: 7C00 по-прежнему относится к местоположению 31,744. Так что моя реакция кишки является автором этого кода загрузочного сектора GRUB Legacy, тянет нашу ногу. Regardl эссе формы ссылки на память, сделанной любым BIOS, если эффективный адрес вычисляется до десятичного числа 31 744, то, похоже, нет проблем в том, что этот длинный прыжок решается.
В предположении, что автор кода просто выразил ложную физическую ячейку памяти таким образом, что, похоже, было то же физическое местоположение, что и было правильно, я начал думать о том, как можно было бы обращаться с BIOS, который отправил его на неправильный адрес. Пятибайтовый длинный прыжок, похоже, не является решением чего-либо. Пять NOP будут выполнять одну и ту же цель (на самом деле, просто , начав код загрузочного сектора на пять байт раньше, и исключение Long Jump будет иметь тот же эффект, что и Long Jump к следующей команде).
Если BIOS переместится в нужное место (7C00), никаких проблем. Если BIOS переместится в положение выше 7C00, тогда никакой код, загруженный на 7C00, не сможет исправить эту проблему. Если BIOS переместится в местоположение между 7C00 и 7C4B, тогда данные, хранящиеся в этой области (или ошибки, интерпретируемые с отсутствующими байтами), скорее всего, вызовут сбой. Если BIOS скачет точно на 7C4B, инструкция TEST будет переписана (с помощью Long Jump), а JNZ - 7C54 будет выполнена на основе последней математики, выполняемой в BIOS.
Для того, чтобы BIOS перепрыгнул ниже 7C4B, снова неправильные инструкции могут вызвать сбой. С удачей, часть кода загрузочного сектора будет выполнена. Результаты такого выполнения будут зависеть от того, к чему именно «фиктивный» адрес памяти загружается BIOS. Так автор этого кода загрузочного сектора вытягивает нашу ногу с рассказом о «фиктивных BIOS, которые переходят в неправильное место»?
Я отмечаю в BLOG Luke Luo, что загрузочный сектор GRUB2, хотя и отличается от загрузочного сектора GRUB Legacy, retains this inexplicable Long Jump. Поэтому, если оригинальный автор загрузочного сектора GRUB Legacy играет в нас шутку, это довольно удачная шутка (она пережила полную перезапись GRUB). Я остался с выбором, полагая невероятное утверждение о некотором неименованном BIOS и решении такой проблемы, которая, по-видимому, ничего не делает или, полагая, что автор исходного загрузочного сектора играл в нас шутку.
Люк Ло, похоже, согласен с написанием инструкций NOP к 7C66 и 7C67, что свидетельствует о том, что у него нет BIOS, который перескакивает в неправильное место. Загрузочный сектор GRUB2, который был записан на мой Flash-накопитель Linux Mint 13, имеет те же NOP. Однако загрузочный сектор GRUB2, записанный на жесткий диск моего ноутбука (Debian Etch), имеет короткий переход к следующей инструкции, написанной на 7C66 и 7C67 (обратите внимание, что Luke Luo показывает нам, что исходный загрузочный сектор, хранящийся в/usr/lib/grub/i386-pc/boot.img имеет значение Debian). Обе альтернативы имеют одинаковый эффект (выполняют инструкцию, которая следует за ними), поэтому работают оба загрузочных сектора. Также не будет такой эффективности, которую я ожидал бы в загрузочном секторе, где доступно всего около 450 байт для кода, который должен загружать другой сектор и выполнять его (включая сообщения об ошибках, если что-то пойдет не так с этой простой операцией и восьмибайтовым адресом самого сектора).
Так что я что-то упускаю, или я определил kludge, который должен быть удален из загрузочного сектора GRUB (чтобы освободить место для более значимого кода)?
Некоторое время назад я написал [Stackoverflow Q & A] (http://stackoverflow.com/questions/34548325/near-call-jump-tables-dont-always-work-in-a-bootloader) о ситуации, когда не имея этого даун-прыжка, могут привести к неправильным результатам в загрузчике. Это действительно зависит от того, как написан код загрузчика. Некоторые разработчики загрузочных загрузчиков из избытка осторожности добавляют FAR JMP к явным установкам _CS_ к значению, которое они хотят, чтобы они не сталкивались с проблемами, но это может быть необязательно, если их код никогда не полагается на определенное значение в _CS_ –
Подумайте, «изобилие осторожности» покрывает его. Без дальнейшей идентификации BIOS с этой проблемой нельзя даже проверить, что он все еще существует. В те дни, когда у нас не было выбора, кроме как получить наш BIOS с нашим оборудованием, это было бы решением поставщика BIOS, который не знает, как закодировать. Сегодня я надеюсь, что решение будет состоять в замене BIOS. –
Когда изменилась ситуация, что BIOS не пришел с аппаратным обеспечением? Каждая материнская плата, которую я купил за последние несколько лет, поставляется со встроенным BIOS. И даже с виртуальными машинами поставщик VM все еще записывает реализацию BIOS. –