mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-09-21 11:53:35 +08:00
显示段选择符和段描述符...
This commit is contained in:
@@ -22,14 +22,167 @@ MODULE_LICENSE("Dual BSD/GPL");
|
||||
#define bit_clr(number, pos) ((number) &= ~(1 << (pos))) /// 把某位清0
|
||||
#define bit_cpl(number, pos) ((number) ^= 1 << (pos)) /// 把number的POS位取反
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 打印段描述符的数据
|
||||
* desc 指向GDT的指针
|
||||
*/
|
||||
static void print_desc_struct(struct desc_struct *desc)
|
||||
{
|
||||
#if 0
|
||||
printk("limit0 = %0x, ", desc->limit0);
|
||||
printk("base0 = %0x, ", desc->base0);
|
||||
|
||||
printk("base1 = %0x, ", desc->base1);
|
||||
printk("type = %0x, ", desc->type);
|
||||
printk("s = %0x, ", desc->s);
|
||||
printk("dpl = %0x, ", desc->dpl);
|
||||
printk("p = %0x, ", desc->p);
|
||||
|
||||
printk("limit = %0x, ", desc->limit);
|
||||
printk("avl = %0x, ", desc->avl);
|
||||
printk("l = %0x, ", desc->l);
|
||||
printk("d = %0x, ", desc->d);
|
||||
printk("g = %0x, ", desc->g);
|
||||
|
||||
printk("base2 = %0x\n", desc->base2);
|
||||
#endif
|
||||
/*
|
||||
段描述符
|
||||
----------------------------------------------------------------------------------------
|
||||
63 56/55 52/51 48/47 40/39 32/31 16/15 0
|
||||
----------------------------------------------------------------------------------------
|
||||
| B31-B24 | G D/B O AV | L19-L16 | P DPL S E ED/C R/W A | B23-B16 | B15-B0 | L15-L0 |
|
||||
----------------------------------------------------------------------------------------
|
||||
| | | | | | | | | | |
|
||||
| | | | | | | --------- |
|
||||
| | | | | | | | |
|
||||
| | | | | | | | ------------ = 1, 已被访问过
|
||||
| | | | | | | |
|
||||
| | | | | | | | |-- E = 0, 数据段
|
||||
| | | | | | | | ------|-- ED = 0, 向上延伸(数据段); ED = 1, 向下延伸(堆栈段)
|
||||
| | | | | | | | | |-- W = 0, 不可写入; W = 1, 可写入
|
||||
| | | | | | | ----------|
|
||||
| | | | | | | | |-- E = 1, 代码段
|
||||
| | | | | | | ------|-- C = 0, 忽视特权级别; C = 1, 依照特权级别
|
||||
| | | | | | | |-- R = 0, 不能读; R = 1, 可读
|
||||
| | | | | | |
|
||||
| | | | | | | |-- = 0, 表示专用于系统管理的系统段, 如各类描述表
|
||||
| | | | | | |---------------------|
|
||||
| | | | | | |-- = 1, 表示用于一般的代码段或者数据段
|
||||
| | | | | |
|
||||
| | | | | ---------------------------- 特权级别
|
||||
| | | | ------------------------------- = 1, 表示该段在内存中
|
||||
| | | |
|
||||
| | | |
|
||||
| | | -------- 可由软件使用, CPU忽略该位
|
||||
| | ----------- 永远为0
|
||||
| -------------- = 1, 表示对该段的访问为32位指令; = 0, 为16位指令
|
||||
----------------- = 1, 段长以4K字节为单位; = 0, 以字节为单位
|
||||
|
||||
*/
|
||||
|
||||
#define get_desc_struct_BASE0(gdt) (((gdt) >> 16) & 0xffff)
|
||||
#define get_desc_struct_BASE1(gdt) (((gdt) >> 32) & 0xff)
|
||||
#define get_desc_struct_BASE2(gdt) (((gdt) >> 56) & 0xff)
|
||||
#define get_desc_struct_BASE(gdt) \
|
||||
((get_desc_struct_BASE0(gdt) << 16) \
|
||||
| (get_desc_struct_BASE1(gdt) << 8) \
|
||||
| (get_desc_struct_BASE2(gdt)))
|
||||
|
||||
|
||||
#define get_desc_struct_LIMIT0(gdt) ((gdt) & 0xffff)
|
||||
#define get_desc_struct_LIMIT1(gdt) (((gdt) >> 48) & 0x0f)
|
||||
#define get_desc_struct_LIMIT(gdt) \
|
||||
((get_desc_struct_LIMIT0(gdt) << 4) \
|
||||
| (get_desc_struct_LIMIT1(gdt)))
|
||||
|
||||
#define get_desc_struct_G(gdt) (((gdt) >> 55) & 0x01) /* 55 */
|
||||
#define get_desc_struct_D_or_B(gdt) (((gdt) >> 54) & 0x01) /* 54 */
|
||||
#define get_desc_struct_O(gdt) (((gdt) >> 53) & 0x01) /* 53 */
|
||||
#define get_desc_struct_AV(gdt) (((gdt) >> 52) & 0x01) /* 52 */
|
||||
#define get_desc_struct_P(gdt) (((gdt) >> 47) & 0x01) /* 47 */
|
||||
#define get_desc_struct_DPL(gdt) (((gdt) >> 45) & 0x03) /* 46-45 */
|
||||
#define get_desc_struct_S(gdt) (((gdt) >> 44) & 0x01) /* 44 */
|
||||
#define get_desc_struct_E(gdt) (((gdt) >> 43) & 0x01) /* 43 */
|
||||
#define get_desc_struct_ED_or_C(gdt) (((gdt) >> 42) & 0x01) /* 42 */
|
||||
#define get_desc_struct_R_or_W(gdt) (((gdt) >> 41) & 0x01) /* 41 */
|
||||
#define get_desc_struct_A(gdt) (((gdt) >> 40) & 0x01) /* 40 */
|
||||
|
||||
|
||||
printk("0x%08x, 0x%08x | 0x%x | %d | %d |\n",
|
||||
desc->b, desc->a, desc->type, desc->dpl, desc->s);
|
||||
unsigned long data = *((unsigned long *)desc);
|
||||
printk("base = 0x%0x, limit = 0x%0x, P = %d, DPL = %d, type = %d%d%d%d\n",
|
||||
get_desc_struct_BASE(data), get_desc_struct_LIMIT(data),
|
||||
get_desc_struct_P(data), get_desc_struct_DPL(data),
|
||||
get_desc_struct_S(data), get_desc_struct_ED_or_C(data),
|
||||
get_desc_struct_R_or_W(data), get_desc_struct_A(data));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 打印 CPU 的 GDT 的数据
|
||||
* 参数
|
||||
* cpu : CPU 的编号
|
||||
*/
|
||||
static void print_cpu_gdt_table(unsigned int cpu)
|
||||
{
|
||||
int i = 0;
|
||||
struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
|
||||
|
||||
|
||||
printk("GDT_ENTRIES = %d\n", GDT_ENTRIES);
|
||||
printk("-----------------------------------\n");
|
||||
printk("|\t\t\t\t| type | dpl | s |\n");
|
||||
for(i = 0; i < GDT_ENTRIES; i++)
|
||||
{
|
||||
printk("| [%0x] = ", i);
|
||||
print_desc_struct(gdt_table + i);
|
||||
}
|
||||
printk("-----------------------------------\n");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 打印段选择符和段描述符号的信息
|
||||
*
|
||||
* 段标识符(段选择符)(存放在段寄存器中)字段如下 :
|
||||
* index 用来得到段描述符在GDT或LDT中的偏移(位置)
|
||||
* TI 指明段描述符是在GDT中(TI=0)或在LDT中(TI=1)
|
||||
* RPL 请求特权级,
|
||||
*
|
||||
* 由于一个段描述符是8字节,
|
||||
* 因此它的地址=GDT或LDT内的首地址+(index*8).
|
||||
* 能够保存在GDT中的段描述符的最大数目是8191(213-1),其中13是index的位数.
|
||||
* 不同段的段描述符构成段描述符表,
|
||||
* 段描述符(8字节)存放在全局描述符表(GDT)或局部描述符表(LDT)中
|
||||
* GDT在主存中的地址和大小存放在gdtr控制寄存器中,
|
||||
* 当前正被使用的LDT地址和大小存放在ldtr控制寄存器中。
|
||||
*/
|
||||
static void print_segment_desc(unsigned long seg)
|
||||
{
|
||||
#define get_segment_INDEX(n) ((n) >> 3)
|
||||
#define get_segment_TI(n) (((n) >> 2) & 0x01)
|
||||
#define get_segment_RPL(n) ((n) & 0x03)
|
||||
printk("0x%0x, index = %d, TI = %d, RPL = %d\n", seg,
|
||||
get_segment_INDEX(seg),
|
||||
get_segment_TI(seg),
|
||||
get_segment_RPL(seg));
|
||||
}
|
||||
|
||||
|
||||
// http://lxr.free-electrons.com/source/arch/x86/include/asm/segment.h#L123
|
||||
/*
|
||||
* 打印 Linux 内核中分段信息,
|
||||
* 打印段描述
|
||||
*/
|
||||
static void print_segment(void)
|
||||
{
|
||||
long data = 0;
|
||||
long data = 0;
|
||||
struct desc_struct *gdt_table = get_cpu_gdt_table(1);
|
||||
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------------------------
|
||||
@@ -51,79 +204,55 @@ static void print_segment(void)
|
||||
__USER_DS = 0x0033 = | 00110011 00000000 |
|
||||
__USER_DS = 0x002B = | 00101011 00000000 |
|
||||
*/
|
||||
data = __KERNEL_CS;
|
||||
printk("__KERNEL_CS = %0x, index = %d, TI = %d, RPL = %d\n", data,
|
||||
get_segment_INDEX(data),
|
||||
get_segment_TI(data),
|
||||
get_segment_RPL(data));
|
||||
printk("=====================\n");
|
||||
// 打印__KERNEL_CS的段描述符
|
||||
printk("__KERNEL_CS = ");
|
||||
print_segment_desc(__KERNEL_CS);
|
||||
// 打印__KERNEL_CS在gdt_table中的具体值
|
||||
printk("__KERNEL_CS @ index(%d) in cpu_gdt_table\n", get_segment_INDEX(__KERNEL_CS));
|
||||
printk("GDT[%d] = ", get_segment_INDEX(__KERNEL_CS));
|
||||
print_desc_struct(gdt_table + get_segment_INDEX(__KERNEL_CS));
|
||||
printk("=====================\n\n");
|
||||
|
||||
data = __KERNEL_DS;
|
||||
printk("__KERNEL_DS = %0x, index = %d, TI = %d, RPL = %d\n", data,
|
||||
get_segment_INDEX(data),
|
||||
get_segment_TI(data),
|
||||
get_segment_RPL(data));
|
||||
printk("=====================\n");
|
||||
// 打印__KERNEL_DS的段描述符
|
||||
printk("__KERNEL_DS = ");
|
||||
print_segment_desc(__KERNEL_DS);
|
||||
// 打印__KERNEL_DS在gdt_table中的具体值
|
||||
printk("__KERNEL_DS @ index(%d) in cpu_gdt_table\n", get_segment_INDEX(__KERNEL_DS));
|
||||
printk("GDT[%d] = ", get_segment_INDEX(__KERNEL_DS));
|
||||
print_desc_struct(gdt_table + get_segment_INDEX(__KERNEL_DS));
|
||||
printk("=====================\n\n");
|
||||
|
||||
data = __USER_CS;
|
||||
printk("__USER_CS = %0x, index = %d, TI = %d, RPL = %d\n", data,
|
||||
get_segment_INDEX(data),
|
||||
get_segment_TI(data),
|
||||
get_segment_RPL(data));
|
||||
|
||||
data = __USER_DS;
|
||||
printk("__USER_DS = %0x, index = %d, TI = %d, RPL = %d\n", data,
|
||||
get_segment_INDEX(data),
|
||||
get_segment_TI(data),
|
||||
get_segment_RPL(data));
|
||||
}
|
||||
|
||||
|
||||
static void print_desc_struct(struct desc_struct *desc)
|
||||
{
|
||||
#if 0
|
||||
printk("limit0 = %0x, ", desc->limit0);
|
||||
printk("base0 = %0x, ", desc->base0);
|
||||
|
||||
printk("base1 = %0x, ", desc->base1);
|
||||
printk("type = %0x, ", desc->type);
|
||||
printk("s = %0x, ", desc->s);
|
||||
printk("dpl = %0x, ", desc->dpl);
|
||||
printk("p = %0x, ", desc->p);
|
||||
|
||||
printk("limit = %0x, ", desc->limit);
|
||||
printk("avl = %0x, ", desc->avl);
|
||||
printk("l = %0x, ", desc->l);
|
||||
printk("d = %0x, ", desc->d);
|
||||
printk("g = %0x, ", desc->g);
|
||||
|
||||
printk("base2 = %0x\n", desc->base2);
|
||||
#endif
|
||||
printk("0x%08x, 0x%08x | 0x%x | %d | %d |\n",
|
||||
desc->b, desc->a, desc->type, desc->dpl, desc->s);
|
||||
}
|
||||
|
||||
|
||||
static void print_cpu_gdt_table(struct desc_struct *desc, int size)
|
||||
{
|
||||
int i = 0;
|
||||
printk("-----------------------------------\n");
|
||||
printk("|\t\t\t\t| type | dpl | s |\n");
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
printk("| [%0x] = ", i);
|
||||
print_desc_struct(desc + i);
|
||||
}
|
||||
printk("-----------------------------------\n");
|
||||
printk("=====================\n");
|
||||
// 打印__USER_CS的段描述符
|
||||
printk("__USER_CS = ");
|
||||
print_segment_desc(__USER_CS);
|
||||
// 打印__USER_CS在gdt_table中的具体值
|
||||
printk("__USER_CS @ index(%d) in cpu_gdt_table\n", get_segment_INDEX(__USER_CS));
|
||||
printk("GDT[%d] = ", get_segment_INDEX(__USER_CS));
|
||||
print_desc_struct(gdt_table + get_segment_INDEX(__USER_CS));
|
||||
printk("=====================\n\n");
|
||||
|
||||
printk("=====================\n");
|
||||
// 打印__USER_DS的段描述符
|
||||
printk("__USER_DS = ");
|
||||
print_segment_desc(__USER_DS);
|
||||
// 打印__USER_DS在gdt_table中的具体值
|
||||
printk("__USER_DS @ index(%d) in cpu_gdt_table\n", get_segment_INDEX(__USER_DS));
|
||||
printk("GDT[%d] = ", get_segment_INDEX(__USER_DS));
|
||||
print_desc_struct(gdt_table + get_segment_INDEX(__USER_DS));
|
||||
printk("=====================\n\n");
|
||||
}
|
||||
|
||||
static int hello_init(void)
|
||||
{
|
||||
printk("GDT_ENTRIES = %d\n", GDT_ENTRIES);
|
||||
struct desc_struct *gdt_table = get_cpu_gdt_table(1);
|
||||
|
||||
print_cpu_gdt_table(gdt_table, GDT_ENTRIES);
|
||||
print_cpu_gdt_table(0);
|
||||
|
||||
print_segment();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user