私のブートローダの第2段階で、仮想フロッピーディスクの一部のセクタをbochsのメモリにロードしようとしていますが、int 0x13
を呼び出すと、戻ることはありません。フロッピーリード(AH = 0x2、int 0x13)が完了しない
私は私の第二段階から関連するコードがあると信じて:
bootsys_start:
mov %cs, %ax
mov %ax, %ds
/*
* Remap IRQs. Interrupts have been disabled in the
* bootloader already.
*/
mov i8259A_ICW1($i8259A_IC4), %al
out %al, i8259A_ICW1_ADDR($i8259A_MASTER)
out %al, i8259A_ICW1_ADDR($i8259A_SLAVE)
mov i8259A_ICW2($USER_INT_START), %al
out %al, i8259A_ICW2_ADDR($i8259A_MASTER)
mov i8259A_ICW2($USER_INT_START + 8), %al
out %al, i8259A_ICW2_ADDR($i8259A_SLAVE)
mov i8259A_ICW3($0x4), %al
out %al, i8259A_ICW3_ADDR($i8259A_MASTER)
mov i8259A_ICW3($0x2), %al
out %al, i8259A_ICW3_ADDR($i8259A_SLAVE)
mov i8259A_ICW4($i8259A_uPM & i8259A_x86), %al
out %al, i8259A_ICW4_ADDR($i8259A_MASTER)
out %al, i8259A_ICW4_ADDR($i8259A_SLAVE)
call mm_detect
/* Load the kernel now. */
xor %bp, %bp
1:
mov $KERNEL_ORG >> 0x4, %ax
mov %ax, %es
mov $KERNEL_ORG & 0xf, %bx
mov $0x200 | KERNEL_SECTORS, %ax
mov $(KERNEL_C << 0x8) | KERNEL_S, %cx
mov $(KERNEL_H << 0x8) | FLOPPY_DRV, %dx
int $0x13 /* <--- This int 0x13 doesn't seem to return */
jnc 1f
cmp $0x2, %bp
je floppy_err
inc %bp
xor %ah, %ah
int $0x13
jmp 1b
コードのすべてが私のGithub repositoryで見つけることができます。私がやったコマンドにbochs
を使用してBOCHSを
make all
を使用して、
で実行 を構築するにはまず最初は、私は本当にすべてのパラメータが右まし検証されました。
CPU0:
rax: 00000000_534d0201 rcx: 00000000_00000005
rdx: 00000000_534d0000 rbx: 00000000_00000000
rsp: 00000000_00007700 rbp: 00000000_00000000
rsi: 00000000_000e0005 rdi: 00000000_00000316
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_00000036
eflags 0x00007046: id vip vif ac vm rf NT IOPL=3 of df if tf sf ZF af PF cf
ah = 0x2
(ルーチンID)、al = 0x1
(セクタ数)、ch = 0x0
(シリンダ番号の下位バイト)、cl = 0x5
(セクター番号およびシリンダなしの高い2ビット):Bochsのシェル収率でr
dh = 0x0
(ヘッド番号)、dl = 0x0
(ドライブ番号)。
sreg
es
用印刷物:
es:0x0000
とbx = 0x0
、その部門は、私が意図したのと同様に、0x0:0x0
にロードされます。
、私はいくつか試してみました:私は多分IVTまたはBDAを上書きすることは割り込みルーチンBIOSの実行中に、良いアイデアではないかもしれないと思った0x600
物理アドレスに
ロード私はセクタを
0x600
(es = 0x60
、bx = 0x0
)にロードしようとしました(BDAのサイズは256バイトのみです)。同じ結果。たぶん第五部門を読ん
が範囲または任意の外に何らかの形で?ディスクの最初のセクターをロードしますか
int 0x13
を使用して私の第2段階を読むコードは、期待通りに機能します。私の第2段階のint 0x13
は似ているので、私はそれがうまくいくと期待していました。テストとして、私はセクター1を読むために私の第2ステージを変更しましたが、それでも動作しませんでした。私は考え出しeax
の上部をゼロ
は多分確かにBIOSルーチンにバグがあり、何とか
eax
はax
を使用していません。私はeax
の上位16ビット部分をゼロにしてみました...無駄です。
私はすでに前に言ったように、私はすでにメモリにディスクからいくつかのセクターをロード。(Bochsのシェルでr
を用いて得られた)次のようにint 0x13
前のGPRのコンテンツ権利がある:
CPU0:
rax: 00000000_00000203 rcx: 00000000_00090002
rdx: 00000000_00000000 rbx: 00000000_00000000
rsp: 00000000_00007700 rbp: 00000000_00000000
rsi: 00000000_000e7cdd rdi: 00000000_000000e2
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_00007c59
eflags 0x00007046: id vip vif ac vm rf NT IOPL=3 of df if tf sf ZF af PF cf
sreg
es:0x8f60
をもたらします。両方を比較 、私は割り込みルーチンの機能に影響を与える可能性がある有意な差が表示されないので、問題はレジスタを介して渡されたパラメータにすることはできません。
他に何をすべきか提案がありますか?私は一種のあなたのInt 13h/AH=02hフロッピーディスク読み取りコードに...ここ
あなたは[MCVE]で問題を分離しようとしたことがありますか?具体的には、IPが最初のケースで36h、2番目のケースで7c59hであることを考慮してセグメントレジスタを設定する方法。 –
"セクタが0x0:0x0にロードされるので、エラーベクタテーブルを上書きしますか? – davmac
@MargaretBloom 'cs'は、前者は' 0x8f60'、後者は '0x0'です。 BIOSはブートローダを物理アドレス0x7c00にロードし、ブートローダはEBDAの直下の第2ステージブートローダをロードします。その値は動的に取得され、第2ステージブートローダはカーネルを物理アドレス0x0にロードします。私はMCVEをして、ロードセクタが** no **試みが成功した場合に一般的に動作することを確認します。しかし、セカンダリブートローダをロードするだけでうまくいきます。 – Downvoter