hi i am trying to switch in to protected mode. using
mov eax,cro
or al, 01h
mov cr0,eax
but sytem is rebooting while updating the cr0 register.
Can anyone help me regarding this?
Setup a GDT
CLI
LGDT
switch to pmode
MOV GS,8
switch to rmode
STI
MOV GS,0
access 0-4GB with GS: override
Of course windows (even DOS with himem/emm) will not like it.
SEGMENT_DESCRIPTOR struct
segment_limit_0_15 dw ?
base_addr_0_15 dw ?
base_addr_16_23 db ?
segment_properties db ?
seg_limit_16_19_gran db ?
base_addr_24_31 db ?
SEGMENT_DESCRIPTOR ends
gdt_start label qword
nullDescriptor SEGMENT_DESCRIPTOR <0,0,0,0,0,0>
code16Descriptor SEGMENT_DESCRIPTOR <0ffffh,0000,00,9Fh,00h,00>
code32Descriptor SEGMENT_DESCRIPTOR <0ffffh,0000,00,9Fh,08Fh,00>
Data16Descriptor SEGMENT_DESCRIPTOR <0ffffh,0000,00,93h,8Fh,00>
gdt_end label qword
gdtr_base label fword
dt_limit dw gdt_end-gdt_start-1 ;
gdt_addr dd 00000000h ;
orig_gdtr_base label fword
orig_gdt_limit dw 0000h ;
orig_gdt_addr dd 00000000h ;
push eax
push ebx
push ds
push es
db 66h
sgdt fword ptr cs:orig_gdtr_base
pushfd
cli
mov bx, Data16Descriptor - gdt_start
; Load GDTR
lgdt fword ptr cs:[gdtr_base]
mov eax, cr0
or al, 1
mov cr0,eax
mov ds, bx
mov es, bx
mov eax, cr0
and al, 0FEh
mov cr0, eax
nop
db 66h
lgdt cs:orig_gdtr_base
popfd
pop es
pop ds
pop ebx
pop eax
while setting the PE bit, system reboots. Can any one help in this.?
Suprised it worked at all
gdtr_base label fword
dw LPCFG_GDT_LENGTH
gdt_limit dw gdt_end-gdt_start-1 ;limit
gdt_addr dd 00000000h ; 32 bit address (filled in above)
One too many dw's in there :wink
PS forgot about the A20 line.
Quote from: sinsi on February 27, 2012, 12:21:42 PM
PS forgot about the A20 line.
Sh1t.. that rings a bell :bg
Plz help me , if i missed something
Your code, as posted, will not assemble. How do you know it is failing?
fun proc near
push eax
push ebx
push ds
push es
push fs
push gs
db 66h
sgdt fword ptr cs:orig_gdtr_base
pushfd
cli
mov bx, bigData16Descriptor - gdt_start
; Make Sure A20 line is Enabled
in al,SYS_CTRL_PORTA ; read system control port A
or ah, ah
mov cs:SaveA20, al
test al, 02h
jne A20_set
or al,02 ; enable A20 line
out SYS_CTRL_PORTA,al
A20_set:
; Load GDTR
lgdt fword ptr cs:[gdtr_base]
; Save SS:ESP
mov ax, ss
mov cs:SaveSS, ax
mov cs:SaveESP, esp
mov eax, cr0
or al, 1
mov cr0,eax
mov ds, bx ; Change Data segments to BIG REAL LIMIT
mov es, bx ; Change External segment to BIG REAL LIMIT
mov eax, cr0
and al, 0FEh
mov cr0, eax
nop
db 66h
; Restore Original GDT
lgdt cs:orig_gdtr_base
; Set Segment Registers to known values
popfd
pop gs
pop fs
pop es
pop ds
pop ebx
pop eax
fun end-- i added some debug msgs, those are getting printed
i am calling this proc, its coming up to mov cr0,eax. while setting PE bit in cR0 shall i need to do anything else
Although it is very different than your code, there is an example in the attachment here (http://www.masm32.com/board/index.php?topic=13085.msg101551#msg101551) that switches to protected mode to set the GS segment limit to the size of the 32-bit address space, and then back to real mode.
If you use something like Bochs debugger you can single-step and see why your code triple faults.
Maybe zip your code and attach it so we can see the whole thing, switching to pmode is not an easy thing.
Too many things can make the cpu triple fault.
this code is part of pxe driver(pci option ROM driver). I dnt knw how to debug this issue.
Do i need to handle IDT while swithing to Unreal mode? if yes, Give some sample code.
Problems I can see:
You don't set the linear address of the GDT in gdt_addr.
No need to save/restore the current GDT.
No need to save/restore ss/esp.
No need for more than two descriptors (null and data32).
Bochs will let you add a ROM image and debug that.
>Do i need to handle IDT while swithing to Unreal mode?
As long as all you do is set a segment register to a data32 descriptor and wrap the cr0 moves in cli/sti then no.
I have attached my code, be aware that it is FASM syntax but easy to translate to MASM.
I am trying to set linear address to gdt_addr
xor eax, eax
mov eax, cs
shl eax, 4
add eax, offset gdt_start
mov dword ptr cs:gdt_addr, eax
Is it sufficient to get the linear address of gdt_start?
Yes, that will give you the linear address.
Re the A20 line, using port 92h is usually considered the last resort. My order is BIOS, if that doesn't work then the KBC, if that also doesn't work then try 92.
I tried after setting the linear address . But the result is same.
If you are still using this, it is wrong
gdtr_base label fword
dw LPCFG_GDT_LENGTH
gdt_limit dw gdt_end-gdt_start-1 ;limit
gdt_addr dd 00000000h ; 32 bit address (filled in above)
Correct
gdtr_base label fword
gdt_limit dw gdt_end-gdt_start-1 ;limit
gdt_addr dd 00000000h ; 32 bit address (filled in above)
i am using the correct one
gdtr_base label fword
gdt_limit dw gdt_end-gdt_start-1 ;limit
gdt_addr dd 00000000h ; 32 bit address (filled in above)
---------
and then i set gdt_addr to the linear address of gdt_start
There is not enough information to know what is going on.
1. How are you testing this code?
2. How do you know the instruction causing the fault?
we will flash this ROM image onto our PCI network card and put this card into IBM , Dell Servers. this driver is for pxe booting. While system is coming up , will load our driver. I added some debug prints , so i can see execution flow. Once the initialization is done, we have to load UNDI driver, for that i have to swith to unreal mode for accessing the 32bit pci BAR address.
i am able to read the CR0 register. got the CR0 value 0x12 ,. While enabling the PE bit system reboots.
That is way above what we seem to be doing here. Setting a segment register for 4GB access is a trivial thing.
If i use this ,On Dell also i was not able to enter unreal mode
gdtr_base label fword
gdt_limit dw gdt_end-gdt_start-1 ;limit
gdt_addr dd 00000000h ; 32 bit address (filled in above)
what will happen internally if i set the PE bit in CR0? Can any one help me in this?
All the information you require is in the Intel Manuals, specifically the Systems Programming Manual.
Read it.
Read it again.
If you have any further questions, you might get better help at http://forum.osdev.org/; but be warned, they won't have much patience for you if you haven't read and understood the basics.
lol - they're not the friendliest guys in the world, are they
i don't usually ask questions in there
i just read all the posts that are relevant to what i want to know
there is a lot of good code posted in there - and some bad, too