PatchworkOS
Loading...
Searching...
No Matches
GDT

Global Descriptor Table. More...

Data Structures

struct  gdt_desc_t
 GDT descriptor structure. More...
 
struct  gdt_segment_t
 A single GDT segment descriptor. More...
 
struct  gdt_long_system_segment_t
 A long mode system segment descriptor, used for TSS and LDT. More...
 
struct  gdt_t
 The actual GDT structure. More...
 

Enumerations

enum  gdt_ring_t {
  GDT_RING0 = 0 ,
  GDT_RING1 = 1 ,
  GDT_RING2 = 2 ,
  GDT_RING3 = 3
}
 
enum  gdt_segment_selector_t {
  GDT_NULL = 0 ,
  GDT_KERNEL_CODE = 0x08 ,
  GDT_KERNEL_DATA = 0x10 ,
  GDT_USER_DATA = 0x18 ,
  GDT_USER_CODE = 0x20 ,
  GDT_TSS = 0x28 ,
  GDT_CS_RING0 = GDT_KERNEL_CODE | GDT_RING0 ,
  GDT_SS_RING0 = GDT_KERNEL_DATA | GDT_RING0 ,
  GDT_CS_RING3 = GDT_USER_CODE | GDT_RING3 ,
  GDT_SS_RING3 = GDT_USER_DATA | GDT_RING3
}
 Segment selectors. More...
 
enum  gdt_access_t {
  GDT_ACCESS_ACCESSED = 1 << 0 ,
  GDT_ACCESS_READ_WRITE = 1 << 1 ,
  GDT_ACCESS_DIRECTION_CONFORMING = 1 << 2 ,
  GDT_ACCESS_EXEC = 1 << 3 ,
  GDT_ACCESS_SYSTEM = 0 << 4 ,
  GDT_ACCESS_DATA_CODE = 1 << 4 ,
  GDT_ACCESS_TYPE_LDT = 0x2 ,
  GDT_ACCESS_TYPE_TSS_AVAILABLE = 0x9 ,
  GDT_ACCESS_TYPE_TSS_BUSY = 0xB ,
  GDT_ACCESS_RING0 = 0 << 5 ,
  GDT_ACCESS_RING1 = 1 << 5 ,
  GDT_ACCESS_RING2 = 2 << 5 ,
  GDT_ACCESS_RING3 = 3 << 5 ,
  GDT_ACCESS_PRESENT = 1 << 7
}
 Access byte. More...
 
enum  gdt_flags_t {
  GDT_FLAGS_NONE = 0 ,
  GDT_FLAGS_RESERVED = 1 << 0 ,
  GDT_FLAGS_LONG_MODE = 1 << 1 ,
  GDT_FLAGS_SIZE = 1 << 2 ,
  GDT_FLAGS_4KB = 1 << 3
}
 Flags byte. More...
 

Functions

void gdt_load_descriptor (gdt_desc_t *descriptor)
 Loads a GDT descriptor.
 
void gdt_init (void)
 Initialize the GDT.
 
void gdt_cpu_load (void)
 Load the GDT on the current CPU.
 
void gdt_cpu_tss_load (tss_t *tss)
 Load a TSS into the GDT and load it using the ltr instruction on the current CPU.
 

Detailed Description

Global Descriptor Table.

The global descriptor table is a legacy feature from the days of 32-bit x86 and older. Most of its features are unused, but is still required in 64-bit mode to specify the current privilage level and to load the TSS.

See also
OSDev Wiki GDT

Enumeration Type Documentation

◆ gdt_access_t

Access byte.

Enumerator
GDT_ACCESS_ACCESSED 

Will be set to 1 when accessed, but its best to set it to 1 manually.

GDT_ACCESS_READ_WRITE 

If set on a code segment, its readable. If set on a data segment, its writable.

GDT_ACCESS_DIRECTION_CONFORMING 

If set on a data segment, the segment grows downwards. If set on a code segment, conforming.

GDT_ACCESS_EXEC 

If set, the segment is a code segment. If clear, its a data segment.

GDT_ACCESS_SYSTEM 

Is a system segment.

GDT_ACCESS_DATA_CODE 

Is a data or code segment.

GDT_ACCESS_TYPE_LDT 

Local Descriptor Table. Only used if the SYSTEM bit is 0.

GDT_ACCESS_TYPE_TSS_AVAILABLE 

Available 64-bit Task State Segment. Only used if the SYSTEM bit is 0.

GDT_ACCESS_TYPE_TSS_BUSY 

Busy 64-bit Task State Segment. Only used if the SYSTEM bit is 0.

GDT_ACCESS_RING0 

Descriptor Privilege Level 0 (kernel).

GDT_ACCESS_RING1 

Descriptor Privilege Level 1, unused.

GDT_ACCESS_RING2 

Descriptor Privilege Level 2, unused.

GDT_ACCESS_RING3 

Descriptor Privilege Level 3 (user).

GDT_ACCESS_PRESENT 

Must be 1 for all valid segments.

Definition at line 56 of file gdt.h.

◆ gdt_flags_t

Flags byte.

Enumerator
GDT_FLAGS_NONE 

No flags set.

GDT_FLAGS_RESERVED 

Must be 0.

GDT_FLAGS_LONG_MODE 

If set, its a 64-bit code segment.

GDT_FLAGS_SIZE 

If set, its a 32-bit segment. If clear, its a 16-bit segment. Ignored in 64-bit mode.

GDT_FLAGS_4KB 

If set, the limit is in 4KiB blocks. If clear, the limit is in bytes.

Definition at line 82 of file gdt.h.

◆ gdt_ring_t

enum gdt_ring_t
Enumerator
GDT_RING0 
GDT_RING1 
GDT_RING2 
GDT_RING3 

Definition at line 21 of file gdt.h.

◆ gdt_segment_selector_t

Segment selectors.

These values are stored in the segment registers (CS, DS, ES, FS, GS, SS) to tell the CPU which segment of the GDT to use.

Enumerator
GDT_NULL 

Null segment selector, unused but the gdt must start with it.

GDT_KERNEL_CODE 

Kernel code segment selector.

GDT_KERNEL_DATA 

Kernel data segment selector.

GDT_USER_DATA 

User data segment selector.

GDT_USER_CODE 

User code segment selector.

GDT_TSS 

TSS segment selector.

GDT_CS_RING0 

Value to load into the CS register for kernel code.

GDT_SS_RING0 

Value to load into the SS register for kernel data.

GDT_CS_RING3 

Value to load into the CS register for user code.

GDT_SS_RING3 

Value to load into the SS register for user data.

Definition at line 36 of file gdt.h.

Function Documentation

◆ gdt_cpu_load()

void gdt_cpu_load ( void  )

Load the GDT on the current CPU.

This will load the GDT using the lgdt instruction and then reload all segment registers to use the new GDT.

Must be called after gdt_init().

Definition at line 55 of file gdt.c.

References gdt_load_descriptor(), gdt_desc_t::offset, and gdt_desc_t::size.

Referenced by cpu_init().

◆ gdt_cpu_tss_load()

void gdt_cpu_tss_load ( tss_t tss)

Load a TSS into the GDT and load it using the ltr instruction on the current CPU.

Note that the actual TTS descriptor in the GDT can be shared between CPUs, as its only used while loading the TSS, after that its just useless.

Parameters
tssThe TSS to load.

Definition at line 63 of file gdt.c.

References GDT_ACCESS_ACCESSED, GDT_ACCESS_PRESENT, GDT_ACCESS_RING0, GDT_ACCESS_SYSTEM, GDT_ACCESS_TYPE_TSS_AVAILABLE, GDT_FLAGS_NONE, gdt_long_system_segment(), and tss_load().

Referenced by cpu_init().

◆ gdt_init()

void gdt_init ( void  )

Initialize the GDT.

This will setup the GDT structure in memory, but will not load it. Loading is done in gdt_cpu_load().

Definition at line 35 of file gdt.c.

References GDT_ACCESS_ACCESSED, GDT_ACCESS_DATA_CODE, GDT_ACCESS_EXEC, GDT_ACCESS_PRESENT, GDT_ACCESS_READ_WRITE, GDT_ACCESS_RING0, GDT_ACCESS_RING3, GDT_ACCESS_SYSTEM, GDT_ACCESS_TYPE_TSS_AVAILABLE, GDT_FLAGS_4KB, GDT_FLAGS_LONG_MODE, GDT_FLAGS_NONE, gdt_long_system_segment(), and gdt_segment().

Referenced by init_early().

◆ gdt_load_descriptor()

void gdt_load_descriptor ( gdt_desc_t descriptor)
extern

Loads a GDT descriptor.

Dont use this directly use gdt_cpu_load() instead.

Parameters
descriptorThe GDT descriptor to load.

Referenced by gdt_cpu_load().