http://forum.osdev.org/viewtopic.php?f=1&t=29900
now my code enters and exits protected mode just fine after following fixes:
-corrected the way GDT PTR is calculated (use flat address instead of SEG:OFF). that means before correction. lgdt was loading some arbitrary address and system was still stable before loading segment selector!
-did spend lot of time on descriptor format and make sure every bits are set as intended.
-I did parseDesc to printout the every segment descriptors in a GDT in very verbose manner (pasted below)
Now I enter pmode grab few bytes (dword) from memory and display back after exiting using segment selector+offset.
I did two different known addresses:
BDA at 0:0400h - this is known memory location as first dword has serial port address
RSD PTR at 0f45f0h - another known memory location that reside somewhere between e000-ffffh segment and has "RSD "
Once pass these address to function that enters pmode and exit, I see dword at BDA returned right bytes: serial port addresses "03f802f8"
But RSD PTR is not returning right bytes: it should return part of signature "RSD " in 1st dowrd.
If I read the same location from real-mode at the same time in same program, it DOES return the correct signature.
I am wondering what could be the culprit for the latter. Both location are read exactly the same way.
I will be trying few more known memory locations to see if I can find out any pattern.
Code: Select all
==============
Descriptor No: 01
===============:
Descriptor Info:
---------------:
0000FFFF:00CF9A00
Segment base: 00000000
Segment size(lim): 000FFFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00- AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl bit:
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 0A - segment descriptor type:
Rx05[3]: 01 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
code: 0=code can only be exec-d from priv.lvl set in ring
1=code can be exec-d from same or lower priv.level
Rx05[1]: 01 - W(data)/R(code)
code: 0=read access not allowed
1=read access allowed (write access never allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No: 02
===============:
Descriptor Info:
---------------:
0000FFFF:00CF9200
Segment base: 00000000
Segment size(lim): 000FFFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00- AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl bit:
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 02 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)