Description: This blog is kernel related to the Gdt,ldt and LDT related source analysis, and the Gdt,ldt and IDT detailed instructions and principles can be found in the Intel IA-32 Architecture Manual. No longer repeat here, (manual address) 1, Descriptor (64bits) category
2, the relationship between the three
A, Gdt,idt are all global. LDT is local (has its descriptor in GDT)
B, GDT used to store descriptors (door or not door), several CPUs in the system, there are several GDT
struct Gdt_page {
struct desc_struct gdt[gdt_entries];
__attribute__ ((Aligned (page_size)));
declare_per_cpu_page_aligned (struct gdt_page, gdt_page);
C, IDT the entire system has only one
D, the system needs to initialize GDT and IDT when starting. LDT and process related, and not necessarily must have
3, IA-32 the structure of various descriptors
4. Descriptor Structure Definition
<arch/x86/include/asm/desc_defs.h>
struct Desc_struct {
union {
struct {
unsigned int A;
unsigned int b;
};
struct {
u16 limit0;
U16 Base0;
Unsigned base1:8, Type:4, s:1, Dpl:2, p:1;
Unsigned limit:4, avl:1, L:1, D:1, G:1, Base2:8;};}
__ATTRIBUTE__ ((packed));
Federation--it's a beautiful way to access and set up member domains. The first anonymous struct above is used as a member to access the value of the exit, and the second structure below sets the entry for the value of the real member.
Field (combined with the diagram above):
Limit: Length of segment
Base: The linear address of the first byte of a segment, consisting of three parts of a base0,base1,base2
Type: Types of segments and access permissions
S: System flag. n system segment; 0-Normal segment
DPL: Descriptor Privilege level
P:segment-present. Linux is always under 1
Avl:linux, No.
D: Distinguish between code snippets or data segments
G: Segment size granularity. Calculated in 4 K multiples
On a 32-bit machine, this is the data structure of all descriptors, no subdivisions and no doors.
typedef struct DESC_STRUCT Gate_desc;
typedef struct DESC_STRUCT Ldt_desc;
typedef struct DESC_STRUCT Tss_desc;
Because all three types of descriptors are of a struct type, the following macros are used to initialize the table entries in GDT
#define GDT_ENTRY_INIT (Flags, base, limit) {{{\
. A = (limit) & 0xFFFF) | ((base) & 0xFFFF) <<, \
. B = ((base) & 0xff0000) >> 16 | (((Flags) & 0XF0FF) << 8) | \
((limit) & 0xf0000) | (base) & 0xff000000), \}}
But on a 64-bit machine, Linux is carefully divided:
16-byte Gate descriptor structure
/* 16byte Gate * *
struct Gate_struct64 {
u16 offset_low;
U16 segment;
Unsigned ist:3, Zero0:5, Type:5, Dpl:2, p:1;
U16 Offset_middle;
U32 Offset_high;
U32 Zero1;
} __ATTRIBUTE__ ((packed));
16-byte LDT or TSS descriptor structure
/* LDT or TSS descriptor in the GDT. Bytes. * *
struct LDTTSS_DESC64 {
u16 limit0;
U16 Base0;
Unsigned base1:8, Type:5, Dpl:2, p:1;
Unsigned limit1:4, Zero0:3, G:1, Base2:8;
U32 base3;
U32 Zero1;
} __ATTRIBUTE__ ((packed));
typedef struct GATE_STRUCT64 Gate_desc;
typedef struct LDTTSS_DESC64 Ldt_desc;
typedef struct LDTTSS_DESC64 Tss_desc;
See from the code above that the TypeDef is redefined on either 32-bit or 64-bit machines to provide the system with other partially consistent type names that use this descriptor
Enumeration that distinguishes descriptors
enum {
gate_interrupt = 0xE,
gate_trap = 0xF,
gate_call = 0xC,
gate_task = 0x5,
};
enum {
desc_tss = 0x9,
Desc_ldt = 0x2,
desctype_s = 0x10, /*!system *
/};
System Gdt,idt Pointer Description structure
struct DESC_PTR {
unsigned short size;
unsigned long address;
__ATTRIBUTE__ ((packed));
This structure records the size of the GDT or IDT of the system and the linear base in the system.
Reference:
<arch/x86/include/asm/desc_defs.h>
Http://www.osdever.net/tutorials/pdf/descriptors.pdf.