2012-04-04 12 views
6

Od około tygodnia pracuję nad prostym systemem operacyjnym do celów edukacyjnych i ... "zabawą". VirtualBox i NASM na wyciągnięcie ręki, faktycznie miałem dobry start. Ostatecznie zdecydowałem, że chcę również opracować bootloader (po uderzeniu w ściankę 512-bajtową), poprzez zasilenie niesławnego Brokenthorn tutorial, aż do momentu załadowania z systemów plików.Działający bootloader FAT16 generuje błąd odczytu na aktualnym sprzęcie?

Z niektórymi shenaniganami HexFiend i kilkoma pustymi obrazami FAT16, w końcu udało mi się opracować BPB. Z dodatkowym hakerem montażowym (podstawą jest samouczek Brokenthorna, part 6), również załadowałem plik działając z moim bootloaderem, który ładuje trafnie nazwany plik "boot" z mojego dysku wirtualnego (wykonany przy użyciu dd if =/dev/zero of = boot.img bs = 512 count = 2880)

Jaki jest więc problem? To, co widzę, kiedy załadować do rzeczywistego sprzętu za pomocą pamięci USB (w tym przypadku/dev/disk3, gdzie skompilowany plik jest boot.bin):

dd bs=512 count=1 if=compiled/boot.bin of=/dev/disk3 

Oto oczekiwany wynik (w VirtualBox):

Current output

porównaniu do actual output (na starym laptopie)

Old output

'-' 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 

(użyłbym rzeczywiste komunikaty debugowania, ale limit 512-bajtowy jest dość makabryczny.)

Tak, różnica jest taka, że ​​jeden jest pamięć USB, a jeden jest (wirtualny) floppy dysk. Oba mają dokładnie taką samą informację załadowaną na każdą z nich, łącznie z BPB. Jednak jeden działa, a jeden nie. Tutaj jest główną częścią mojego kodu do ładowania sektor (za pomocą ah 02h/13h, co usłyszałem pracował prawidłowo przez 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 

(pełny źródła, w tym BPB, można znaleźć na pastebin (http://pastebin.com/SeUm7xu6)

mam pokonać szereg problemów z montażem do tej pory, ale ten jeden ma mnie stumped. mam nadzieję, że mogę ominąć bootloadera i streszczenie plików IO jak najszybciej.

Wszelkie sugestie będą bardzo mile widziane. Z góry dziękujemy!

Odpowiedz

6

Twój kod odczytuje z dysku numer 0, który może nie być ładowanym przez bootloader urządzenia (i bardzo często nie jest, jeśli uruchamiasz się z pamięci USB). Numer dysku, z którego należy odczytać, jest ładowany przez BIOS do rejestru dl. Jest to już wersja answered question na SO.