Global Descriptor Table

From OSDev.wiki
Revision as of 20:46, 7 December 2006 by osdev>Walling (creating page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The Global Descriptor Table (GDT) is specific for the I386 architecture. It contains entries telling the CPU about memory segments. A similar Interrupts Descriptor Table exists containing tasks and interrupts descriptors. Read the GDT for dummies article.

Structure

The GDT is loaded using the LGDT instruction. It expects the location of a GDT description structure:

Byte:   0 . . . . . . 7 8 . . . . . .15
       +---------------+---------------+
   0   |              Size             |
       +---------------+---------------+
        0 . . . . . . 7 8 . . . . . .15 16. . . . . .23 24. . . . . .31
       +---------------+---------------+---------------+---------------+
   2   |                             Offset                            |
       +---------------+---------------+---------------+---------------+

The offset is the location of the table itself. The size is the size of the table subtracted by 1. This is because the maximum value of size is 65535, while the GDT can be up to 65536 bytes (a maximum of 8192 entries). Further no GDT can have a size of 0.

The table contain 8-byte entries. Each entry have a complex structure:

Byte:   0 . . . . . . 7 8 . . . . . .15 16. . . . . .23 24. . . . . .31
       +---------------+---------------+---------------+---------------+
   0   |           Limit 0:15          |           Base 0:15           |
       +---------------+---------------+---------------+---------------+
        0 . . . . . . 7 8 . . . . . .15 16. . . . . .23 24. . . . . .31
       +---------------+---------------+-------+-------+---------------+
   4   |  Base 16:23   | Access byte   | Flags |       |  Base 24:31   |
       +---------------+---------------+-------+---^---+---------------+
                                                   |
                                              Limit 16:19

What "Limit 0:15" means is that the field contains bits 0-15 of the limit value. The base is a 32 bit value containing the liniar address where the segment begins. The limit, a 20 bit value, tells the size of the segment. It is either in bytes (1 B) or pages (4 KiB) and is subtracted by 1. If you choose page granularity (4 KiB) and sets the limit to 0xFFFFF the segment will span the full 4 GiB address space. Here is the structure of the access byte and flags:

Access byte:                 Flags:
 0  .  .  .  .  .  .  7       0  .  .  3
+----------------------+     +----------+
|Pr Privl 1 Ex DC RW Ac|     |Gr Sz 0  0|
+----------------------+     +----------+

The bit fields are:

  • Pr: Present bit. This must be 1 for all valid selectors.
  • Privl: Privilege, 2 bits. Contains the ring level, 0 = highest (kernel), 3 = lowest (user applications).
  • Ex: Executable bit. If 1 code in this segment can be executed, ie. a code selector. If 0 it is a data selector.
  • DC: Direction bit/Conforming bit.
    • Direction bit for data selectors: Tells the direction. 0 the segment grows up. 1 the segment grows down, ie. the offset has to be greater than the base.
    • Conforming bit for code selectors: Privilege-related. (Please add more information)
  • RW: Readable bit/Writable bit.
    • Readable bit for code selectors: Whether read access for this segment is allowed. Write access is never allowed for code segments.
    • Writable bit for data selectors: Whether write access for this segment is allowed. Read access is always allowed for data segments.
  • Ac: Accessed bit. Just set to 0. The CPU sets this to 1 when the segment is accessed.
  • Gr: Granularity bit. If 0 the limit is in 1 B blocks (byte granularity), if 1 the limit is in 4 KiB blocks (page granularity).
  • Sz: Size bit. If 0 the selector defines 16 bit protected mode. If 1 it defines 32 bit protected mode. You can have both 16 bit and 32 bit selectors at once.

See also

External references