2010-01-14 129 views
9

我寫了簡單的第一階段啓動加載程序,它使用中斷向BIOS顯示「Hello world」。現在作爲編寫第二階段的下一個顯而易見的步驟,但是代碼應該存在以及如何從第一階段加載它?如何從第一階段加載第二階段啓動加載器?

下面是第一階段的程序

[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

你是用C語言?任何其他您可以分享的重要信息? – 2010-01-14 15:53:22

+0

,我們一直使用第一架組件的x86指令,但我們r打算寫第二階段在更高層次語言如C ..我在哪裏存儲第二階段二進制以及如何從第一階段的引導加載程序加載[加載內核的 – Xinus 2010-01-14 16:15:23

+0

可能的複製從組件(NASM)(http://stackoverflow.com/questions/1551240/loading-kernel-from-assembly-nasm) – 2015-10-28 18:14:36

回答

6

在x86上,你會做以下(簡化):

  • 有引導程序加載磁盤/軟盤的第n個部門(無論你從哪裏啓動)到內存中並執行它(即加載段/偏移量,並執行retf)。一個更好的選擇是在文件系統中搜索某個文件名(例如KERNEL.BIN) - 但是你需要知道文件系統類型(例如,如果你是從軟盤映像進行測試,則爲FAT12)。
  • 內核然後會以實模式啓動。它設置代碼描述符,GDT等等,激活32位尋址(您應該聽說過「A20」)並最終進入保護模式。然後你需要遠程跳轉到一個32位的代碼段(內核文件必須以32位代碼處於絕對位置的方式連接在一起,例如在偏移512處,緊跟在16位實模式之後) 。
  • 然後,32位內核程序集僅定義了EXTERN _mykernel並調用該符號。
  • 然後,你可以開始編寫你的內核作爲C函數mykernel

好吧,這是我幾年前做的一個簡短的概述(有很多從互聯網複製&粘貼;)。如果這是沒有幫助的,下面是OS開發一些好的網絡資源:

希望幫助^^

+1

感謝第一個鏈接 – Xinus 2010-01-17 17:12:58

1

看看這裏的GRUB實現(階段1):

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

首先注意到起始點爲0x7c00,結束簽名爲0xaa55,這是第一個扇區。從拆解中,U可以看到這一點:

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 

本質的邏輯是第2階段代碼複製到內存的另一部分,並且跳躍後,直接出現,那就是「啓動階段2 」。換句話說,「啓動階段1」在將扇區加載到內存後從BIOS中有效觸發,而階段2則是您跳到那裏的地方 - 它可以在任何地方。

+0

如何彙編知道,所有的代碼標籤從裝磁盤現在可以通過加載到RAM中的任何位置來抵消? – 2015-05-17 21:21:54

3

加載階段2並跳轉到它

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 

編譯並執行最少的可運行NASM BIOS例如:

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

預期結果:a被打印在屏幕上,然後將程序暫停。

測試在Ubuntu 14.04。

使用接頭腳本和更正確的初始化(段寄存器,棧)on my GitHub理智GAS例子。

+0

如果有人可以猜測爲什麼downvote,請這樣做,我可以學習和改進信息。我從不報復。 – 2015-10-05 11:54:35

+0

啊,我正在瀏覽'bootloader'標籤活動列表,我看到我們再次見面。我會做的一個觀察是,我可能會把這個問題的範圍過寬。雖然您提供了一個解決方案,但您聲稱OP將在MBR之後從下一個扇區加載。儘管這是一個解決方案,但我認爲upvoted在討論其他想法時更接近標準,例如爲文件系統進行文件查找。這個答案假設了很多東西 - 是否有包含第二階段的文件系統?它是什麼文件系統?等... – 2015-10-05 19:34:37

+0

@MichaelPetch嘿再次:-)同意這是一個很好的答案。只是我通常喜歡先運行一些東西,看看它的美麗程度,然後讓它更容易理解以後的更深層次的部分。 – 2015-10-05 19:44:06