2010-01-14 9 views
9

Ho scritto un semplice bootloader di primo livello che mostra "Ciao mondo" usando l'interruzione al BIOS. Ora come un passo successivo ovvio per scrivere una seconda fase, ma dove dovrebbe esistere il codice per quello e come caricarlo dal primo stadio?Come caricare il boot loader di seconda fase dal primo stadio?

Ecco un programma per la prima fase

[BITS 16] ;Tells the assembler that its a 16 bit code 
[ORG 0x7C00] ;Origin, tell the assembler that where the code will 
       ;be in memory after it is been loaded 

MOV SI, HelloString ;Store string pointer to SI 
CALL PrintString ;Call print string procedure 
JMP $  ;Infinite loop, hang it here. 


PrintCharacter: ;Procedure to print character on screen 
    ;Assume that ASCII value is in register AL 
MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen. 
MOV BH, 0x00 ;Page no. 
MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background 

INT 0x10 ;Call video interrupt 
RET  ;Return to calling procedure 



PrintString: ;Procedure to print string on screen 
    ;Assume that string starting pointer is in register SI 

next_character: ;Lable to fetch next character from string 
MOV AL, [SI] ;Get a byte from string and store in AL register 
INC SI  ;Increment SI pointer 
OR AL, AL ;Check if value in AL is zero (end of string) 
JZ exit_function ;If end then return 
CALL PrintCharacter ;Else print the character which is in AL register 
JMP next_character ;Fetch next character from string 
exit_function: ;End label 
RET  ;Return from procedure 


;Data 
HelloString db 'Hello World', 0 ;HelloWorld string ending with 0 

TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0 
DW 0xAA55   ;Add boot signature at the end of bootloader 
+0

Stai utilizzando il linguaggio C? Qualche altra informazione importante che puoi condividere? –

+0

abbiamo usato le istruzioni assembly x86 per il primo stadio, ma stiamo progettando di scrivere il secondo stadio nel linguaggio di livello superiore come c .. dove immagazzino quel binario di secondo stadio e come caricarlo dal bootloader di primo stadio – Xinus

+0

Possibile duplicato di [Caricamento kernel from assembly (NASM)] (http://stackoverflow.com/questions/1551240/loading-kernel-from-assembly-nasm) –

risposta

6

Su x86 si dovrebbe fare quanto segue (semplificato):

  • Avere il bootloader caricare il settore n-esimo del disco/floppy (ovunque tu stia effettuando il boot da) in memoria ed eseguilo (es. carica segmento/offset e fai retf). Un'alternativa migliore è quella di cercare nel file system un determinato nome di file (ad esempio KERNEL.BIN), ma è necessario conoscere il tipo di file system (ad esempio FAT12 se si esegue il test da un'immagine floppy).
  • Il kernel dovrebbe quindi avviarsi in modalità reale. Imposta i descrittori di codice, GDT e così via, attiva l'indirizzamento a 32 bit (dovresti aver sentito parlare di "A20") e infine entra in modalità protetta. Quindi è necessario un salto in lungo verso un segmento di codice a 32 bit (il file del kernel deve essere collegato insieme in modo che il codice a 32 bit sia in una posizione assoluta, ad esempio con offset 512, subito dopo la modalità reale a 16 bit) .
  • L'assembly del kernel a 32 bit, quindi, definisce semplicemente EXTERN _mykernel (ad esempio) e chiama tale simbolo.
  • Quindi è possibile iniziare a scrivere il kernel come funzione C mykernel.

Va bene questa era una breve panoramica di ciò che ho fatto alcuni anni fa (con un sacco di copia & incolla da Internet;). Se questo non è disponibile, qui ci sono alcune buone risorse web su sviluppo OS:

Speranza che aiuta ^^

+1

Grazie per il primo collegamento – Xinus

1

Guardate l'attuazione di GRUB qui (fase 1):

