It works perfectly on real hardware, but under Bochs and QEMU it just hangs. I've boiled what I'm doing down into a snippet of assembly - it seems that Bochs doesn't like to do int 13h if the CPU has previously entered protected mode. Again, this works as expected on real hardware:
Code: Select all
use16
org 0x7c00
cli
lgdt [gdtr]
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x08:protected
protected:
use32
; should be in protected mode eh
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov sp, 0xffff
call 0x18:move_to_real
hlt
move_to_real:
mov eax, 0x20
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov eax, cr0
and al, ~1
mov cr0, eax
use16
jmp 0:real
real:
use16
mov ax, 0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; the actual disk read
mov ah, 2
mov al, 1
mov ch, 0
mov cl, 1
mov dh, 0
mov bx, 0x500
int 0x13
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x08:.protected
.protected
use32
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
ret
gdtr:
dw 5*8 - 1
dd gdt
gdt:
; null
dw 0x0000
dw 0x0000
db 0x00
db 0x00
db 0x00
db 0x00
; code (0x08)
dw 0xffff
dw 0x0000
db 0x00
db 0x9A
db 0xf | 11000000b
db 0x00
; data (0x10)
dw 0xffff
dw 0x0000
db 0x00
db 0x92
db 0xf | 11000000b
db 0x00
; 16 bit code (0x18)
dw 0xffff
dw 0x0000
db 0x00
db 0x9A
db 0xf
db 0x00
; 16 bit data (0x20)
dw 0xffff
dw 0x0000
db 0x00
db 0x92
db 0xf
db 0x00
;
times 510-($-$$) db 0
db 0x55
db 0xaa
Thanks