1. 程式人生 > >程序0的LDT0程式碼段描述符分析

程序0的LDT0程式碼段描述符分析

LDT0的值為

····
    	{ \
    		{0,0}, \
    /* ldt */	{0x9f,0xc0fa00}, \
    		{0x9f,0xc0f200}, \
    	},
···

其中第二項{0x9f,0xc0fa00}為程式碼段的描述符。

然後看task中對ldt的定義:

struct task_struct {
/* these are hardcoded - don't touch */
	long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	long counter;
	long priority;
	long signal;
	struct sigaction sigaction[32];
	long blocked;	/* bitmap of masked signals */
/* various fields */
	int exit_code;
	unsigned long start_code,end_code,end_data,brk,start_stack;
	long pid,father,pgrp,session,leader;
	unsigned short uid,euid,suid;
	unsigned short gid,egid,sgid;
	long alarm;
	long utime,stime,cutime,cstime,start_time;
	unsigned short used_math;
/* file system info */
	int tty;		/* -1 if no tty, so it must be signed */
	unsigned short umask;
	struct m_inode * pwd;
	struct m_inode * root;
	struct m_inode * executable;
	unsigned long close_on_exec;
	struct file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
	struct desc_struct ldt[3];
/* tss for this task */
	struct tss_struct tss;
};

其中 ldt的型別為結構體:desc_struct
可以得知desc_struct的定義為:

typedef struct desc_struct {
	unsigned long a,b;
} desc_table[256];

就是兩個long的整數,而每個long都是4個位元組,32位的。

ok,我們把{0x9f,0xc0fa00}展開完整(8個位元組):0x0000 009f,0x00c0 fa00;其中第一個數在低32位,第二數在高32位
也就是:
高:
0x00c0
0xfa00
低:
0x0000
0x009f
轉換為bit:
c為1100

63-48:00000000 11000000
47-32:11111010 00000000
31-16:00000000 00000000
15-00:00000000 10011111

根據段描述符的定義:
15-00為段限長:0x009f,其單位根據G=1,為說明單位是4k。
31-16(最低16位):00000000 00000000 ,39-32(次低8位):00000000,63-56(高8位):00000000 合併起來構成段基址:00000000 00000000 00000000 00000000,就是地址0.
它的DPL為46-45位:11,也就是3

再看看核心的GDT 程式碼段描述符號:

gdt:	.quad 0x0000000000000000	/* NULL descriptor */
	.quad 0x00c09a0000000fff	/* 16Mb */
	.quad 0x00c0920000000fff	/* 16Mb */
	.quad 0x0000000000000000	/* TEMPORARY - don't use */
	.fill 252,8,0			/* space for LDT's and TSS's etc */

第2項0x00 c0 9a 00 00 00 0f ff 為核心程式碼段
高:
0x00c0
0x9a00
低:
0x0000
0x0fff

63-48:00000000 11000000
47-32:10011010 00000000
31-16:00000000 00000000
15-00:00001111 11111111

它的31-16(最低16位)為00000000 00000000 ,39-32(次低8位)為00000000,63-56(高8位)為00000000 合併起來構成段基址:00000000 00000000 00000000 00000000
DPL:00,也就是0

因此,程序0的程式碼段基址與核心的段基址是相同的,都為0.