http://src.illumos.org/source/xref/illumos-gate/usr/src/grub/grub-0.97/stage1/stage1.S

Prima notato il punto di partenza a 0x7c00 e la firma fine 0xAA55 per questo primo settore. Dall'interno lo smontaggio, u può vedere questo:

349 copy_buffer: 
350 movw ABS(stage2_segment), %es 
351 
352 /* 
353 * We need to save %cx and %si because the startup code in 
354 * stage2 uses them without initializing them. 
355 */ 
356 pusha 
357 pushw %ds 
358 
359 movw $0x100, %cx 
360 movw %bx, %ds 
361 xorw %si, %si 
362 xorw %di, %di 
363 
364 cld 
365 
366 rep 
367 movsw 
368 
369 popw %ds 
370 popa 
371 
372 /* boot stage2 */ 
373 jmp *(stage2_address) 
374 
375 /* END OF MAIN LOOP */ 
376 

Essenzialmente la logica è copiare il codice fase 2 in un'altra parte della memoria, e dopo che passa direttamente lì, e cioè "boot stage2 ". In altre parole, "boot stage1" viene effettivamente attivato dal BIOS dopo aver caricato il settore in memoria, mentre stage2 è il punto in cui si salta lì - può essere ovunque.

+0

Come fa l'assemblatore a sapere che tutte le etichette per il codice caricate dal il disco viene ora spostato da qualsiasi punto della RAM? –

3

Minimal eseguibile esempio NASM BIOS che carica stadio 2 e salta ad esso

use16 
org 0x7C00 

    ; You should do further initializations here 
    ; like setup the stack and segment registers. 

    ; Load stage 2 to memory. 
    mov ah, 0x02 
    ; Number of sectors to read. 
    mov al, 1 
    ; This may not be necessary as many BIOS set it up as an initial state. 
    mov dl, 0x80 
    ; Cylinder number. 
    mov ch, 0 
    ; Head number. 
    mov dh, 0 
    ; Starting sector number. 2 because 1 was already loaded. 
    mov cl, 2 
    ; Where to load to. 
    mov bx, stage2 
    int 0x13 

    jmp stage2 

    ; Magic bytes.  
    times ((0x200 - 2) - ($ - $$)) db 0x00 
    dw 0xAA55 

stage2: 

    ; Print 'a'. 
    mov ax, 0x0E61 
    int 0x10 

    cli 
    hlt 

    ; Pad image to multiple of 512 bytes. 
    times ((0x400) - ($ - $$)) db 0x00 

compilare ed eseguire:

nasm -f bin -o main.img main.asm 
qemu-system-i386 main.img 

previsto risultato: a viene stampato allo schermo, e quindi la il programma si ferma.

Testato su Ubuntu 14.04.

Esempio di GAS Saner che utilizza uno script del linker e un'inizializzazione più corretta (registri di segmento, stack) on my GitHub.

+0

Se qualcuno può indovinare il motivo del downvote, per favore, posso imparare e migliorare le informazioni. Non ho mai reagito. –

+0

Ah, sto guardando attraverso la lista attiva dei tag 'bootloader' e vedo che ci incontriamo di nuovo. Un'osservazione che farò è che probabilmente avrei chiuso questa domanda come troppo ampia. Sebbene tu fornisca una soluzione, asserisci che l'OP si caricherà dal settore successivo dopo l'MBR. Anche se questa è una soluzione, penso che quella con upvoted sia più vicina al marchio nel discutere altre idee come fare una ricerca di file per il file system. Questa risposta presuppone anche molte cose: esiste un file system che contiene il 2 ° stadio? Che file system è? ecc ... –

+0

@MichaelPetch hey there again :-) Concordato che questa è una buona risposta. È solo che di solito mi piace prima ottenere alcune cose correndo per vedere la bellezza di esso: e quindi rende più facile capire le parti più profonde in seguito. –

Problemi correlati