2011-10-10 6 views
4

最近、私はブートローダの仕組みにハングアップしようとしています。 私はローダーをnasmアセンブラに書いていて、ボッチとフロッピーイメージでテストしています。ブートローダの第2段階を読み込んで起動する

ステージ1と2のコンパイル済みバイナリは、コピーによって1つのイメージに結合されます。 この画像は私が望むのとまったく同じです。 512Bytesのステージ1コード(マジックナンバーが含まれており、うまくロードされます)と第2セクタの512ステージ2コード。

しかし、私の問題はセクターをラムにロードしてそれに飛び込んでいると思います。私のコードに何か問題がありますか?

Stage1.asm

BITS 16 
start: 
    mov ax, 07C0h ; Set up 4K stack space after this bootloader 
    add ax, 288  ; (4096 + 512)/16 bytes per paragraph 
    mov ss, ax 
    mov sp, 4096 

    mov ax, 07C0h ;Set data segment to where we're loaded 
    mov ds, ax 

    mov si,s_version 
    call print_string 

    ; ## Load stage2 
    mov si,s_loading 
    call print_string 

    xor ax,ax 
    xor bx,bx 
    xor cx,cx 
    xor dx,dx 

    ;read 2nd sector 
    mov ah,02h 
    mov al,1 ;read 1 
    mov ch,0 ;on track 0 
    mov cl,2 ;2nd sector 
    mov dh,0 ;head 1 
    mov dl,0 ;from floppy a  

    mov bx,09C0h;destination segment 
    mov es,bx 

    mov bx,0 ;destination offset 

    int 13h ;<-- Fails right here 

    mov si,s_sector 
    call print_string 

    ;print number of read sectors 
    add ax, 48 
    mov ah, 0Eh 
    int 10h 
    mov al, 21 
    mov ah, 0Eh 
    int 10h 

    ;print the sector's magicnumber (debugging purposes) 
    mov al, [09C0h+511] 
    int 10h 

    xor ax,ax 
    int 16h 

    mov si,s_jumping 
    call print_string 

    call word 09C0h:0000h 

; #### print a string from si 
print_string: 
    push ax 
    push bx 
    mov ah, 0Eh 
    .repeat: 
     lodsb 
     cmp al, 0 
     je .exit 
     int 10h 
    jmp .repeat 
    .exit: 
    pop bx 
    pop ax 
ret 
; **** 

; #### define strings  
s_version db 'VeOS 0.0.0.1',10,13,0 
s_loading db 'Loading Stage2...',10,13,0 
s_sector db 'Loading sector...',10,13,0 
s_jumping db 'Passing control to Stage2.',10,13,0 
; **** 

;fillup with zeros 
times 510-($-$$) db 0 
;boot signature 
dw 0xAA55 

stage2.asm

BITS 16 
start: 
    mov ax, 09C0h ; Set up 4K stack space after this bootloader 
    add ax, 288  ; (4096 + 512)/16 bytes per paragraph 
    mov ss, ax 
    mov sp, 4096 

    mov ax, 09C0h ;Set data segment to where we're loaded 
    mov ds, ax 

    mov ah, 0Eh 
    mov al, 21  ;"!" 
    int 10h 

    mov ah, 00h 
    int 16h 

    jmp $ 


times 511-($-$$) db 0 
;Magicnumber for debugging 
db 0x41 

私は徹底的にGoogleで検索し、RAMにセクターをロードし、そこにジャンプする方法を正確に記述し、何も見つかりませんでした。 2番目のセクターのMagicnumberさえ私のプログラマーによって発見されていません。

アドレス上の誤算の場合には大丈夫でしょうか。

更新: 現在のソースコード、ロックアップを行っている行がマークされています。私は純粋なパラノイアのうち4つのメインレジスタを0に設定しました。

更新2: また、現在のバージョン。レジスタの設定とint 13hの発行の間に何もしませんでした。

答えて

3

アップデート:下記のほかに、読み込み時にスタックを上書きしています!

あなたのスタックが08E0h:1000h = 09E0h:0000hある07C0h + 288 : 4096にあり、あなたは、スタックを上書き(09E0h:0000hで終わる)512バイト前方09C0h:0000に読んで、としています。スタックを移動するか、別の場所に読み込みます。インスピレーションについては、memory map from osdev.orgを参照してください。

私は良いステップバイステップのデバッガを知りません。私はちょうどjmp $-2命令をコードに置き、適切なポイントで "情報レジスタ"を行うためにQEMUs組み込みデバッガを使いました。私はBochsが類似したものを持っているかもしれないと思います。

スリー(2.5)私は(もっとあるかもしれませんが)を参照のこと:

