News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

unreal mode

Started by dileep, February 27, 2012, 11:02:04 AM

Previous topic - Next topic

dileep

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?

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.

dileep

#2
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.?

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.

vanjast

Quote from: sinsi on February 27, 2012, 12:21:42 PM
PS forgot about the A20 line.
Sh1t.. that rings a bell  :bg

dileep

Plz help me , if i missed something

MichaelW

Your code, as posted, will not assemble. How do you know it is failing?
eschew obfuscation

dileep

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

dileep

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

MichaelW

Although it is very different than your code, there is an example in the attachment here 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.
eschew obfuscation

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.

dileep

#11
this code is part of pxe driver(pci option ROM driver).  I dnt knw how to debug this issue.

dileep

Do i need to handle IDT while swithing to Unreal mode?  if yes, Give some sample code.

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.

dileep

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?