Global Descriptor Table (GDT)

A Little History

16-bit Addressing Limitation:

The Intel 8086, released in 1978, was designed with a 20-bit address bus but only 16-bit registers. This allowed the 8086 to address up to 1 MB of memory, but not straightforward to manage with only 16-bit registers.

To address this limitation, Intel introduced segmentation. The 8086 used segment registers (CS, DS, SS, ES) to hold segment address, each segment being a 64 KB block. A logical address (segment:offset) could then be mapped to a 20-bit physical address.

Segmentation Model:

  • Segmentation in the 8086 allowed the processor to access more memory than what a single 16-bit register could address. By combining a segment base address stored in a segment register with a 16-bit offset, the 8086 could effectively manage its 1MB address space.
  • This model enabled code, data, stack, and extra segments to be handled separately, providing a basic form of memory organization and protection.

Evolution Beyond the 8086:

As computing needs grew, the limitations of the 8086 segmentation model became apparent. With the introduction of the 80286 and later processors, Intel extended the segmentation concept to include more sophisticated memory management and protection mechanisms:

  • Introduction of the 80286:
    • The Intel 80286, released in 1982, introduced protected mode, which extended the capabilities of the segmentation model. In protected mode, segment descriptors could specify more attributes like access rights and limit checks, offering better protection and isolation between different types of memory (code, data, stack).
    • The GDT was introduced as part of this enhanced segmentation model. The GDT allowed the definition of a global set of segment descriptors accessible by all tasks, thus centralizing segment management and improving security and flexibility.
  • Advanced Features in the 80386 and Beyond:
    • The Intel 80386, released in 1985, further expanded the capabilities of segmentation by introducing 32-bit addressing and paging. This allowed for more complex memory management schemes, combining the benefits of segmentation and paging for improved efficiency and protection.
    • The GDT continued to play a critical role in defining segment properties, even as paging became the primary mechanism for memory management in modern operating systems. The GDT allowed the definition of larger and more complex memory models while maintaining backward compatibility with earlier x86 processors.

Key Contributions of the GDT

  1. Memory Segmentation: Historically, x86 processors used memory segmentation to address memory beyond the 16-bit addressing limit. Segmentation divides memory into variable-sized chunks called segments, allowing programs to access more than 64 KB of memory. The GDT defines the attributes of these segments, such as their base address, size, and access permissions.
  2. Memory Protection: The GDT enables memory protection by assigning privilege levels (called Descriptor Privilege Levels or DPL) to segments. This feature restricts access to memory segments based on the privilege level of the code attempting to access them. For instance, an operating system might define separate segments for user-mode and kernel-mode code and data, ensuring that user processes cannot directly access privileged system resources.
  3. Operating System Control: The GDT provides the operating system with control over memory management. By defining segments and their attributes, the operating system can enforce memory protection, manage memory allocation and deallocation, and switch between different memory contexts efficiently.
  4. Processor State Management: Along with the Task State Segment (TSS) and other system segments, the GDT plays a crucial role in managing the processor's state during task switches and other context changes. The TSS contains information about the processor's state, such as register values and the stack pointer, facilitating efficient context switching between different tasks or threads.

Virtual Memory Support: While the GDT itself does not directly handle virtual memory, it lays the groundwork for its implementation. Virtual memory management relies on mechanisms like segmentation to provide processes with their own virtual address spaces. The GDT's role in memory segmentation is thus foundational to the implementation of virtual memory systems on x86 processors.

What is the GDT (Global Descriptor Table)?

The Global Descriptor Table is a data structure used by Intel x86 processors to define the characteristics of the various memory areas used during program execution. These characteristics include the base address, size, and access permissions of memory segments. The GDT allows the CPU to switch between different segments of memory with specific properties efficiently.

It contains entries telling the CPU about memory segments.

Structure of the GDT

The GDT is an array of entries called segment descriptors. Each descriptor is 8 bytes long and defines the properties of a segment. A segment can be a piece of code, data, or a system segment (like a task state segment or LDT). Here is the structure of a typical segment descriptor:

  • Base Address: 32 bits split across three fields (Base 31:24, Base 23:16, Base 15:0).
  • Segment Limit: 20 bits split across two fields (Limit 19:16, Limit 15:0).
  • Access Byte: 8 bits defining the segment type, descriptor privilege level (DPL), and presence bit.
  • Flags: 4 bits defining the granularity, size, and other characteristics.

Each GDT entry provides detailed control over the corresponding memory segment. The combination of these entries enables the CPU to manage memory with precision and security.