Chinaunix首页 | 论坛 | 博客
  • 博客访问: 43021
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-23 18:46
文章分类
文章存档

2015年(3)

2014年(4)

我的朋友

分类: LINUX

2015-10-05 10:09:36

GDTR: 保存全局描述符表的32位基址和16位表长度值
IDTR:中断描述符表的32位线性基址和16位表长度值
lDTR:由两部分组成,

当使用LLDT把含有LDT表段的选择符加载到LDTR时,LDT的段描述符的段基址,段限长,以及描述符属性也会被加载到LDTR中。当进行任务切换时,处理器会把新任务LDT的段选择符合和段描述符会被自动加载到LDTR

GDT和LDT关系:
系统中所有任务共享的段由GDT来映射,这样的段通常包含有操作系统的段以及所有任务各自包含LDT的特殊段。
段选择子:16位的选择符,保存在CS,DS等寄存器中,格式如下
GDT表的索引,
TI=0时,为GDT的索引
TI=1,时,为LDT的索引
段描述符:包含段基址,段限长,特权级等信息。
如何通过段选择子,GDT和LDT查找代码所在的段。
当TI=1时表示段描述符在LDT中,如下图所示:
  1. 还是先从GDTR寄存器中获得GDT基址。
  2. 从LDTR寄存器中获取LDT所在段的位置索引(LDTR高13位)。
  3. 以这个位置索引在GDT中得到LDT段描述符从而得到LDT段基址。
  4. 用段选择器高13位位置索引值从LDT段中得到段描述符。
  5. 段描述符符包含段的基址、限长、优先级等各种属性,这就得到了段的起始地址(基址),再以基址加上偏移地址yyyyyyyy才得到最后的线性地址。

当 TI=0时表示段描述符在GDT中,如下图所示:
  1.  先从GDTR寄存器中获得GDT基址。
  2.  然后再GDT中以段选择器高13位位置索引值得到段描述符。
  3.  段描述符符包含段的基址、限长、优先级等各种属性,这就得到了段的起始地址(基址),再以基址加上偏移地址yyyyyyyy才得到最后的线性地址

下面以Linu-0.11 多任务简单内核一段代码为例:
# Move to user mode (task 0)
     pushfl
     andl $0xffffbfff, (%esp)
     popfl
     movl $TSS0_SEL, %eax !TSS0_SEL=0X20
     ltr %ax
     movl $LDT0_SEL, %eax !LDT0_SEL=0X28
     lldt %ax
     movl $0, current
     sti
     pushl $0x17       !返回时弹入SS
     pushl $init_stack !返回时弹入ESP
     pushfl            !返回时弹入EFLAGS
     pushl $0x0f       !返回时弹入CS
     pushl $task0      !返回时弹入EIP
     iret
当执行IRET从模拟的中断返回时,栈里面的内容被返回到EIP,CS,EFLAGS,ESP,SS中,
CS=0x0f,可以得到索引为0000 0000 0000 1,TI=1,说明是LDT中的索引,此时LDTR内容为Ox28,在GDT中以0x28
为索引,得到的描述符word 0x0040, ldt0, 0xe200, 0x0     # LDT0 descr 0x28,这样就可以得到LDT0的基址,然后再以CS中的索引,在LDT中得到task0所在段
GDT:
gdt: .quad 0x0000000000000000     /* NULL descriptor */
     .quad 0x00c09a00000007ff     /* 8Mb 0x08, base = 0x00000 */
     .quad 0x00c09200000007ff     /* 8Mb 0x10 */
     .quad 0x00c0920b80000002     /* screen 0x18 - for display */

     .word 0x0068, tss0, 0xe900, 0x0     # TSS0 descr 0x20
     .word 0x0040, ldt0, 0xe200, 0x0     # LDT0 descr 0x28
     .word 0x0068, tss1, 0xe900, 0x0     # TSS1 descr 0x30
     .word 0x0040, ldt1, 0xe200, 0x0     # LDT1 descr 0x38
end_gdt:
     .fill 128,4,0

LDT:
.align 3
ldt0:     .quad 0x0000000000000000
     .quad 0x00c0fa00000003ff     # 0x0f, base = 0x00000
     .quad 0x00c0f200000003ff     # 0x17

tss0:     .long 0                /* back link */
     .long krn_stk0, 0x10          /* esp0, ss0 */
     .long 0, 0, 0, 0, 0          /* esp1, ss1, esp2, ss2, cr3 */
     .long 0, 0, 0, 0, 0          /* eip, eflags, eax, ecx, edx */
     .long 0, 0, 0, 0, 0          /* ebx esp, ebp, esi, edi */
     .long 0, 0, 0, 0, 0, 0           /* es, cs, ss, ds, fs, gs */
     .long LDT0_SEL, 0x8000000     /* ldt, trace bitmap */

     .fill 128,4,0
krn_stk0:
#     .long 0

/************************************/
.align 3
ldt1:     .quad 0x0000000000000000
     .quad 0x00c0fa00000003ff     # 0x0f, base = 0x00000
     .quad 0x00c0f200000003ff     # 0x17

tss1:     .long 0                /* back link */
     .long krn_stk1, 0x10          /* esp0, ss0 */
     .long 0, 0, 0, 0, 0          /* esp1, ss1, esp2, ss2, cr3 */
     .long task1, 0x200          /* eip, eflags */
     .long 0, 0, 0, 0          /* eax, ecx, edx, ebx */
     .long usr_stk1, 0, 0, 0          /* esp, ebp, esi, edi */
     .long 0x17,0x0f,0x17,0x17,0x17,0x17 /* es, cs, ss, ds, fs, gs */
     .long LDT1_SEL, 0x8000000     /* ldt, trace bitmap */

     .fill 128,4,0
krn_stk1:
阅读(7707) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~