Global Descriptor Table: Difference between revisions
Jump to navigation
Jump to search
[unchecked revision] | [unchecked revision] |
Content deleted Content added
Revolution (talk | contribs) I felt this article could use somewhat of a rewrite as I found its formatting confusing and information kind of garbled (particularly information pertaining to 64-bit mode). Feel free to change formatting or wholly revert the edit if not welcome. |
Revolution (talk | contribs) Changed old images (one lacking an important flag) to box-drawn text blocks and added a section about the layout of the table itself. Again, if this edit is not welcome feel free to revert it. |
||
Line 1: | Line 1: | ||
The '''Global Descriptor Table''' ('''GDT''') is a binary data structure specific to the [[IA32_Architecture_Family | |
The '''Global Descriptor Table''' ('''GDT''') is a binary data structure specific to the [[IA32_Architecture_Family |IA-32]] and [[X86-64 |x86-64]] architectures. It contains entries telling the CPU about memory [[Segmentation|segments]]. A similar [[Interrupt Descriptor Table]] exists containing [[task]] and [[Interrupts|interrupt]] descriptors. |
||
It is recommended to read the [[GDT Tutorial]]. |
|||
== Structure == |
|||
== GDTR == |
|||
The '''GDT''' is pointed to by the value in the '''GDTR''' register. This is loaded using the '''LGDT''' assembly instruction, whose argument is a pointer to a '''GDT Descriptor''' structure: |
The '''GDT''' is pointed to by the value in the '''GDTR''' register. This is loaded using the '''LGDT''' assembly instruction, whose argument is a pointer to a '''GDT Descriptor''' structure: |
||
<pre> |
|||
[[Image:Gdtr.png|frame|center|GDTR]] |
|||
GDT Descriptor (GDTR): |
|||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ |
|||
┃79 (64-bit Mode) / 48 (32-bit Mode) 16│15 0┃ |
|||
┠───────────────────────────────────────────────────────────────┼───────────────────────────────┨ |
|||
┃Offset │Size ┃ |
|||
┃63 (64-bit Mode) / 31 (32-bit Mode) 0│15 0┃ |
|||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ |
|||
</pre> |
|||
* '''Size:''' The size of the table in bytes subtracted by 1. This subtraction occurs because the maximum value of '''Size''' is 65535, while the '''GDT''' can be up to 65536 bytes in length (8192 entries). Further, no '''GDT''' can have a size of 0 bytes. |
* '''Size:''' The size of the table in bytes subtracted by 1. This subtraction occurs because the maximum value of '''Size''' is 65535, while the '''GDT''' can be up to 65536 bytes in length (8192 entries). Further, no '''GDT''' can have a size of 0 bytes. |
||
Line 15: | Line 24: | ||
For more information, see '''Section 2.4.1: Global Descriptor Table Register (GDTR)''' and '''Figure 2-6: Memory Management Registers''' of the Intel Software Developer Manual, Volume 3-A. |
For more information, see '''Section 2.4.1: Global Descriptor Table Register (GDTR)''' and '''Figure 2-6: Memory Management Registers''' of the Intel Software Developer Manual, Volume 3-A. |
||
== Table == |
|||
---- |
|||
The entries in the '''GDT''' are 8 bytes long and form a table like this: |
|||
⚫ | |||
<pre> |
|||
⚫ | |||
Table: Address: |
|||
┏━━━━━━━━━━━┓ |
|||
┃ Null ┃ IDTR Offset + 0 |
|||
┠───────────┨ |
|||
┃ Entry 1 ┃ IDTR Offset + 8 |
|||
┠───────────┨ |
|||
┃ Entry 2 ┃ IDTR Offset + 16 |
|||
┠───────────┨ |
|||
┃ Entry 3 ┃ IDTR Offset + 24 |
|||
┠───────────┨ |
|||
┃ ... ┃ ... |
|||
┠───────────┨ |
|||
</pre> |
|||
The first entry in the '''GDT''' (Entry 0) should always be null and subsequent entries should be used instead. |
|||
[[Image:GDT_Entry.png|frame|center|Segment Descriptor]] |
|||
Entries in the table are accessed by '''Segment Selectors''', which are either loaded into '''[[Segmentation]]''' registers by assembly instructions or by hardware functions such as '''[[Interrupts]]'''. |
|||
What "Limit 0:15" means is that the field contains bits 0-15 of the '''Limit''' value. |
|||
⚫ | |||
⚫ | |||
<pre> |
|||
SEGMENT DESCRIPTOR: |
|||
┏━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┓ |
|||
┃63 56│55 52│51 48│47 40│39 32┃ |
|||
┠───────────────────────┼───────────┼───────────┼───────────────────────┼───────────────────────┨ |
|||
┃Base │Flags │Limit │Access Byte │Base ┃ |
|||
┃31 24│4 0│19 16│7 0│23 16┃ |
|||
┗━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━┛ |
|||
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ |
|||
┃31 16│15 0┃ |
|||
┠───────────────────────────────────────────────┼───────────────────────────────────────────────┨ |
|||
┃Base │Limit ┃ |
|||
┃15 0│15 0┃ |
|||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ |
|||
</pre> |
|||
* '''Base:''' A 32-bit value containing the linear address where the segment begins. |
* '''Base:''' A 32-bit value containing the linear address where the segment begins. |
||
Line 30: | Line 72: | ||
In 64-bit mode, the '''Base''' and '''Limit''' values are ignored, each descriptor covers the entire linear address space regardless of what they are set to. |
In 64-bit mode, the '''Base''' and '''Limit''' values are ignored, each descriptor covers the entire linear address space regardless of what they are set to. |
||
⚫ | |||
⚫ | |||
=== Access Byte === |
|||
'''Access Byte |
The '''Access Byte''' is laid out as follows: |
||
<pre> |
|||
ACCESS BYTE: |
|||
┏━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┓ |
|||
┃ 7 │ 6 5 │ 4 │ 3 │ 2 │ 1 │ 0 ┃ |
|||
┠─────────┼───────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┨ |
|||
┃Pr │Privl │S │Ex │DC │RW │Ac ┃ |
|||
┗━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┛ |
|||
</pre> |
|||
* '''Pr:''' Present bit. Allows an entry to refer to a valid segment. Must be set ('''1''') for any valid segment. |
* '''Pr:''' Present bit. Allows an entry to refer to a valid segment. Must be set ('''1''') for any valid segment. |
||
* '''Privl:''' Descriptor privilege level field. Contains the [[Security#Rings| |
* '''Privl:''' Descriptor privilege level field. Contains the [[Security#Rings|CPU Privilege level]] of the segment. '''0''' = highest privilege (kernel), '''3''' = lowest privilege (user applications). |
||
* '''S:''' Descriptor type bit. If clear ('''0''') the descriptor defines a system segment (eg. a [[Task_State_Segment|Task State Segment]]). If set ('''1''') it defines a code or data segment. |
* '''S:''' Descriptor type bit. If clear ('''0''') the descriptor defines a system segment (eg. a [[Task_State_Segment|Task State Segment]]). If set ('''1''') it defines a code or data segment. |
||
* '''Ex:''' Executable bit. If clear ('''0''') the descriptor defines a data segment. If set ('''1''') it defines a code segment which can be executed from. |
* '''Ex:''' Executable bit. If clear ('''0''') the descriptor defines a data segment. If set ('''1''') it defines a code segment which can be executed from. |
||
Line 50: | Line 101: | ||
* '''Ac:''' Accessed bit. Best left clear ('''0'''), the CPU will set it when the segment is accessed. |
* '''Ac:''' Accessed bit. Best left clear ('''0'''), the CPU will set it when the segment is accessed. |
||
=== Flags === |
|||
⚫ | |||
<pre> |
|||
FLAGS: |
|||
┏━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┓ |
|||
┃ 3 │ 2 │ 1 │ 0 ┃ |
|||
┠─────────┼─────────┼─────────┼─────────┨ |
|||
┃Gr │Sz │L │Reserved ┃ |
|||
┗━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┛ |
|||
</pre> |
|||
* '''Gr:''' Granularity flag, indicates the size the '''Limit''' value is scaled by. If clear ('''0'''), the '''Limit''' is in 1 Byte blocks (byte granularity). If set ('''1'''), the '''Limit''' is in 4 KiB blocks (page granularity). |
* '''Gr:''' Granularity flag, indicates the size the '''Limit''' value is scaled by. If clear ('''0'''), the '''Limit''' is in 1 Byte blocks (byte granularity). If set ('''1'''), the '''Limit''' is in 4 KiB blocks (page granularity). |
||
* '''Sz:''' Size flag. If clear ('''0'''), the descriptor defines a 16-bit protected mode segment. If set ('''1''') it defines a 32-bit protected mode segment. A GDT can have both 16-bit and 32-bit selectors at once. |
* '''Sz:''' Size flag. If clear ('''0'''), the descriptor defines a 16-bit protected mode segment. If set ('''1''') it defines a 32-bit protected mode segment. A GDT can have both 16-bit and 32-bit selectors at once. |
||
* '''L:''' Long-mode code flag. If set ('''1'''), the descriptor defines a 64-bit code segment. When set, '''Sz''' should always be clear. For any other type of segment (other code types or any data segment), it should be clear ('''0'''). |
* '''L:''' Long-mode code flag. If set ('''1'''), the descriptor defines a 64-bit code segment. When set, '''Sz''' should always be clear. For any other type of segment (other code types or any data segment), it should be clear ('''0'''). |
||
** The diagram currently does not reflect its position, it is bit-53 of the overall descriptor or one bit to the right of the '''Sz''' bit in this diagram. |
|||
⚫ | |||
== See |
== See Also == |
||
=== Articles === |
=== Articles === |
||
* [[GDT Tutorial]] |
* [[GDT Tutorial]] |