I'm trying to setup gdt for the CS, DS, SS and video so that we could read/write the memory mapped registers of a pci card.
On switching back, we have to restore all the segments. Any pointers will be very helpful.
I wrote 0x11223344 at location 0x200000 and get some garbage values on reading back.
Tools used: MSVC1.5 and MASM6.5.
environment: option bios
Code: Select all
// -- 'C' file --
void SetUpGdtTbl(void)
{
//ProcSaveSegs()
//===============
__asm{
mov ax, cs
mov gPrevCS, ax
mov ax, ds
mov gPrevDS, ax
mov ax, ss
mov gPrevSS, ax
};
PrepareGdtDescp (&gGdtDesc[0], 0, 0, 0, 0); // 0x00 -- NullDescriptor
PrepareGdtDescp (&gGdtDesc[1],((unsigned long)gPrevCS)<<4, 0xFFFF, 0x9A, 0); // 0x08 -- CurCodeSegment Descriptor for ProtectedMode
PrepareGdtDescp (&gGdtDesc[2],((unsigned long)gPrevDS)<<4, 0xFFFF, 0x92, 0); // 0x10 -- CurDataSegment Descriptor for ProtectedMode
PrepareGdtDescp (&gGdtDesc[3],((unsigned long)gPrevSS)<<4, 0xFFFF, 0x92, 0); // 0x18 -- CurStackSegment Descriptor for ProtectedMode
PrepareGdtDescp (&gGdtDesc[4], 0xB8000L, 0xFFFF, 0x92, 0); // 0x20 -- VideoModeSegment Descriptor is used as scratch pad for Memory Movement
PrepareGdtDescp (&gGdtDesc[5], 0L, 0xFFFF, 0x92, 0x8F); // 0x28 -- Segment Descriptor for 4GB segment
gGdtRegs.base = ((unsigned long)gPrevDS)<<4;
gGdtRegs.base += (unsigned int)&gGdtDesc;
gGdtRegs.limit = sizeof(gGdtDesc)-1;
}
void setBigRealMode(void)
{
KeyboardA20(1);
SetUpGdtTbl();
UnrealCode();
}
// ASM file
;//-=========================
//MASM6.5
@UnrealCode proc
pushad
push ds
push ds
mov ax,cs ;code16
mov ds,ax
xor eax,eax ; point gdt_ptr to gdt
mov ax,ds
shl eax,4
add ax,offset gdt ; EAX=linear address of gdt
mov dword ptr _gGdtRegs + 2,eax
cli ; Interrupts off
mov bx,offset _gGdtRegs
jmp flush1
flush1:
lgdt fword ptr[bx]
mov eax,cr0
or al,1
mov cr0,eax ; partial switch to 32-bit pmode
jmp flush2
flush2:
mov bx,8 ; selector to segment w/ 4G limit
mov ds,bx
mov es,bx ; set seg limits in descriptor caches
dec al
mov cr0,eax ; back to (un)real mode
pop es ; segment regs back to old values,
pop ds ; but now 32-bit addresses are OK
popad
sti
ret
@UnrealCode endp