domingo, 20 de abril de 2014

Como cargar a memoria más sectores del disco de inicio

Como cargar a memoria más sectores del disco de inicio

En la página anterior escribimos un pequeño programa en asembler para escribir en pantalla "Hola Mundo" hacien uso de la Interrupción 10H, ahora vamos a utilizar la interrupción 13H para cargar sectores del disco a RAM, a esta subrutina la vamos a llamar "carga_sector.asm".

;carga DH sectores a ES:BX desde el disco DL
carga_sector:
push dx          ; Guarda DX en el stack para usarla posteriormente
mov ah, 0x02 ; Funcion del BIOS para leer sectores
mov al, dh      ; Leer DH sectores
mov ch, 0x00 ; Seleccionar cilindro 0
mov dh, 0x00 ; Seleccionar cabeza 0
mov cl, 0x02  ; Comenzar lectura desde el sector 2 
int 0x13         ; Interrupcion del BIOS 
jc disk_error   ; Si hay error de lectua el carry vale 1 y salta
pop dx           ; Restaura DX desde el  stack
cmp dh, al      ; si AL (sectores leidos) != DH (sectores solicitados)
jne disk_error ; Muesta mensaje de error
ret
disk_error:
mov si, DISK_ERROR_MSG
call print_string
jmp $
; Variables
DISK_ERROR_MSG db " Error de Lectura !" , 0

Para verificar que hemos leido dos sectores inicializamos el sector dos con la palabra 0xabcd y el sector 3 con la palabra 0x1234, para verificar la carga leemos una palabra del sector 2 y una del sector 3 en memoria y la mostramos en pantalla. Para esto debemos escribir una rutina que convierta numeros hexadecimales a caracteres ASCII y los imprima en pantalla.
Esta rutina la llamamos "print_hex.asm".

;convertimos a DX en su representacion hexadecimal en caracteres ASCIII
print_hex:
              mov   al, dh
call hex_to_char
              lea   bx, [STRING]
              mov   [bx], ax      ;Colocamos el caracter convertido en el string
              mov   al, dl
call hex_to_char
              lea   bx, [STRING+2]
              mov   [bx], ax      ;Colocamos la parte menos significativa a continuacion
mov si, HEX_OUT
call print_string   ; Para mostrar en pantalla usamos la rutina print_string
ret


TABLE:
            db "0123456789ABCDEF", 0

hex_to_char:
            lea   bx, [TABLE]
            mov   ah, al        ;hacemos al igual ah para tener el nibble bajo en al
            shr   ah, 4         ;y el nibble alto en ah
            and   al, 0x0F      ;
            xlat                ;buscamos en TABLA la representacion ASCII de al
            xchg  ah, al        ;intercambiamos al, con ah
            xlat                ;lbuscamos en TABLA la representacion ASCII de al
            ret

HEX_OUT: db 'Sector leido 0x'
STRING:  db '0000',0x0A,0x0D,0        

Ahora ya tenenos todos los elemento para armar el programa que cargue los dos sectores adicionales del disco en memoria y muestre en pantalla los valores de los sectores cargados.
Llamamos a este programa "boot.asm"

[BITS 16]
[org 0x7C00]
start:
mov [BOOT_DRIVE], dl ; El BIOS guarda el disco de inicio en DL.
                                                    ; Luego lo usaremos para cargar los otros dos sectores.
mov bp, 0x8000                 ; Seteamos el stack a este lugar seguro
mov sp, bp ; way, at 0x8000
mov bx, 0x9000                 ; Cargamos 5 sectores a 0x0000(ES):0x9000(BX)
mov dh, 5                           ; desde el disco de inicio.
mov dl, [ BOOT_DRIVE ]
call carga_sector
mov dx, [0x9000 ]              ; Mostramos en pantalla la primera palabra cargada desde el sector 2
call print_hex                      ; Esperamos que sea 0xabcd
mov dx, [0x9000 + 512]    ; Mostramos en pantalla la segunda palabra cargada
call print_hex                      ; Esperamos que sea 0x1234
jmp $
%include "./print_string.asm"
%include "./print_hex.asm" 
%include "./carga_sector.asm"

; Global variables

BOOT_DRIVE: db 0
; Relleno del sector 0
times 510 -( $ - $$ ) db 0
dw 0xaa55
times 256 dw 0xabcd
times 256 dw 0x1234

A este programa lo compilamos con el nasm mediante la sentencia:

nasm boot.asm -f bin -o boot.bin

Obtenemos un archivo boot.bin que ocupa exactamente 512 x 3 bytes.
Para crear el disco de Virtual Box arrancamos el programa y creamos una nueva VM ( ej. boot) en Type elegimos "other" y en versión elegimos "other/unknow".Elegimos el disco de longitud fija. Buscamos el archivo os.vdi en la carpeta "Virtualbox VMs"



Ahora debemos escribir el archivo "boot.bin" en el sector 0 del disco de Virtualbox para realizar esto utilizamos un script en python.

Una vez obtenida la maquina virtual la ejecutamos desde VirtualBox y obtenemos el resultado que se muestra en la figura.





    

No hay comentarios:

Publicar un comentario