Я пытаюсь разработать загрузчик, который просто сканирует каталог root своего загрузочного носителя (дискета с FAT16) на наличие файла и переходит к нему. Я, наконец, столкнулся с проблемой, которую нигде не обнаружил в сети, и чувствую, что сделал что-то не так: при запуске моего кода, когда я читаю каталог root диска, используя INT 0x13, устанавливается флаг переноса и после того, как я заставил его распечатать код ошибки, который приходит в AH, я получил 0x80, который, кажется, соответствует тайм-ауту диска. Я уже пробовал жестко кодировать DL до 0x00 (дискета # 1 - то же, что и раньше), 0x01 (дискета # 2 - AH = 0x01 недопустимая функция) и 0x80 (жесткий диск # 1 - на самом деле были данные, но, как и ожидалось, не тот, что из образ дискеты). Я также пытался жестко запрограммировать вычисление параметров и пытался читать только один сектор. Ниже приведен код, в котором, по-видимому, происходит ошибка:
BITS 16
jmp short bootload
nop
; Drive parameters
bootload:
; Segment registers
mov ax, 0x07C0+544
cli
mov ss, ax
mov sp, 4096
sti
mov ax, 0x07C0
mov ds, ax
mov es, ax
; Boot device
mov [bootdev], dl
; Calculations (I just hardcoded them in this example to make it easier to understand)
mov byte [rootdirsize], 14
mov byte [rootdirchssec], 1
mov word [rootdirchstrack], 1
; Read sectors
mov ah, 0x02 ; Read sectors
mov al, byte [rootdirsize] ; The amount of sectors needed by the root dir entries
; (RootDirEntries / 16)
mov dl, byte [bootdev]
mov dh, 0 ; Heads are ignored... yet
mov cl, byte [rootdirchssec] ; Sector number of the root dir in CHS
and cx, 0b0000_0000_0011_1111 ; Sector only uses bits 0-5 of CX
mov bx, word [rootdirchstrack] ; Track number of the root dir in CHS
shl bx, 6 ; Track uses bits 6-15 of CX
or cx, bx ; Transfer to CX
mov bx, 0x0100 ; Segment where it is loaded
mov es, bx
mov bx, 0 ; Offset = 0
int 0x13
jc disk_error ; CF = error
jmp $ ; the rest of the bootloader
disk_error:
mov al, ah ; AH is the error code
mov ah, 0x0E ; print it
int 0x10 ; returns 'Ç' = 0x80 = timeout
jmp $
data:
bootdev db 0
rootdirsec dw 0
rootdirchssec db 0
rootdirchstrack dw 0
rootdirsize db 0
times 510-($-$$) db 0
dw 0xAA55
Реальный код, конечно, намного длиннее, я пытался писать только те части, которые важны для проблемы. Другие сведения, которые могут помочь:
- Я использую NASM
- Я тестирую на VMWare Workstation с виртуальной дискетой
- Другой код работает нормально (например, , распечатывая материал или взаимодействуя с клавиатурой)
- Я сделал несколько снимков для проверки виртуальной памяти с помощью шестнадцатеричного редактора, данные диска (кроме загрузочного кода) никогда не загружались в память