首页
社区
课程
招聘
[求助]内核相关
发表于: 2008-12-3 14:56 3529

[求助]内核相关

pch 活跃值
1
2008-12-3 14:56
3529
线程从用户态切换的内核态,都有哪些途径?真正切换时都做了哪些动作?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
2
CPU发生特权极切换,可分几种情况。

1.发生异常,处理器转入IDT中对应的描述符指向的异常处理入口,该入口是操作系统安装的。

2.外部中断,类似于异常,因为INTEL处理器把异常和中断用同样的方式对待。

3.系统调用,分不同的方式

    传统的“软件中断”,即故意产生一个异常。说它传统,因为曾经许多操作系统都用软件中断来实现系统调用,即使那时还没有特权级的概念 。在32位保护模式下,虽然INTEL提供了所谓“调用门”机制,但一般系统软件还是倾向于使用“陷阱门”来实现系统调用的入口,所以说软件中断产生一个“异常”。DOS的系统服务是int 0x21,在NT中,中断号是0x2e,Linux上使用int 0x80。

    sysenter指令,这是一种比软件中断更快的系统调用方式。它所执行的CPU动作比软件中断要少,所以速度快一些。但这不是386最初设计时的指令,是后来增加的(具体哪一代增加,我忘记了,大约是奔腾II或者差不多那个时期的吧),不过现在的产品上都是存在这条指令的。

    syscall指令,x64体系结构新增加的系统调用指令。对x64不熟悉,不说了。

通过异常或中断进入ring0的方法,CPU的动作大致是相同的,从TSS中取得ring0的SS及ESP,切换到ring0的栈,然后将必要的信息(比如异常或中断时的原来的CS,EIP,SS,ESP,EFLAGS等)压栈保存,特定的异常还会再压入一个异常码;从IDT中得到对应的中断门或陷阱门,然后转到入口地址。

通过sysenter执行系统调用则简单地多,CPU直接从MSR中找到ring0的CS,EIP,ESP的值,而SS的值是CS+8,然后便进入ring0代码执行了。当然还有其它实现细节,比如清除EFLAGS中的VM位等等。它之所以快,一方便它不需要访问IDT(位于内存中),而直接读取MSR(CPU的寄存器,访问速度比内存快几个数量级),另一方面也不把返回地址和ring3栈指针等进行压栈。所以为了使用sysenter,实际上还要初始化其它一些东西。

具体细节请查询INTEL的指令手册。

http://www.intel.com/products/processor/manuals/
2008-12-3 16:34
0
雪    币: 2368
活跃值: (81)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
3
楼主很幸运。书呆子可是cpu相关的行家里手.......

膜拜膜拜..........
2008-12-3 16:48
0
雪    币: 108
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
受益匪浅……
2008-12-3 20:27
0
游客
登录 | 注册 方可回帖
返回
//