Mostrando entradas con la etiqueta python. Mostrar todas las entradas
Mostrando entradas con la etiqueta python. Mostrar todas las entradas

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.





    

lunes, 14 de abril de 2014

Como crear un disco booteable en VirtualBox

Como crear un disco booteable en VirtualBox

Una computadora cuando arranca carga el sector 0 del primer disco booteable.
Un disco para que sea booteable,  el sector (0) de booteo debe comenzar con codigo (asembler x86) y termina con 0XAA55.



En un disco virtual de VirtualBox en el byte 0x158 como se ve en la figura, se encuentra el puntero al primer sector del disco.


A continuación vamos a escribir un pequeño programa en assembler la computadora carga el sector 0 en la dirección 0x7C00 y transfiere el control a esta dirección, el programa escribe en la pantalla "Hola Mundo!" llamando a la interrupción del BIOS 10H, ya que a esta altura no existe ningún SO cargado.


[BITS 16]

[org 0x7C00]
 start: 
     mov si,MSG    
call print_string    
jmp $ 

print_string:           ; Espera un mensaje terminado en null en si    
mov al,[si]    
or al,al    
jz  .end 
     inc si    
call print_char 
     jmp print_string
 .end:    
retn

print_char: 
    mov ah,0x0E         ; Especifica que caracter queremos escribir en pantalla 
    mov bl,0x07           ; Especifica el color del texto    
mov bh,0x00          ; Numero de pagina. 
    int 0x10                   ; Interrupcion del  BIOS
     retn
;data    

MSG db 'Hola Mundo!',0x0A,0
TIMES 510 - ($ - $$) db 0

DW 0xAA55




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 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 facilitar esta tarea se ha escrito un script en python.




#!/usr/bin/python

from struct import *

import sys, getopt ,os

l = long
def main(argv):
inputfile = ''
   outputfile = ''
try:
   opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
    except getopt.GetoptError:
     print 'vdiboot.py -i <inputfile> -o <outputfile>'
     sys.exit(2)
  for opt, arg in opts:
if opt == '-h':
print 'vdiboot.py -i <inputfile> -o <outputfile>'
   sys.exit()
     elif opt in ("-i", "--ifile"):
          inputfile = arg
     elif opt in ("-o", "--ofile"):
          outputfile = arg
leng = os.path.getsize(inputfile)
f = open(outputfile,'rb+')
g = open(inputfile,'rb')
f.seek(0x158)
byte = f.read(4)
l = unpack("<l", byte)
f.seek(l[0])
sector0 = g.read(leng)
f.wr ite(sector0)
print 'escribiendo sector ....'
f.close
g.close
if __name__ == "__main__":
        main(sys.argv[1:])

La secuencia de comandos para realizar toda la tarea es:

nasm boot.asm -f bin -o boot.bin
./vdiboot.py -i boot.bin -o boot.vdi
cp ./boot.vdi /home/usuario/VirtualBox\ VMs/boot/

Lanzamos en VirtualBox el sistema boot.vdi y podemos observar en la pantalla "Hola Mundo!


Bibligrafia


http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders
http://www.codeproject.com/KB/tips/boot-loader.aspx?fid=1541607&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=1#_Toc231383187