2016-06-26 6 views
1

私はx86リアルモードプログラミングを学んでおり、QEMUを使って小さなブートローダをテストしてテストしています。私は学習のためにGNUアセンブラを選択しました。ここでInt 10HがQEMUで動作しません

は、アセンブリコードです:

# 
# boot.s 
# 

.section .text 
.globl start 
start: 
//setup stack  
    mov  $0x7c0,  %ax 
    mov  %ax,  %ss 
    mov  $512,  %sp 

    //setup video 
    mov  $0x0,  %eax 
    mov  $0x0,  %al 
    int  $0x10 

    //print a character say 'm' 
    mov  $'m',  %al 
    mov  $0x0E,  %ah 
    int  $0x10 
1: 
    jmp 1b 

次のテキストがQEMUディスプレイに表示されます:ハードディスクからのブート

...

が問題:上記のメッセージが印刷され、それはnothiのように表示されますng。

私は組み立てに使用するスクリプト、リンクは次のとおりです。

> to assemble :  gcc -c boot.s 
> to link  :  ld -T link.ld boot.o -o b.bin 
> to put on bootsector of Hard-disk image 
    dd if=b.bin of=HD.img conv=notrunc 
> to attach boot magic 
    echo -ne "\x55\xaa" | dd seek=510 bs=1 of=HD.img 
> to emulate:  qemu-system-i386 HD.img 

私は1つを自分で作成する方法を知りませんでしたから、私はどこかで見たオンラインチュートリアルからコピーされたリンカスクリプト:

OUTPUT_FORMAT("binary") 
ENTRY(start) 
phys = 0x00100000; 
SECTIONS 
{ 
.text phys : AT(phys) { 
    code = .; 
    *(.text) 
    *(.rodata) 
    . = ALIGN(4096); 
} 
.data : AT(phys + (data - code)) 
{ 
    data = .; 
    *(.data) 
    . = ALIGN(4096); 
} 
.bss : AT(phys + (bss - code)) 
{ 
    bss = .; 
    *(.bss) 
    . = ALIGN(4096); 
} 
end = .; 
} 

追加の引数を指定する必要がありますか、コードに間違いがありますか?私はそれがスタックの設定だと思ったが、多くの可能性を試したが、うまくいかなかった。

ハードディスクのブートメッセージが表示され、ブートローダに文字「m」が表示されるようにするにはどうすればよいですか?

私の作業プラットフォームは、あなたのリンカスクリプトがプロテクトモードカーネルが0x00100000にロードされるだろう、環境のために書かれたと思われるのFedora 23

+1

「機能しない」とはどういう意味ですか?それは意味のある問題の説明ではありません。 –

答えて

7

です。これは、multiboot specificationに準拠したブートローダに共通です。あなたのようなリアルモードのブートローダは、ディスクの最初の512バイトから読み込まれ、メモリの0x7c00に配置されます。原点0x7c00を使用するリンカースクリプトが必要です。また、リンカースクリプトを使用して、起動ディスクの署名0xAA55を出力することもできます。

基本的なブートローダのリンカスクリプトは、このlink.ldのようなものになります:

OUTPUT_FORMAT("binary"); 
ENTRY(start); 
SECTIONS 
{ 
    . = 0x7C00; 
    .text : AT(0x7C00) { 
     *(.text); 
    } 
    .data : SUBALIGN(0) { 
     *(.data); 
     *(.rodata); 
    } 
    .bss : SUBALIGN(4) { 
     __bss_start = .; 
     *(COMMON); 
     *(.bss) 
     . = ALIGN(4); 
     __bss_end = .; 
    } 
    __bss_sizel = SIZEOF(.bss)>>2; 
    __bss_sizeb = SIZEOF(.bss); 

    /* Boot signature */ 
    .sig : AT(0x7DFE) { 
     SHORT(0xaa55); 
    } 
} 

あなたboot.sを16ビット・コードを生成するように指示されていません。アセンブラファイルの先頭にディレクティブ.code16を配置して、16ビット命令の生成を強制することができます。また、GCCコマンドを16ビットコードとしてコンパイルするように修正する必要があり、リンカには-melf_i386オプションが必要です。

あなたのブートローダコードは実際にはDSレジスタとスタックを設定する必要があります。リンカースクリプトはコードがメモリ位置0x07c00にあると想定しているので、DSをゼロに設定する必要があります。 segmented modelでは、物理アドレス=(セグメント< <4)+オフセットです。 DSは0に設定され、0x7c00の起点(ベースオフセット)は(0 < < 4)+ 0x7c00 =物理アドレス0x07c00にマッピングされます。これは、BIOSによってブートローダがロードされる場所です。

私はいくつかの価値があるかもしれないgeneral bootloader tipで答えを書きました。 、組み立てリンクとあなたが使用できるディスクイメージを生成するには

# 
# boot.s 
# 

.code16 
.section .text 
.globl start 
start: 
    //setup stack 
    mov  $0x7c0, %ax 
    mov  %ax, %ss 
    mov  $512, %sp 

    xor  %ax, %ax # AX = 0 
    mov  %ax, %ds # Set DS = 0 since origin point is 0x7c00 

    //setup video 
    xor  %ax, %ax # Zero 16-bit AX register (includes AL and AH) 
    //mov $0x0, %ax # Works but is not preferred for zeroing a reg 
    int  $0x10 

    //print a character say 'm' 
    mov  $'m',  %al 
    mov  $0x0E,  %ah 
    int  $0x10 
1: 
    jmp 1b 

gcc -c boot.s -m16 
ld -melf_i386 -T link.ld boot.o -o b.bin -nostdlib --nmagic 
dd if=b.bin of=HD.img conv=notrunc 

あなたはフロッピーとして画像を使用して、それを実行することができboot.sは、次のようになりクリーンアップ

qemu-system-i386 -fda HD.img 

または、ハードドライブイメージとして:

qemu-system-i386 -hda HD.img 
+0

それは本当にマイケル先生に働いてくれてありがとう、ありがとう、私はいくつかのvgaドライバとハードディスクのドライブを行うことができますいくつかの文書(ATA、SATA、PCI IDEの)を指摘してください。私はGoogleでたくさんのものを検索したが、誰もがレディメイドコードを与える。 osdev.orgでもポートをプログラミングする方法ではありません。 –

+0

@Madhusoodan:ディスク関連のものについては、Ralf Brownのintterupt list http://www.ctyme.com/intr/cat-003.htmが良いスタートです。 VGAのものは広いです、あなたはそのためにGoogleにできるはずです。 –

+0

いいえ私はもうBIOSに依存したくないし、Linuxや他のソースからそれをコピーしたくない。 –

関連する問題