En aquest tema, aprendrem a escriure un bootloader simple en llenguatge Assembly. Un bootloader és un programa petit que s'executa quan l'ordinador s'encén i carrega el sistema operatiu a la memòria. Aquest exercici ens ajudarà a comprendre millor com funciona el procés d'arrencada d'un ordinador i com interactuar directament amb el maquinari.

Objectius

  • Entendre el concepte de bootloader.
  • Escriure un bootloader simple en Assembly.
  • Carregar i executar el bootloader en un entorn d'emulació.

Requisits Previs

  • Coneixements bàsics de llenguatge Assembly.
  • Entorn de desenvolupament configurat per a Assembly.
  • Familiaritat amb eines d'emulació com QEMU o Bochs.

Conceptes Clau

Què és un Bootloader?

Un bootloader és un programa que s'executa quan l'ordinador s'encén. La seva funció principal és carregar el sistema operatiu a la memòria i transferir-li el control. Els bootloaders es troben en el primer sector del disc dur, conegut com el Master Boot Record (MBR).

Estructura del Bootloader

Un bootloader simple en Assembly ha de complir amb els següents requisits:

  • Ha de ser de 512 bytes o menys.
  • Ha de tenir una signatura específica (0x55AA) als últims dos bytes per ser reconegut pel BIOS.

Escriure el Bootloader

Codi del Bootloader

A continuació, es mostra un exemple de codi Assembly per a un bootloader simple que mostra un missatge a la pantalla:

[BITS 16]          ; Indica que el codi és de 16 bits
[ORG 0x7C00]       ; Indica l'adreça d'origen del codi

start:
    mov si, msg    ; Carrega l'adreça del missatge a SI
    call print_string

hang:
    jmp hang       ; Bucle infinit per mantenir el bootloader en execució

print_string:
    mov ah, 0x0E   ; Funció de BIOS per imprimir caràcters
.next_char:
    lodsb          ; Carrega el següent byte de la cadena a AL
    cmp al, 0      ; Comprova si és el final de la cadena
    je .done       ; Si és zero, finalitza
    int 0x10       ; Crida a la interrupció de BIOS per imprimir el caràcter
    jmp .next_char ; Continua amb el següent caràcter
.done:
    ret            ; Retorna al punt de crida

msg db 'Hello, World!', 0  ; Missatge a imprimir

times 510-($-$$) db 0      ; Omple amb zeros fins a 510 bytes
dw 0xAA55                  ; Signatura de boot (0x55AA)

Explicació del Codi

  • [BITS 16] i [ORG 0x7C00]: Indiquen que el codi és de 16 bits i que s'executarà a l'adreça 0x7C00, on el BIOS carrega el bootloader.
  • start:: Etiqueta d'inici del codi.
  • mov si, msg: Carrega l'adreça del missatge a SI.
  • call print_string: Crida a la subrutina per imprimir la cadena.
  • hang:: Bucle infinit per mantenir el bootloader en execució.
  • print_string:: Subrutina per imprimir una cadena de caràcters.
  • msg db 'Hello, World!', 0: Defineix el missatge a imprimir.
  • times 510-($-$$) db 0: Omple amb zeros fins a 510 bytes.
  • dw 0xAA55: Signatura de boot (0x55AA).

Carregar i Executar el Bootloader

Utilitzant QEMU

QEMU és una eina d'emulació que ens permet provar el nostre bootloader sense necessitat de maquinari físic.

  1. Guarda el codi Assembly en un fitxer anomenat bootloader.asm.
  2. Assembla el codi utilitzant NASM:
    nasm -f bin -o bootloader.bin bootloader.asm
    
  3. Executa el bootloader utilitzant QEMU:
    qemu-system-x86_64 -drive format=raw,file=bootloader.bin
    

Utilitzant Bochs

Bochs és una altra eina d'emulació que es pot utilitzar per provar el bootloader.

  1. Guarda el codi Assembly en un fitxer anomenat bootloader.asm.
  2. Assembla el codi utilitzant NASM:
    nasm -f bin -o bootloader.bin bootloader.asm
    
  3. Configura Bochs per carregar el fitxer bootloader.bin i executa'l.

Exercicis Pràctics

Exercici 1: Modificar el Missatge

Modifica el codi del bootloader per mostrar un missatge diferent a la pantalla.

Exercici 2: Afegeix una Segona Cadena

Modifica el codi per imprimir una segona cadena després de la primera.

Exercici 3: Interacció amb l'Usuari

Modifica el codi per esperar una tecla de l'usuari abans de mostrar el missatge.

Solucions

Solució a l'Exercici 1

msg db 'Welcome to Assembly!', 0  ; Nou missatge a imprimir

Solució a l'Exercici 2

start:
    mov si, msg1
    call print_string
    mov si, msg2
    call print_string
    jmp hang

msg1 db 'Hello, World!', 0
msg2 db 'Welcome to Assembly!', 0

Solució a l'Exercici 3

start:
    call wait_for_key
    mov si, msg
    call print_string
    jmp hang

wait_for_key:
    mov ah, 0
    int 0x16  ; Espera una tecla
    ret

msg db 'Hello, World!', 0

Conclusió

En aquest tema, hem après a escriure un bootloader simple en llenguatge Assembly, carregar-lo i executar-lo en un entorn d'emulació. Hem explorat conceptes clau com la signatura de boot i la interacció amb el BIOS. Els exercicis pràctics ens han ajudat a reforçar els conceptes apresos i a experimentar amb modificacions del codi. En el proper tema, aprofundirem en la creació d'un nucli bàsic de sistema operatiu.

© Copyright 2024. Tots els drets reservats