Вы находитесь на странице: 1из 5

Para poder construir un bootstrap se debe de conocer un poco sobre la BIOS (Basic Input Output System) que es un programa

informtico que al arrancar la mquina, nos permite buscar un bootstrap en algn medio de almacenamiento no voltil, como puede ser un floppy, un CD-ROM o el disco duro.

Cuando se habla de los discos como floppy o hard-disk, el BIOS lee el primer bloque de 512 Bytes que se encuentra en la ubicacin cabeza cero, cilindro cero, sector uno. El ltimo Word de este bloque debe contener un identificador de booteo, en el caso de la arquitectura x86 este identificador es AA55h. Si encuentra este identificador, entonces el BIOS carga en algn lugar de memoria este bloque. En el caso de las x86, la posicin donde carga este programa es en 07C00h, es decir en 07C0:0000. Una vez cargado en la memoria, el BIOS salta a esa direccin y entonces el programa empieza a ejecutarse.

Para poder construir un bootstrap que pueda cargar un programa que se encuentra en un medio de almacenamiento no voltil, el primer paso a lograr es cargar un ejecutable al que despus saltaremos y que ser nuestro kernel. Este puede estar tambin en modo de 16 bits, o se puede construir de 32 bits. Para leer algo de un dispositivo hay que tener en cuenta cmo se pide informacin a bajo, nivel que se cargue un bloque de datos en la memoria. Los discos se direccionan mediante nmero de cabeza, nmero de cilindro y nmero de sector. Esto es as por el motivo de que un disco puede tener varios platos, cada plato o conjunto de platos se divide en cilindros y cada cilindro se divide en sectores. A su vez, cada plato tiene como mnimo dos cabezas que leen el dato, una del lado de arriba y una del lado de abajo. Entonces con el nmero de cabeza indicamos que plato leeremos, con el nmero de cilindro decimos la ubicacin en el plato que leeremos y con el nmero de sector dentro del cilindro tendremos nuestro bloque.

En la cabeza cero, cilindro cero y sector uno tenemos nuestro bootstrap, as que los dems datos y programas que queramos guardar en nuestro disco, debern estar ubicados en cualquiera de los dems lugares. Un ejemplo sobre como cargar el programa que se encuentra en el floppy: ; boot.asm [BITS 16] ;Se setea en modo de 16bits, como se encuentra el procesador al inicio [ORG 0] ;Se pone el cdigo desde el principio del segmento jmp inicializar ;Se dirige al inicio del programa, salto todo lo que es declaraciones ;-------------------------------------------------------------; Datos usados en el proceso de boot-loading ;-------------------------------------------------------------mensajeInicial db "Que buen bootstrap!", 0x0D,0x0A,0 ;-------------------------------------------------------------; impMensaje imprime un mensaje en ascii por pantalla ;-------------------------------------------------------------impMensaje: imprimir: lodsb ; Carga el byte que esta en ds:si en al or al,al ; Comprueba si el carcter es 0 (fin) jz finImpMensaje mov ah,0x0E ; Indica que la interrupcin ser para imprimir por pantalla mov bx,0x0009 ; Se indica pgina base y color de fondo int 10h ; Llamada al BIOS jmp imprimir finImpMensaje: ret ;-------------------------------------------------------------; Procedimiento que carga un programa contenido en el floppy ;-------------------------------------------------------------cargarKernel:

reset: mov ax, 0x0000 ; opcin para resetear el dispositivo mov dl, 0x00 ; drive=0 floppy int 0x13 ; interrupcin 13 del BIOS jc reset ; si hay acarreo es que ocurri un error, y regresa a reset cargar: mov ax, 0x1000 ; ES:BX es donde se carga lo ledo de la interrupcin mov es, ax ; se colocan en ES 1000 mov bx, 0x0000 ;se coloca en bx la dir 0000 mov ah, 0x02 ; con ah=2 digo que voy a leer mov al, 0x05 ; con al indico la cantidad de sectores a leer mov ch, 0x00 ; cilindro=0 mov cl, 0x02 ; sector=2 (en el 1 tengo el booteable) mov dh, 0x00 ;cabeza=0 mov dl, 0x00 ; drive=0 es el floppy int 13h ; invoco la interrupcin jc cargar ; si ocurri un error (acarreo=1), regresa a cargar jmp 0x1000:0x00 ; Salta a la direccin donde se carga el programa ret ; nunca va a llegar a ejecutarse ;-------------------------------------------------------------; Procedimiento que inicializa los registros ;-------------------------------------------------------------inicializar: ;El BIOS ubica en el segmento 07C00h, as que se setean los segmentos a la posicin actual ;As no se tiene que aadir 07C00h a todos los datos mov ax, 0x07C0 mov ds, ax mov es, ax mov fs, ax

mov gs, ax ;call inicializar ;Salvo la direccin del dispositivo desde el que se est booteando mov [bootdrv], dl ;se inicializan los valores para la pila cli ;Se deshabilita las interrupciones mov ax, 0x0000 mov ss, ax mov sp, 0xFFFF sti ;habilito nuevamente las interrupciones jmp main ;-------------------------------------------------------------; main del programa ;-------------------------------------------------------------main: mov si, mensajeInicial ; Muestra el mensaje por pantalla call impMensaje call cargarKernel TIMES 510-($-$$) DB 0 ;Hace que el archivo sea de 512 bytes de longitud dw 0AA55h ; Se indica al bios que es un bootstrap

A la interrupcin 13h hay que pasarle varios parmetros, lo primero que se debe de hacer es resetear el dispositivo, esto es recomendable, y se logra eligiendo la opcin de resetear de la interrupcin (ah=00) y se indica que dispositivo se va a resetear (dh=00 indica el floppy). Luego lo que se hace es cargar el programa, para esto se necesita pasar ms parmetros, el que indica que va a realizar una lectura (ah=02), la cantidad de sectores que se desea leer (al=05), que cilindro se va a leer (ch=00), que sector se va a leer (cl=02), de que cabeza (dh=00) y de que drive (dl=00 indica el floppy).

Los datos que carga la interrupcin, los cargar en la direccin ES:BX, por lo que lo primero que se debe de hacer es setear estos valores a los que se desean. En este caso se quiere que cargue el programa en 1000:0000. Luego de cargar el programa lo que se hace es saltar a la direccin donde se carga el programa, as comienza a ejecutarse. Un ejemplo sencillo de programa a cargar, en este caso se crea un programa que imprima solamente un caracter. Se crea un programa simple en assembler que se llame kernel.asm y se compila, al mismo se coloca en el sector dos de la cabeza cero, cilindro cero: ; kernel.asm [BITS 16] [ORG 0] mov al, 'H' ; Se mueve a al lo que se desea imprimir mov ah, 0x0E ; Se indica que se va a usar la opcion 0E de la interrupcion, para imprimir por pantalla mov bx, 0x0007 ; atributos de la impresion int 10h ciclar: jmp ciclar ; ciclo

Para compilar los archivos.asm simplemente hacemos uso del siguiente comanodo: nasm archivo.asm -o nombreCompilado. Usando el qemu podemos hacer pruebas de la siguiente forma, usando el comando: cat nombreCompilado | dd of=floppy conv=notrunc.