Несмотря на то, что этот вопрос является старым, он выявляет проблему, о которой я знаю, был воспринят другими, которые заслуживают надлежащего ответа.
dd if=boot.bin of=\.\e: bs=512 count=2
Обычно вы будете использовать of=\\.\e:
с двойной обратной косой черты, однако это не является причиной проблемы. \.\e:
фактически не указывает на начало диска (или USB-накопитель). Он указывает на начало раздела, что E: указывает на. Из-за этого вы написали свой загрузчик в начале данных раздела, а не Master Boot Record (MBR). Новые версии DD поддерживают параметр, чтобы указать начало всего устройства (а не только раздел):
Изменения в версии 0.6beta1
новая функция ID =/од = для ввода и вывода диска диск. если это единственный раздел на диске, тогда выбирается весь диск. Например: если вы вставляете USB-диск и монтируется как f: тогда «id = f:» будет выбирать USB-диск (а не только раздел, например if = \.\ Е: бы)
Для записи в начале USB диск, что раздел E: является частью, вы можете сделать это (я предполагаю, что вы работаете в командной строке, как пользователь с правами администратора):
dd if=boot.bin od=e: bs=512 count=2
Уведомление о том, как я указал (od=e:
). od=
(устройство вывода) означает, что мы хотим использовать весь раздел физических устройств E: принадлежит.
Объяснение наблюдаемого поведения
Что может быть интересен, почему ваш загрузчик, казалось, работали, но распечатывается 0x0000
. Я предлагаю свое лучшее предположение, основанное на знании Windows.
Из-за проблемы с DD запись в начало раздела (а не начало диска) сектор №2 (на основе 1) фактически не содержит нашего маленького ядра. Сектор №1 даже не содержит загрузчика, который мы написали!
Теперь, если наш код был написан в разделе, почему наш загрузчик даже запустил и почему он напечатал неправильное значение (0x0000)?
Это произойдет, если вы отформатировали USB-накопитель в Windows. Что вы можете не понимать, так это то, что USB-накопитель по умолчанию отформатирован как жесткий диск с одним разделом, и один раздел помечен как загрузочный. Microsoft устанавливает загрузчик в MBR (первый сектор диска). Этот загрузчик Microsoft является Chainloader, и это, как правило, функционирует следующим образом (некоторые детали могут отличаться):
- Установите сегмент стека и соответствующим образом
- Сохранить DL [диск мы загружаться на]
- Переместите себя с физического адреса 0x00007C00 в другом месте.
- Перейти к смещению в новой ячейке памяти, где мы должны продолжать
- Посмотрите на таблице разделов для раздела загрузочного
- Read первого сектор (512 байт) на загрузочного разделе (не диск) в память при 0x00007C00
- Восстановление DL со значением, сохраненным в первом шаге
- FAR JMP на 0х0000: 0x7C00
- Выполнения Партии загрузчик запускается так, как если бы BIOS загружался и сразу переходил на него.
Что мы имеем сейчас - загрузчик Microsoft MBR, считывающий первый сектор загрузочного раздела на USB-накопителе и выполняющий его. Первый сектор раздела - наш загрузчик, потому что мы использовали dd if=boot.bin of=\.\e: bs=512 count=2
. Мы на самом деле писали два сектора. Второй сектор раздела (не диск) содержит наше ядро. Настолько эффективно, что наш загрузчик работает!
Итак, теперь мы знаем, почему наш загрузчик запущен, почему он напечатал неправильное значение?Теперь может быть яснее, что второй сектор диска не имеет нашего ядра, этот раздел содержит его. Диск для чтения (INT 13h) делает код:
mov ah, 0x02 ; Disk Read
mov al, 0x01 ; Number of Sectors to read
mov bx, 0x0000
mov es, bx
mov bx, 0x7e00 ; ES:BX location to read to 0x0000:0x7E00
mov dl, [driveno]
xor dh, dh
mov cx, 0x0002 ; Read sector #2 (1-based, not 0-based)
int 0x13
Мы только что прочитал второй сектор диска, а не раздел. Скорее всего, второй сектор обнуляется и, следовательно, причина, по которой наш загрузчик считывает значение 0x0000.
Заключение
Если бы мы правильно написали в течение первых 2-х секторов (1024 байт) диска (с DD), то наш загрузчик и ядро бы работал нормально ..
Благодаря Microsoft и его загрузчик цепочек - наш загрузчик работал, но ядро находилось не на том месте на диске, и мы распечатали сектор, который, вероятно, заполнен нулями. Эта цепочка событий заставила запустить наш загрузчик и показала, что int 13h не удалось. Вероятно, это вообще не сработало, он просто прочитал сектор, который не содержал наше ядро.
Примечание: Я использую слово kernel
, но в контексте этого вопроса он относится к данным (0x1234
), хранящимся во втором секторе.
Единственное, что выглядит «забавным» для меня, это 'of = \. \ E:'. Он должен работать, иначе вы не увидите никакой информации. То, что я привык использовать, - 'of =/dev/fd0' - у меня есть настоящий флоппи-дисковод. Я бы «ожидал», возможно, что-то вроде 'of =/dev/sdb' (?) Для USB. Это порт Windows 'dd'? Это объясняет мою путаницу. Я не вижу ошибок в вашем коде - на самом деле неплохо. Удачи! –
Да, это оконный порт. Есть ли какая-нибудь другая программа, которую я могу попробовать? –
«rawrite» может быть (я не знаком с инструментами Windows), но я думаю, что ваш 'dd' должен работать, иначе вы не увидите никакого вывода. Вернуться к 'int 13h'. Я думаю, что проверка 'ah' для номера ошибки будет работать, но указание ошибки - это флаг флага. Вы можете попробовать 'jc reset' ... –