;read 2nd sector 
    mov ah,02h 
    mov al,1 ;read 1 
    mov ch,0 ;on track 0 
    mov cl,1 ;2nd sector 
    mov dl,0 ;from floppy a 
    mov bx,09C0h ;destination 
    mov es,bx 
    int 13h 
  • あなたは09c0hとしてbxを残しているので、それが09C0h:09C0hではなく09C0h:0000hに読み込みます。
  • あなたは第2セクター(cl = 1)から読んでいると言っていますが、最初の読者から読んでいます! Ralph Brownを参照してください。
  • dh(頭)を設定していません。 Bochsではおそらく問題ありませんが、最初の条件が保証されていることを私の頭の上から思い出すことはできません。dl being set to the drive number

小さなテストカーネル(osdev.orgのさまざまな部分から取得したもので、私が導入したエラーがあるかもしれないので、注意してください)のために使用したブートローダは、次のとおりです。 。(私はdlをそのまま残しています。なぜなら、ブートドライブが入っているのでハードコードする必要がないからです)。

 bits 16 
     org 0x7c00 

Start: jmp EntryPoint 

PrintString16: 
     pusha 
.PrintLoop: 
     lodsb 
     or al, al 
     jz .PrintDone 
     mov ah, 0xe 
     int 0x10 
     jmp .PrintLoop 
.PrintDone: 
     popa 
     ret 

EntryPoint: 
     xor ax, ax 
     mov ss, ax 
     mov ds, ax 
     mov sp, 0x7c00 
.DiskReset: 
     mov ah, 0 
     int 0x13 
     jc .DiskReset 
     mov ax, 0x50 ; load to 0x500 linear address. It has unused space up to 0x7bff 
     mov es, ax 
     xor bx, bx 
     mov ax, 0x023B ; count = 0x3b = 59, the maximum (while still leaving soom room for the stack and the boot sector code we're currently running) 
     mov cx, 0x0002 
     xor dh, dh ; leave dl intact 
     int 0x13 
     jnc .ReadDone 
     mov si, ReadError 
     call PrintString16 
     jmp .DiskReset 
.ReadDone: 
     ;jmp 0x50:0x0 ;jump to stage 2 loaded at 0x500 

     cli 
     xor ax, ax 
     mov ds, ax 
     mov es, ax 
     mov ax, 0x9000 
     mov ss, ax 
     mov sp, 0xffff 
     sti 

     mov si, HelloMsg 
     call PrintString16 

     ; Disable interrupts until safely in protected mode 
     cli 

     ; Install GDT 
     lgdt [toc] 

     ; Enable A20 
     mov al, 0xdd 
     out 0x64, al 

     mov si, GoPMode 
     call PrintString16 

     ; enable protected mode 
     mov eax, cr0 
     or eax, 1 
     mov cr0, eax 

     jmp 0x8:PmodeStart  
     bits 32 
PmodeStart: 
     ; setup stack and datasegments 
     mov ax, 0x10 
     mov ds, ax 
     mov es, ax 
     mov fs, ax 
     mov gs, ax 
     mov ss, ax 

     ; Setup stack at 0x90000 
     mov esp, 0x90000 

     ; Jump to C-code 
     jmp 0x8:0x500 

     ; Reboot if C-code returns 
Reboot: 
     mov word [0x472], 0x1234 
     jmp 0x8:0xffff0 


ReadError db 'Read error - retrying...', 13, 10, 0 
HelloMsg db 'Loading...',0 
GoPMode db 'Entering protected mode..',0 
gdt_data: 
     dd 0       ; null descriptor 
     dd 0 

; gdt code:        ; code descriptor 
     dw 0FFFFh      ; limit low 
     dw 0       ; base low 
     db 0       ; base middle 
     db 10011010b     ; access 
     db 11001111b     ; granularity 
     db 0       ; base high 

; gdt data:        ; data descriptor 
     dw 0FFFFh      ; limit low (Same as code)10:56 AM 7/8/2007 
     dw 0       ; base low 
     db 0       ; base middle 
     db 10010010b     ; access 
     db 11001111b     ; granularity 
     db 0       ; base high 

end_of_gdt: 
toc: 
     dw end_of_gdt - gdt_data - 1 ; limit (Size of GDT) 
     dd gdt_data      ; base of GDT 


times 510 - ($-$$) db 0 ; pad to 512 bytees, will also warn if we exceed 512 bytes 

     dw 0xAA55 ; boot signature 
+0

あなたが言ったように、私はbx = 0とcl = 2に設定しました。今bochs(または私のコード)は、int 13hを実行する瞬間にロックアップします。仮想フロッピーのBochsステータスは「読み込み中」のままであり、何も起こりません。 これまでのご協力ありがとうございます。あなたのコードを見てみましょう。 – vikenemesh

+0

'dh = 0'また、' es'を '09c0h'に設定した後に' bx'をゼロに設定していることを明確にするには、そうですか?その動作は、割り込みテーブルを上書きしたように聞こえるためです。どのような場合でも、更新されたソースコードで質問を更新してみてください。 – user786653

+0

更新されたソースコードについては上記を参照してください。 – vikenemesh

関連する問題