I have successfully written code for real mode. But the trouble started with 32-bit Protected Mode. Before jumping to Protected Mode, I have disabled interrupts using cli, loaded GDT using lgdt and set 32-bit mode bit in cr0. But QEMU is rebooting infinitely. Following are the codes
boot.asm:
[BITS 16]
BOOTSEG equ 0x7c00
DATASEG equ 0x07c0
STACKSEG equ 0x17c0
EXTRASEG equ 0x37c0
STACKPOINT equ 0x0000
BLACKONWHITE equ 0x0F
YELLOWONBLUE equ 0x1E
VIDEO_MEMORY equ 0xb8000
global _start
_start:
xor ax, ax
mov ax, STACKSEG
mov ss, ax ;initializing stack segment
mov sp, STACKPOINT
mov ax, DATASEG
mov ds, ax ;initializing data segment
mov ax, EXTRASEG
mov es, ax ;initializing extra segment
call Switch_To_Pm
%include "./screen.asm"
%include "./lib.asm"
%include "./gdt.asm"
%include "./protected_mode/switch_to.asm"
[bits 32]
Begin_Pm:
jmp $
times 510 - ($ - $$) db 0
dw 0xAA55
gdt.asm:
gdt_start:
null_descriptor:
dd 0x0
dd 0x0
code_descriptor:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
data_descriptor:
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 code_descriptor - gdt_start
DATA_SEG equ data_descriptor - gdt_start
protected_mode/switch_to.asm:
[BITS 16]
Switch_To_Pm:
cli
lgdt [gdt_descriptor]
mov eax , cr0
or eax , 0x1
mov cr0 ,eax
jmp CODE_SEG:Init_Pm
[BITS 32]
Init_Pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
call Begin_Pm
lib.asm contains a delay routine using int 0x15 and screen.asm contains BIOS routines to print text in real mode.
Following are the commands I used to build
nasm -fbin -o boot.bin boot.asm
qemu boot.bin
Don't know why but QEMU is rebooting infinitely. Code till real mode worked well. Probably there is a problem with switching to Protected Mode.
Prior thanks to any help
I think I have identified where the problem is. The problem is with the line
jmp CODE_SEG:Init_Pm
in protected_mode/switch_to.asm
. I should add an offset of 0x7c00 to the far jump.
Instead I used [org 0x7c00]
and rewrote both real mode and protected mode codes, it worked.