簡體   English   中英

我正在構建自己的引導程序,當我使用qemu對其進行仿真時,我得到“引導失敗:無法讀取引導盤”

[英]I'm building my own bootloader and when I emulate it using qemu I get “Boot failed: could not read the boot disk”

我正在構建自己的引導程序,當我使用qemu對其進行仿真時,我得到“引導失敗:無法讀取引導盤”。 它的工作方式如下:第一階段加載第二階段,然后第二階段引導加載程序加載內核。 一切看起來都很好,但是我一直在收到該消息,但沒有任何工作像它應該的那樣。

這是我的第一階段引導程序的代碼:我正在構建自己的引導程序,當我使用qemu模擬它時,我得到“引導失敗:無法讀取引導盤”。

org 0x7C00
jmp 0x0000:start

string db 'Bootloader by JCLC - GMM4 - RGT!', 13, 10, 0

    start:
    ;Setup stack segments
    mov ax,cs              
    mov ds,ax  
    mov es,ax              
    mov ss,ax
    mov sp, 0x7c00

    xor ax, ax
    mov ds, ax

    xor ax, ax
    mov ds, ax
    mov si, string
    mov cl, 0

    printString:
    lodsb                                
    cmp cl, al                          
    je done

    mov ah, 0xe    
    mov bl, 2      
    int 10h            

    jmp printString

    done:

    mov ah, 0x02
    mov al, 1
    mov dl, 0x80
    mov ch, 0
    mov dh, 0   
    mov cl, 2
    mov bx, 0x7E00
    int 0x13

    jmp 0x7E00  

    times ((0x200 - 2) - ($ - $$)) db 0x00
    dw 0xAA55

這是我第二階段引導程序的代碼:

org 0x7E00

    mov ax,cs              
    mov ds,ax  
    mov es,ax              
    mov ss,ax
    mov sp,0x7E00

    xor ax, ax
    mov ds, ax    

    mov ah, 0x500
    mov al, 1
    mov dl, 0x80
    mov ch, 0
    mov dh, 0   
    mov cl, 2
    mov bx, 0x500
    int 0x13

    jmp 0x500 

    times ((0x200 - 2) - ($ - $$)) db 0x00
    dw 0xAA55

這就是內核。 這只是我寫的文章,以查看Everythig是否按預期工作。

org 0x500

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

    cli
    hlt

    ; Pad image to multiple of 512 bytes.

times ((0x200 - 2) - ($ - $$)) db 0x00

您的代碼有很多問題。 您在原始的boot1.asm有此boot1.asm

    jmp 0x0000:start
string db 'Bootloader by JCLC - GMM4 - RGT!', 13, 10, 0
    ;Setup stack segments
    mov ax,cs              
    mov ds,ax  
    mov es,ax              
    mov ss,ax
    mov sp, 0x7c00
start:

您應該在string定義之后start ,以便正確設置所有段。

當BIOS將控制權轉移到引導加載程序時, DL包含可用於磁盤操作的引導驅動器號,例如Int 13h / AH = 2 (磁盤讀取)。 mov dl, 0x80硬編碼驅動器號mov dl, 0x80強制您始終從硬盤1引導(0x00 =軟盤A,0x01 =軟盤B,0x80 =硬盤1,0x81 =硬盤2)。 您可以簡單地從第一級和第二級磁盤讀取中刪除mov dl, 0x80 ,因為您在任何時候都不會銷毀DL ,它仍然是BIOS傳遞的值。

如果您閱讀拉爾夫·布朗的Int 0x13 / AH = 2的中斷列表,則會發現:

磁盤-將扇區讀入內存

 AH = 02h AL = number of sectors to read (must be nonzero) CH = low eight bits of cylinder number CL = sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only) DH = head number DL = drive number (bit 7 set for hard disk) ES:BX -> data buffer 

返回:

 CF set on error if AH = 11h (corrected ECC error), AL = burst length CF clear if successful AH = status (see #00234) AL = number of sectors transferred (only valid if CF set for some BIOSes) 

boot1.asmboot2.asm您錯誤地設置了AH AH應該為2以進行磁盤讀取。

boot2.asm您讀取了錯誤的扇區號。 你有:

    mov cl, 2

您要從磁盤讀取第三個扇區。 它應該是:

    mov cl, 3

考慮到所有這些,您的文件將如下所示:

boot1.asm

org 0x7C00
jmp 0x0000:start

string db 'Bootloader by JCLC - GMM4 - RGT!', 13, 10, 0

    start:    
    ;Setup stack segments
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov sp, 0x7c00

    mov si, string
    mov cl, 0

    printString:
    lodsb
    cmp cl, al
    je done

    mov ah, 0xe
    mov bl, 2
    int 10h

    jmp printString

    done:

    mov ah, 2       ; Int 13h/AH=2 = disk read
    mov al, 1
    ;mov dl, 0x80   ; Comment out - use value passed by BIOS in DL
    mov ch, 0
    mov dh, 0
    mov cl, 2
    mov bx, 0x7E00
    int 0x13

    jmp 0x7E00

    times ((0x200 - 2) - ($ - $$)) db 0x00
    dw 0xAA55

boot2.asm

org 0x7E00

    mov ax,cs
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov sp,0x7E00

    xor ax, ax
    mov ds, ax

    mov ah, 2        ; Int 13h/AH=2 = disk read 
    mov al, 1
    ; mov dl, 0x80   ; Comment out - use value passed by BIOS in DL
    mov ch, 0
    mov dh, 0
    mov cl, 3        ; You want to read sector 3 (not 2)
    mov bx, 0x500
    int 0x13

    jmp 0x500

    times ((0x200 - 2) - ($ - $$)) db 0x00
    dw 0xAA55

kernel.asm

org 0x500

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

    cli
    hlt

    ; Pad image to multiple of 512 bytes.

times ((0x200 - 2) - ($ - $$)) db 0x00

當我通過您的Makefile運行此Makefile ,將其作為QEMU中的輸出輸出:

在此處輸入圖片說明


調試引導程序

調試引導程序的最佳工具是BOCHS而不是QEMU BOCHS具有一個內置的調試器,該調試器對諸如引導程序之類的實模式代碼有很好的支持。


引導程序提示

我有一個Stackoverflow答案,其中包含許多Bootloader開發技巧

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM