I'm writing a simple boot loader. The boot loader is compiled from two assembly files: boot.asm, protected_start.asm. boot.asm loads protected_start to 0x10000, sets GDTR, enters protected mode and jump to 0x10000. So the encoding is set to 16-bit in boot.asm, 32-bit in protected_start.asm.
I use QEMU, VMware and NASM on Windows. Both virtual machines have 128MB of memory. After entering protected mode, QEMU successfully jumps to 0x10000 and prints given string, but VMWare reboots. I used "jmp $" to seek where the error occurs, and found "jmp dword 0x08:0x0000" in boot.asm makes the error.
The version of QEMU is 20180519, VMware is Workstation Player 14.1.2 build-8497320.
Why "jmp dword 0x08:0x0000" after LGDT makes error? What do I have to do to resolve this problem?
boot.asm:
[org 0x7c00]
[bits 16]
load:
mov ax, 0x1000
mov es, ax
mov bx, 0x0000;
mov ah, 0x02; Read sectors from drive
mov al, 0x08; Number of sectors to read
mov ch, 0x00; Cylinder index
mov cl, 0x02; Sector
mov dh, 0x00; Head
mov dl, 0x00; Drive
int 0x13
jc load
cli
lgdt [gdtr]
mov eax, cr0
or eax, 0x00000001
mov cr0, eax
jmp dword 0x08:0x0000
gdt_list:
dw 0
dw 0
db 0
db 0
db 0
db 0
.gdt_code:
dw 0xFFFF
dw 0x0000
db 0x01
db 0x9A
db 0xCF
db 0x00
.gdt_data:
dw 0xFFFF
dw 0x0000
db 0x00
db 0x92
db 0xCF
db 0x00
.gdt_video:
dw 0xFFFF
dw 0x8000
db 0x0B
db 0x92
db 0xCF
db 0x00
gdtr:
dw 4*8
dd gdt_list
times 510 - ($ - $$) db 0
dw 0xAA55
protected_start.asm:
[org 0x10000]
[bits 32]
protected:
mov ax, 0x10
mov ds, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0xFFFF
mov ebp, 0xFFFF
mov ax, 0x18
mov es, ax
mov edi, 0x0000
mov esi, my_str
call write
jmp $
write:
push eax
push ebx
mov ah, 0x0e
mov bx, 0x0007
.loop:
lodsb
or al, al
jz .end
mov byte [es:edi], al
inc di
mov byte [es:edi], 0x0f
inc di
jmp .loop
.end:
pop ebx
pop eax
ret
my_str:
db "Protected", 0x0
times 512 - ($ - $$) db 0
What I used to invoke virtual machines in PowerShell:
qemu-system-x86_64 -m 128 -smp 1 -fda ".\bin\os.img"
Invoke-Item ".\virtual\os.vmx"
ds
. – Jester