GDT in memory addresses
-
- Member
- Posts: 83
- Joined: Tue Feb 03, 2009 11:37 am
GDT in memory addresses
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?
Re: GDT in memory addresses
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
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 !
The OsDev E.T.
Don't send OsDev MIB !
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Re: GDT in memory addresses
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.
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: GDT in memory addresses
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.
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...
Current state: real-mode kernel-FS reader...
Re: GDT in memory addresses
You can help from "Intel Architecture Software Developer's Manuals" vol3, chapter 3.4.
It's specific illustration....
It's specific illustration....
Re: GDT in memory addresses
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: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?
Code: Select all
15..3 2 1..0
Index TI RPL
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.
-
- Member
- Posts: 83
- Joined: Tue Feb 03, 2009 11:37 am
Re: GDT in memory addresses
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?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.
Re: GDT in memory addresses
13bits = 8192 max number of descriptors. Its your problem if you choose to have only a few. And most people do have only few.gsingh2011 wrote:hy do you need 13 bits to represent only a few descriptors?
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.