あなたのコードは、あなたがそれを仮定することはできませんDSが0に設定されていることを前提としています。あなたがorg 0x7c00
を使用している場合は、あなたのコードの最初の部分は、明示的に0にDSを設定する必要があります。
SS:SPを設定して、スタックの定義を真剣に考えてください。あなたは、既存のものがどこにあるのか、またあなたがしようとしていることを処理するのに十分な大きさであるか分からない。
ブートローダが呼び出される直前に、BIOSはDLレジスタにブートデバイス番号を設定します。ブートドライブからドライブ要求を行うときにあなたのコード内で0にDLを設定すべきではありません。ブートローダが呼び出されたときに、DLに存在する値を使用しているはずです。
あなたはメモリ内に前進することを期待しLODSB命令を使用しているので、方向フラグをクリアするCLD命令を使用する必要があります。方向フラグが正しく設定されているため、必要な方向に明示的に設定する必要がありますので、CLD(前方)またはSTD(後方)に設定する必要があります。
私はGeneral Bootloader Tipsと私StackOverflowの答えでは上記の問題に関するより多くの情報を持っています。
BPBを使用していないので、ブートローダの最初の指示としてjmp start
を削除することを強くお勧めします。代わりに、コードの後でブートセクタの署名(0xAA55
)の前にデータを移動します。その理由は、ブートローダの最初の命令として表示されるJMP命令に基づいて、一部のBIOSがBPBを見つけようとし、メモリ内のブートローダの一部を上書きして、
はあなたのブートローダはあなたの第二段階は、第2のセクターからロードを開始し、この命令を使用しています。
jmp 0x0:0x1000
の問題は、あなたが設定ESのセクターを読んだとき:BXこの方法:
read_sector:
mov ax, 0x0
mov es, ax
xor bx, bx
を
これはES:BX〜0x0000:0x0000を設定します。これは、あなたのJMPがコードを期待する場所ではないことは明らかです。 にディスクセクタを読み込ませるメモリの場所にES:BXを設定する必要があります。
INT 13h/AH = 02hは、シリンダー/ヘッド/セクター番号を正しく設定する必要があります。セクタの番号は1で始まりますが、シリンダとヘッドはゼロベースです。
あなたに
mov ch, 01
:ディスクの第2のセクターは、シリンダ0、ヘッド0でセクター2であるあなたのコードでは、シリンダーはあなたが本当に0に設定されなければならないので、このコードが間違っている1の代わりに、0に設定します2番目の段階ではRET
命令で終了するため、print
を関数として作成しました。 jmp print
はcall print
に変更する必要があります。あなたのコードがあることを変更することができ、私の一般的なブートローダーの先端からのものを含む上記の推奨すべての変更、と
:
boot.asm
[bits 16]
[org 0x7c00]
; Use the boot drive number passed to us by BIOS in register DL
start:
xor ax,ax ; We want a segment of 0 for DS for this question
mov ds,ax ; Set AX to appropriate segment value for your situation
mov es,ax ; In this case we'll default to ES=DS
mov bx,0x8000 ; Stack segment can be any usable memory
mov ss,bx ; This places it with the top of the stack @ 0x80000.
mov sp,ax ; Set SP=0 so the bottom of stack will be @ 0x8FFFF
cld ; Set the direction flag to be positive direction
mov si, wolf_wel_msg
call wolf_print
mov si, wolf_kernel_load
call wolf_print
pushf
stc
mov ah,00
int 13h
read_sector:
mov ax, 0x0
mov es, ax ; ES = 0
mov bx, 0x1000 ; BX = 0x1000. ES:BX=0x0:0x1000
; ES:BX = starting address to read sector(s) into
mov ah, 02 ; Int 13h/AH=2 = Read Sectors From Drive
mov al, 01 ; Sectors to read = 1
mov ch, 00 ; CH=Cylinder. Second sector of disk
; is at Cylinder 0 not 1
mov cl, 02 ; Sector to read = 2
mov dh, 00 ; Head to read = 0
; DL hasn't been destroyed by our bootloader code and still
; contains boot drive # passed to our bootloader by the BIOS
int 13h
jc wolf_error
popf
jmp 0x0:0x1000
cli
hlt
wolf_error:
mov si, wolf_error_msg
call wolf_print
mov si, wolf_error_msg1
call wolf_print
mov ah,00
int 16h
xor ax,ax
int 19h
wolf_print:
lodsb
or al,al
jz exit
mov ah,0x0e
int 10h
jmp wolf_print
exit:
ret
; Moved the data before the boot signature but after the code
wolf_wel_msg db 'Welcome to Bootloader!!!',0x0D,0x0A,0
wolf_kernel_load db 'Loading kernel....',0x0D,0x0A,0
wolf_error_msg db 'Kernel.bin not found!',0x0D,0x0A,0
wolf_error_msg1 db 'Press any key to restart..',0
times 510-($-$$) db 0
dw 0xAA55
hello.asm
[org 0x1000]
jmp start
data:
msg db 'Hello',0
start:
mov si, msg
call print ; print is a function, use CALL instead of JMP
cli
hlt
print:
lodsb
or al, al
jz exit
mov ah,0x0e
int 10h
jmp print
exit:
ret
DDコマンドに記載されている情報に基づいてWindowsを使用しているように見えるので、別の問題が発生している可能性があります。 DDあなたは使用していますが、of=\\.\d:
はディスク(USBドライブ)の先頭に書き込まないので、ディスク自体の先頭ではなく、D:にあるパーティションに書き込みます。
最新のDDからChrysocomeを使用することをおすすめします。今日の最新は0.6beta3です。このバージョンは、特定のパーティションの先頭からではなく、ドライブの先頭からディスク(またはUSBスティック)に正しくアクセスできるため、このバージョンをお勧めします。これは第1セクターと第2セクターを正しく保管しようとすると重大な問題を引き起こす可能性があります。私はUSBドライブへの書き込みを管理者権限でこれらのコマンドを使用したい最新バージョンでは:あなたの質問に提案されたよう:
dd if=f:\boot.bin od=d: bs=512 count=1
dd if=f:\hello.bin od=d: bs=512 seek=1 count=1
これはあなたのUSBドライブがドライブDにある前提としています。 警告:正しいドライブを使用しないと、別のデバイスでデータが失われ、破損する可能性があります。
は、これらのコマンドが正常に動作した場合の出力のようなものになります。
dd if=boot.bin od=d: bs=512 count=1
rawwrite dd for windows version 0.6beta3.
Written by John Newbigin <[email protected]>
This program is covered by terms of the GPL Version 2.
Device d: is a link to \\?\Device\HarddiskVolume5 \\?\Device\HarddiskVolume5 is a partition on \Device\Harddisk1
512 100%
1+0 records in
1+0 records out
dd if=hello.bin od=d: bs=512 seek=1 count=1
rawwrite dd for windows version 0.6beta3.
Written by John Newbigin <[email protected]>
This program is covered by terms of the GPL Version 2.
Device d: is a link to \\?\Device\HarddiskVolume5 \\?\Device\HarddiskVolume5 is a partition on \Device\Harddisk1
28 5%
0+1 records in
0+1 records out
をこれらのコマンドを発行した後、Windowsが自動的にドライブがもはや適切にフォーマットされていないことを検出することができます。 Windowsのドライブのフォーマットを許可しないでください。ドライブのフォーマットを許可すると、ドライブを再パーティションしてフォーマットします。そうすることで、あなたが書いたブートセクタが破壊されます。プロンプトが表示されたら、表示される可能性のある形式のダイアログボックスをキャンセルします。
システムからUSBドライブを取り外す前に、USBドライブを正しく取り外すことを忘れないでください。正しくアンマウントしないと、データが正しくドライブに書き込まれない可能性があります。あなたは、コマンドプロンプトで以下のコマンドで720Kフロッピーを作成することができBochsの、QEMU、DOSBoxをなどのディスクイメージを作成したい場合は
は:
dd if=/dev/zero of=disk.img bs=1024 count=720
dd if=f:\boot.bin of=disk.img bs=512 count=1 conv=notrunc
dd if=f:\hello.bin of=disk.img bs=512 seek=1 count=1 conv=notrunc
画像ファイルdisk.img
はBochsの、QEMUが利用可能でなければなりません、DOSboxなど、または実際のコンピュータで使用するために720kディスケットに書き込むことができます。
/dev/zero
は、一般的なUnix/Linuxデバイスのようです。 DD Windows用コマンド/dev/zero
をゼロを生成する特別な入力デバイスとして理解することをお勧めします。 Windowsには/dev/zero
デバイスがありませんが、DDは、それを特別な内部デバイスとして認識し、それをシミュレートします。 16ギガバイトのUSBスティックと私のレノボL520ノートパソコン(非EFI BIOS)で
これは次のとおりです。
MS Windows上でBochsの2.6.8で実行すると、これは私が見たものです私が見たもの:
何を試しましたか?正確に「うまくいかない」とは何ですか?出力はまったく得られますか? – Yexo
いいえ「kernel.binが見つかりません」という出力が表示されます。つまり、キャリーが設定されている(失敗した)ことを意味します。 –
"hello.bin"はセカンドセクタから読み込まれません。 –