FASM(フラットアセンブラ)を使用してブートローダを作成しています。私は16ビットモードで成功しましたが、私は32ビットモードに切り替える際にエラーに直面しています。私は同様の(infact同じ問題GPF after far jump to protected mode)の答えを見たが、解決策は私の問題を解決しません。保護モードに切り替えて遠くにジャンプするとエラーが発生する
ここに私のブートローダーです -
org 0x7c00
jmp main
include 'bios.asm'
include 'print32.asm'
include 'gdt.asm'
main:
mov bp,0x9000
mov sp,bp
mov bx, bootMsg
call print_string
lgdt [gdt_descriptor]
cli
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp CODE_SEG:init_pm ;**The error seems to occurs here
jmp $
bits = 32
init_pm:
mov ax,DATA_SEG
mov ds,ax
mov ss,ax
mov es,ax
mov ebp, 0x90000
mov esp, ebp
jmp BEGIN_PM
BEGIN_PM:
mov ebx, pmMsg
call print_string32
jmp $
pmMsg:
db "Sucessfully switched to the 32-bit protected mode....",0
bootMsg:
db "Booted in 16-bit Real Mode mode....",0
times 510-($-$$) db 0
dw 0xaa55
ここGDTだ -
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
ハーズは番目のBochsのコンソール出力である -
00478171069i[BIOS ] Booting from 0000:7c00
00478195765e[CPU0 ] write_virtual_checks(): write beyond limit, r/w
00478195765e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00478195765e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00478195765i[CPU0 ] CPU is in protected mode (active)
00478195765i[CPU0 ] CS.mode = 32 bit
00478195765i[CPU0 ] SS.mode = 32 bit
00478195765i[CPU0 ] EFER = 0x00000000
00478195765i[CPU0 ] | EAX=d88e0010 EBX=00007d77 ECX=00090000 EDX=00000000
00478195765i[CPU0 ] | ESP=00009000 EBP=00000000 ESI=000e0000 EDI=0000ffac
00478195765i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00478195765i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00478195765i[CPU0 ] | CS:0008(0001| 0| 0) 00000000 ffffffff 1 1
00478195765i[CPU0 ] | DS:0000(0005| 0| 0) 00000000 0000ffff 0 0
00478195765i[CPU0 ] | SS:0010(0002| 0| 0) 00000000 ffffffff 1 1
00478195765i[CPU0 ] | ES:0010(0002| 0| 0) 00000000 ffffffff 1 1
00478195765i[CPU0 ] | FS:0000(0005| 0| 0) 00000000 0000ffff 0 0
00478195765i[CPU0 ] | GS:0000(0005| 0| 0) 00000000 0000ffff 0 0
00478195765i[CPU0 ] | EIP=00007d2f (00007d2f)
00478195765i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00478195765i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00478195765i[CPU0 ] 0x0000000000007d2f>> or dword ptr ds:[eax], eax : 0900
00478195765e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
誰もこれで私を助けてくださいことはできますか?
org 0x7c00
mov bp,0x9000
mov sp,bp
mov bx, bootMsg
call print_string
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp 0x8:init_pm
jmp $
use32
init_pm:
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp,0x90000
mov esp,0x90000
jmp BEGIN_PM
jmp $
include 'bios.asm'
include 'gdt.asm'
include 'print32.asm'
use32
BEGIN_PM:
mov ebx, pmMsg
call print_string32
jmp $
pmMsg:
db "Sucessfully switched to the 32-bit protected mode....",0
bootMsg:
db "Booted in 16-bit Real Mode mode....",0
times 510-($-$$) db 0
dw 0xaa55
EDIT - - これは、ここで
編集 -
がuse32
VIDEO_MEM equ 0xb8000
W_O_B equ 0x0f
print_string32:
pusha
mov edx,VIDEO_MEM
print_string32_loop:
mov al, [ebx]
mov ah, W_O_B
cmp al,0
je print_string32_end
mov [edx],ax
inc ebx
add edx,2
jmp print_string32_loop
print_string32_end:
popa
ret
コード - print32そして、ブートローダのために変更されたコードです。..長いので、私を悩まされていますコードは今作動する!!
Bochsの内部デバッガを使用して、どのフォルトが発生しているかを調べる手順を実行しようとしましたか?私はそれを間違って読んでいるかもしれませんが、保護モードにして、アドレス0x7d2fの 'dword ptr ds:[eax]、eax'のような命令で失敗したようです。 _EAX_はジャンクを含んでいるように見え、ポインタとして使用されており、DSはセグメントセレクタ0に設定されているようですが、0x10と予想されます。 –
あなたの問題には関係しませんが、 'mov bp、0x9000'' mov sp、bp'は実モードスタックポインタを設定する適切な方法ではありません。 _SS_の後にSPを設定する必要があります。スタックを0x0000:0x9000または物理アドレス0x9000にしたい場合は、 'xor ax、ax'' mov ss、ax'' mov sp、0x9000' –
私はデバッガを使用しませんでしたが、jmpのときCODE_SEG:init_pmはシステムは何のエラーもなく停止しますが、bochsは保護モードへの切り替えについて通知しません。 –