Всю последнюю неделю я разрабатывал простую ОС для учебных целей и... "развлечений". VirtualBox и NASM на буксире, я действительно неплохо начал. В конце концов, я решил, что хочу также разработать загрузчик (после довольно сильного удара по 512-байтовой стене), используя печально известный Brokenthorn tutorial, вплоть до момента загрузки из файловых систем.
С некоторыми махинациями с HexFiend и несколькими пустыми образами FAT16 я в конце концов получил BPB. С некоторыми дополнительными хакерами сборки (основой является учебник Brokenthorn, часть 6), я также получил загрузку файлов, работающую с моим загрузчиком, который загружает 'загрузочный' файл с подходящим названием с моего виртуального диска (сделанный с использованием dd if=/dev/zero of=boot.img bs=512 count=2880)
Так в чем тогда проблема? Это то, что я вижу, когда загружаюсь на реальное оборудование через USB-накопитель (в данном случае /dev/disk3, где скомпилированный файл — boot.bin):
dd bs=512 count=1 if=compiled/boot.bin of=/dev/disk3
Вот ожидаемый результат (в VirtualBox):
По сравнению с фактическим выводом(на старом ноутбуке)
'-' indicates a sector is being loaded
'_' indicates a sector was loaded
'!' indicates all of the desired sectors were loaded properly
'R' indicates a read error
'T' indicates the FAT table is being loaded
'D' indicates the FAT table was loaded properly
'F' means the file is being located (or Found, hence the F)
'L' means the file is being loaded
(я бы использовал фактическиеотладочные сообщения, но ограничение в 512 байт довольно ужасно.)
Итак, разница в том, что один из них представляет собой USB-накопитель, а другой — (виртуальную) дискету.В них обоих загружена точноодна и та же информация, включая BPB. Однако один работает, а другой нет. Вот основная часть моего кода для загрузки сектора (с использованием ah 02h/int 13h, который, как я слышал, работает правильно для USB):
ReadSectors:
mov di, 0x0005 ; How many times should we retry the read?
ReadSectors.loop:
; DEBUG
push ax
mov ah, 0eh
mov al, '-'
int 10h
pop ax
push ax
push bx
push cx
call LBAToCHS
mov ah, 02h ; Set the interrupt to the
; 'read sector' function
mov al, 1 ; Only read one sector
mov ch, byte[chs.track] ; The track to read from
mov cl, byte[chs.sector] ; The sector to read from
mov dh, byte[chs.head] ; The head to read from
mov dl, byte[_bpb.driveNumber] ; The drive to read from
int 13h ; Call our 'disk IO' interrupt
jnc ReadSectors.success ; If we successfully read the data,
; we don't have to try again
mov ah, 00h ; Set the interrupt to the
; 'reset disk' function
int 13h ; Call our 'disk IO' interrupt
dec di ; Decrement our error counter
pop cx
pop bx
pop ax
jnz ReadSectors.loop ; Try again if we've failed
jmp ReadSectors.fail ; RED ALERT
(Полный исходный код, включая BPB, можно найти на Pastebin ( http://pastebin.com/SeUm7xu6)
До сих пор я преодолел ряд проблем с сборкой, но эта поставила меня в тупик Надеюсь, я смогу обойти загрузчик и абстрагировать файловый ввод-вывод как можно скорее.
Будем очень признательны за любые предложения. Заранее спасибо!