GDT in memory addresses

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
gsingh2011
Member
Member
Posts: 83
Joined: Tue Feb 03, 2009 11:37 am

GDT in memory addresses

Post by gsingh2011 »

I'm a little confused... When you have a memory address 0000:0010, I understand that the 00010 is the offset into the segment, but the segment is what's confusing me. Is the selector part of the address referencing where in the memory the segment is or where in the GDT the descriptor is?
gedd
Member
Member
Posts: 104
Joined: Thu Apr 10, 2008 1:47 am

Re: GDT in memory addresses

Post by gedd »

It is the offset to a GDT descriptor :

EQU : GDT_adress + offset_to_GDT_descriptor

in your case 0000 referece the first descriptor that it must be null and must not be used

second decriptor at 0x08
third at 0x10
.... and so on
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: GDT in memory addresses

Post by mathematician »

In real mode the memory address is calculated as segment-selector * 16 + offset. In protected mode, the (visible part of) the segment selector contains an index into the GDT.
The continuous image of a connected set is connected.
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: GDT in memory addresses

Post by Masterkiller »

You should probably read the wiki and/or AMD/Inter developer manual. There is detailed information about that there. I'll give you a short answer.
Selector is 16-bit with format XXXXXXXXXXXXXYYZ
Where X bits forms 13-bit index in a descriptor table (may be not GDT, see bit Z) (0-8191); Y is requested privilege level (0-3) : 0 stands for OS level, 3 stands for User Level; Z bit determine if index is in GDT (if cleared) or in LDT (if set). Selector "selects" a descriptor from GDT/LDT and loads it in the hidden part of the segment register (since the descriptor is 8 byte long, hidden part is also 8 byte long). When you do MOV DS, ax (if ax is valid selector), the hidden part of DS is loaded with descriptor. (selector with value 0 is threated invalid, even it point to GDT index 0).
The loaded in the hidden part descriptor has following properties:
- base address (32-bit value)
- segment limit (20-bit value)
- privilege level
- granularity bit
- Type: Code/Data/System
- Access: Read/Write/Execute
So an example if try to execute code at 0x0008:0x00001000, you point index[1] at GDT, if the descriptor there has a base address of 0x00001000, you got physical address of (0x1000+0x1000=0x2000). That's not the end, CPU checks the segment limit to see if offset is within the segment, check if it code segment, and if it id code segment, check if it is has an execute access, check privilege levels. If one of this check fails, CPU generates an exception.
Granularity bit makes the segment limit to not show how much bytes the segment has, but how much 4KB chunk (or granules) segment has. With this bit cleared, largest segment you can have is 1MB, with this bit set is 4GB.
I suppose you will wonder if segment base point 0xFFFFFFF0 and offset point 0x00000010 will we go out of 4GB address space. The answer is no, it will wrap and you will access the physical address of 0.
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: GDT in memory addresses

Post by kop99 »

You can help from "Intel Architecture Software Developer's Manuals" vol3, chapter 3.4.
It's specific illustration....
essial
Member
Member
Posts: 26
Joined: Sat Mar 01, 2008 10:23 pm

Re: GDT in memory addresses

Post by essial »

gsingh2011 wrote:I'm a little confused... When you have a memory address 0000:0010, I understand that the 00010 is the offset into the segment, but the segment is what's confusing me. Is the selector part of the address referencing where in the memory the segment is or where in the GDT the descriptor is?
Ok the GDT is the Global Descriptor Table. That is, it is an array of a certain structure that defines things about each descriptor entry -- things like base address, length, privlage, whether it's 16 or 32-bit, etc. The reason why the first (index 0) entry is referenced by a segment selector of 0x08instead of one is because the segment selects in 32-bit are structured like so:

Code: Select all

15..3 2  1..0
Index TI RPL
so MOV CS, 0x08 sets the code segment to 1000. As in, GDT entry 1, GDT, RPL 0.
That is all the segment selectors are for. The way the processor knows where the GDT/LDT is, is when you call LGDT or LLDT functions.

This all differs from 16-bit mode which has no descriptor table. In 16-bit mode, the selectors are simply offsets with the lowest 4 bits hacked off (so CS=0x7C0 means offset 0x7C00); it just adds a 0 to the end of the value of the segment selector, and adds that to the offset to get the final destination.
gsingh2011
Member
Member
Posts: 83
Joined: Tue Feb 03, 2009 11:37 am

Re: GDT in memory addresses

Post by gsingh2011 »

Masterkiller wrote:You should probably read the wiki and/or AMD/Inter developer manual. There is detailed information about that there. I'll give you a short answer.
Selector is 16-bit with format XXXXXXXXXXXXXYYZ
Where X bits forms 13-bit index in a descriptor table (may be not GDT, see bit Z) (0-8191); Y is requested privilege level (0-3) : 0 stands for OS level, 3 stands for User Level; Z bit determine if index is in GDT (if cleared) or in LDT (if set). Selector "selects" a descriptor from GDT/LDT and loads it in the hidden part of the segment register (since the descriptor is 8 byte long, hidden part is also 8 byte long). When you do MOV DS, ax (if ax is valid selector), the hidden part of DS is loaded with descriptor. (selector with value 0 is threated invalid, even it point to GDT index 0).
The loaded in the hidden part descriptor has following properties:
- base address (32-bit value)
- segment limit (20-bit value)
- privilege level
- granularity bit
- Type: Code/Data/System
- Access: Read/Write/Execute
So an example if try to execute code at 0x0008:0x00001000, you point index[1] at GDT, if the descriptor there has a base address of 0x00001000, you got physical address of (0x1000+0x1000=0x2000). That's not the end, CPU checks the segment limit to see if offset is within the segment, check if it code segment, and if it id code segment, check if it is has an execute access, check privilege levels. If one of this check fails, CPU generates an exception.
Granularity bit makes the segment limit to not show how much bytes the segment has, but how much 4KB chunk (or granules) segment has. With this bit cleared, largest segment you can have is 1MB, with this bit set is 4GB.
I suppose you will wonder if segment base point 0xFFFFFFF0 and offset point 0x00000010 will we go out of 4GB address space. The answer is no, it will wrap and you will access the physical address of 0.
Is this for real mode or protected mode? How do they differ? You said "Selector "selects" a descriptor from GDT/LDT and loads it in the hidden part of the segment register (since the descriptor is 8 byte long, hidden part is also 8 byte long)". If that's the case, why do you need 13 bits to represent only a few descriptors?
geppyfx
Member
Member
Posts: 87
Joined: Tue Apr 28, 2009 4:58 pm

Re: GDT in memory addresses

Post by geppyfx »

gsingh2011 wrote:hy do you need 13 bits to represent only a few descriptors?
13bits = 8192 max number of descriptors. Its your problem if you choose to have only a few. And most people do have only few.

I personaly think that during these LongMode days GDT is just a relic of the past needed for compability. Large number(8191) of descriptors maybe useful for hardware task switching but nobody uses it. It is 8191 and not 8192 because very first descriptor in GDT is not used. I have no idea about LDT, never used it, and most likely neither will you.

TSS descriptor is 16bytes long in LongMode. Which means if you use one you have limit of 8190 descriptors.

I tend to think about selector in protected mode as offset into GDT/LDT with lower 3 bits not used but not as index(Intel version).

In real mode selector has nothing to do with GDT/LDT. Its part of address. Read mathematician's post above.

And if you are new then forget about visible/hidden parts. Selector is 2baits for you.
Post Reply