2012-04-04 7 views
6

Durante la última semana, he estado desarrollando un sistema operativo simple para fines de aprendizaje y ... "diversión". VirtualBox y NASM a remolque, en realidad tuve un comienzo bastante bueno. Eventualmente, decidí que también quería desarrollar un gestor de arranque (después de golpear la pared de 512 bytes con bastante fuerza) al pasar por el infame Brokenthorn tutorial, hasta el punto de cargar desde los sistemas de archivos.¿Funciona el cargador de arranque FAT16 genera error de lectura en el hardware real?

Con algunas travesuras de HexFiend y algunas imágenes en blanco de FAT16, finalmente obtuve el BPB funcionado. Con algunos hacks de ensamblaje adicionales (la base es el tutorial de Brokenthorn, part 6), también obtuve carga de archivos trabajando con mi gestor de arranque, que carga el archivo 'boot' apropiadamente llamado de mi disco virtual (hecho usando dd if =/dev/zero of = boot.img bs = 512 count = 2880)

Entonces, ¿cuál es el problema? Es lo que veo cuando me carga sobre el hardware real a través de una memoria USB (en este caso,/dev/disk3, donde el archivo compilado es BOOT.bin):

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

Aquí es el resultado esperado (en VirtualBox):

Current output

en comparación con el actual output (en un viejo ordenador portátil)

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 

(habría utilizado mensajes reales de depuración, pero el límite de 512 bytes es bastante espantosa.)

Por lo tanto, la diferencia es que uno es un lápiz de memoria USB, y uno es un disquete (virtual) disco. Ambos tienen la misma información cargada en cada uno, incluido el BPB. Sin embargo, uno funciona, y uno no. Esta es la parte principal de mi código para la carga de un sector (usando ah 02h/int 13h, la cual he oído funcionaba correctamente para un 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 

(La fuente completo, incluyendo el BPB, se pueden encontrar en Pastebin (http://pastebin.com/SeUm7xu6)

que he superado una serie de problemas con la Asamblea hasta el momento, pero este me ha dejado perplejos. con suerte, puedo conseguir más allá del gestor de arranque y el resumen del archivo IO tan pronto como sea posible.

Cualquier sugerencia sería muy apreciada. ¡Gracias de antemano!

Respuesta

6

Su código se lee desde la unidad número 0, que puede no ser el dispositivo desde el que se cargó el gestor de arranque (y muy a menudo no es así si arranca desde la memoria USB). El BIOS carga el número de unidad desde el que debe leer en el registro dl. Ya es un answered question en SO.

Cuestiones relacionadas