2011-05-12 74 views
2

我正在爲教育用途寫一個引導程序,它會退出。但是當我試圖在真機上啓動時,我的磁盤讀取代碼無法加載某些扇區。沒有給出錯誤代碼也不是CF集合。它也返回1,這意味着1個扇區已被讀取(應該是正確的)。但是,當我嘗試跳到裝入的扇區時,它只是掛起,什麼也不做。第一階段打印出一個A,第二階段用F覆蓋。當用真實硬件啓動時,只顯示A.因此,該部門是不是在內存中,應該是..BIOS詮釋0x13失敗,沒有錯誤

這是我的MBR:

LOADOFF equ 0x7C00 
BUFFER equ 0x600 

[bits 16] 
[org 0x7c00] 

jmp _start 
nop 
    bootdisk db 0 

_start: ; entry point 
    jmp 0x0:.flush 
.flush: 
    xor ax, ax 
    mov ds, ax 
    mov es, ax 
    cli 
    mov ss, ax 
    mov sp, LOADOFF  ; stack setup 
    sti 

    mov [bootdisk], dl ; boot drive number given by the bios in dl 

    mov si, migrate ; move the code below to the buffer 
    mov di, BUFFER 
    mov cx, 256 
    cld 
    rep 
    movsw 

    jmp 0x0:BUFFER ;get my ass in the buffer 
migrate: 

.reset: 
    xor ax, ax  ; reset the disk 
    mov dl, [bootdisk] 
    int 0x13 
    jc .reset 

.read: 
    mov ah, 0x2 
    mov al, 1 ; read 1 sector 
    xor cx, cx ; cylinder 0 
    mov cl, 2 ; sector 2 
    mov dl, [bootdisk] 
    xor dh, dh ; head 0 


    ; setup buffer 
    xor bx, bx 
    mov es, bx 
    mov bx, 0x7c00 ; chain load it 
    int 0x13 
    jc .read 

    test ah, ah 
    jnz .reset 

    cmp al, 0x1 ; is there one and only one sector loaded? 
    jne .reset 

    mov ax, 0xb800 
    mov es, ax 
    xor di, di 
    mov al, 65 ; capital A 
    mov ah, 0xc 
    stosw 

; mov ax, 0x7c0 
; mov es, ax 
; xor di, di 
; 
; mov [es:di], byte 191   ; this code proves that my far jump does its work 
; mov [es:di+1], byte 160  ; if you would like to test, comment it out. 
; mov [es:di+2], byte 128 
; mov [es:di+3], byte 184 
; mov [es:di+4], byte 0 
; mov [es:di+5], byte 176 
; mov [es:di+6], byte 142 
; mov [es:di+7], byte 192 
; mov [es:di+8], byte 184 
; mov [es:di+9], byte 88 
; mov [es:di+10], byte 14 
; mov [es:di+11], byte 171 

    jmp 0x0:0x7c00  ; execute the loaded sector 

times 510 - ($ - $$) db 0 
dw 0xAA55 

ORG 0x7C00 
[BITS 16] 

第2階段:

stage2: 
    mov ax, 0xb800 
    mov es, ax 
    xor di, di 
    mov al, 70 
    mov ah, 0xc 
    stosw 
    jmp $ 

times 512 - ($ - $$) db 0 

它完美的KVM,但不是在真正的硬件與真正的BIOS。我使用USB閃存驅動器在真實硬件上測試引導。

難道問題是我沒有在我的mbr的第一個字節處定義的BPB?我不這麼認爲,因爲我剛剛讀了原始部門。如果我錯了,請糾正我。

任何人都知道它可能是什麼?

謝謝

+2

我認爲,根據您的BIOS,您的USB密鑰可能不被視爲軟盤驅動器...嘗試搜索如何從USB設備啓動。這個過程可能會有所不同。 – Macmade 2011-05-12 19:04:20

+0

不用bios模擬它作爲一個硬盤。我還發現int 0x13會將一個扇區加載到正確的地址,但不知何故,當我跳到它時,它不會執行。 – Bietje 2011-05-12 23:11:52

+0

儘管這個問題很老,但我很想知道用什麼程序將代碼放在USB閃存驅動器上?這是在Windows上完成的嗎? – 2015-12-01 15:51:33

回答

2

您的代碼嘗試從磁盤0加載「第一軟盤驅動器」。現代HDD(和USB閃存盤)通常以磁盤0x80訪問。所以,只是嘗試

bootdisk db 0x80 
在你的代碼

+0

雖然它不會傷害到將bootdisk變量硬編碼爲0x80以確保BIOS非常健全,但它確實看起來像@Bietje通過移動bl(它應該包含當前引導的設備的設備號)來做正確的事情,首先進入變量。 – 2011-06-13 20:11:36

+1

或者更好的辦法是,使用由DL寄存器中的BIOS本身傳遞給引導加載程序的值。它應該是從BIOS加載的啓動扇區的驅動器號。在使用自己的中斷13h加載引導扇區後,它只是將該數字留在那裏。之後,該值僅保留在DL中,引導加載程序可以使用它來知道它已從哪個驅動器啓動。 – SasQ 2015-02-05 05:03:15

+1

另外,如果您希望引導加載程序獨立於從其引導的設備,請在調用int 13h函數08h時使用DL中的該值來獲取驅動器的幾何結構。例如,如果您從HDD或pendrive啓動,它可能與軟盤的標準80:2:18 CHS幾何形狀不同。 – SasQ 2015-02-05 05:07:27