Простой загрузчик не может читать секторы с int 13h на реальной машине

У меня странная проблема с моим простым кодом загрузчика.
Он должен считывать сектор с диска через функцию прерывания BIOS 13h 02h в видеопамять в текстовом режиме (просто чтобы посмотреть, работает ли он). Он отлично работает на эмуляторах (Bochs, QEmu), но когда я пытаюсь загрузить его с Pendrive, подключенного к реальной машине (Acer Extensa 5620Z), он просто очищает экран и печатает:

PCI System Error on Bus/Device/Function 0000h
PCI System Error on Bus/Device/Function 0200h

и это не похоже на загрузку каких-либо данных. После вызова этого прерывания не установлен флаг переноса и нет кода ошибки в AH, только 1 (предположительно, число прочитанных секторов).

Вот соответствующая часть кода:

          mov   bootdev,   %dl      # Device we're booting from.

          # ES=B800 (video memory segment in mode 03h)
          mov   $0xB800,   %ax
          mov   %ax,       %es

          # Read one block.
          mov   $0x0001,   %cx      # C:0, S;1
          mov   $0x00,     %dh      # H:0
          xor   %bx,       %bx      # ES:BX = B800:0000 = output buffer.
          mov   $0x0201,   %ax      # Function 02h: read sectors (just one).
          stc
          int   $0x13               # Disk controller BIOS interrupt.
          jc    error               # On error, print an error message.

Номер устройства, с которого мы загружаемся, взят из самого BIOS (в DL) и хранится в bootdev для последующего использования. Кажется, с этим номером все в порядке, я могу вызвать функцию 08h прерывания 13h, чтобы получить из него правильную геометрию привода. Просто когда я пытаюсь загрузить любые сектора с помощью функции 02h, появляется это сообщение об ошибке.

Есть идеи, что может быть не так?

1 ответ

Решение

Есть две вещи, которые отличаются на "реальной" машине по сравнению с виртуальной машиной:

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

Второе: компоненты памяти не эмулируются, а реальны. Вы не можете быть уверены, что память на адресе B800:0 ведет себя как "обычная" оперативная память на реальной машине. B800:0 - это не "обычная" ОЗУ, а графическая ОЗУ, которая может вести себя не так, как обычная. Попробуйте вместо этого прочитать по адресу 9000:0, а затем скопировать данные в B800:0 с помощью "REP MOVSW".

Другие вопросы по тегам