Having trouble switching back to real mode
Posted: Thu Jan 27, 2011 8:14 am
I'm trying to switch from protected mode to real mode. The ouput I'm currently getting is "write_virtual_checks(): write beyond limit, r/w" repeatedly.
I am using GRUB and El-Torito to make a bootable CD.
Here is my code. GRUB loads my kernel at 0x100000. For testing, I'm trying to move a 'hlt' (0xF4) instruction below the 1 MB mark (currently using 0x7A00), and then jump to it into real mode. _main just installs the GDT, based on http://www.osdever.net/bkerndev/Docs/gdt.htm
MY GDT is filled like this, basing the real mode segments on http://www.sudleyplace.com/pmtorm.html
The 'info gdt' command in Bochs give me the following:
From what I can tell, GRUB does not modify the IDT, so it should already be how I need it.
What am I doing wrong? Thank you.
[EDIT]
Just one more little bit of additional information: printing the memory at 0x7A00 shows that the 'hlt' instruction is there, I'm just not getting there properly.
x /2bx 0x7A00
0x0000000000007a00 <bogus+ 0>: 0xf4 0x00
I am using GRUB and El-Torito to make a bootable CD.
Here is my code. GRUB loads my kernel at 0x100000. For testing, I'm trying to move a 'hlt' (0xF4) instruction below the 1 MB mark (currently using 0x7A00), and then jump to it into real mode. _main just installs the GDT, based on http://www.osdever.net/bkerndev/Docs/gdt.htm
Code: Select all
extern _main
call _main
mov byte [0x7A00], 0xF4
cli
mov eax, 0x20 ; real mode data segment
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
; clear Protect Enable bit
mov eax, cr0
and al, ~0x01
mov cr0, eax
; jmp into real mode at 0x7A00 somehow?
;db 0xEA
;dw 0x7A00
;dw 0x18
jmp 0x18:0x7A00
Code: Select all
gdt_set_gate(0, 0, 0, 0, 0); // 0x00
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // 0x08 - code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // 0x10 - data segment
gdt_set_gate(3, 0, 0x000FFFFF, 0x9A, 0x0F); // 0x18 - real mode code segment
gdt_set_gate(4, 0, 0x000FFFFF, 0x92, 0x0F); // 0x20 - real mode data segment
Code: Select all
Global Descriptor Table (base=0x0000000000104000, limit=39):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x03]=Code segment, base=0x00000000, limit=0x000fffff, Execute/Read, 16-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0x000fffff, Read/Write, Accessed
What am I doing wrong? Thank you.
[EDIT]
Just one more little bit of additional information: printing the memory at 0x7A00 shows that the 'hlt' instruction is there, I'm just not getting there properly.
x /2bx 0x7A00
0x0000000000007a00 <bogus+ 0>: 0xf4 0x00