版权声明:本文为博主jmh原创文章,未经博主允许不得转载。 https://blog.csdn.net/jmh1996/article/details/83034195
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.