Linux2.6对新型CPU快速系统调用的支持
http://tech.ddvip.com 2006年11月20日 社区交流
本文详细介绍Linux2.6对新型CPU快速系统调用的支持
这里还要介绍一个特性,就是 Ring0、Ring3 的代码段描述符和堆栈段描述符在全局描述符表 GDT 中是顺序排列的,这样只需知道 SYSENTER_CS_MSR 中指定的 Ring0 的代码段描述符,就可以推算出 Ring0 的堆栈段描述符以及 Ring3 的代码段描述符和堆栈段描述符。
在 Ring3 的代码调用了 sysenter 指令之后,CPU 会做出如下的操作:
1. 将 SYSENTER_CS_MSR 的值装载到 cs 寄存器
2. 将 SYSENTER_EIP_MSR 的值装载到 eip 寄存器
3. 将 SYSENTER_CS_MSR 的值加 8(Ring0 的堆栈段描述符)装载到 ss 寄存器。
4. 将 SYSENTER_ESP_MSR 的值装载到 esp 寄存器
5. 将特权级切换到 Ring0
6. 如果 EFLAGS 寄存器的 VM 标志被置位,则清除该标志
7. 开始执行指定的 Ring0 代码
在 Ring0 代码执行完毕,调用 SYSEXIT 指令退回 Ring3 时,CPU 会做出如下操作:
1. 将 SYSENTER_CS_MSR 的值加 16(Ring3 的代码段描述符)装载到 cs 寄存器
2. 将寄存器 edx 的值装载到 eip 寄存器
3. 将 SYSENTER_CS_MSR 的值加 24(Ring3 的堆栈段描述符)装载到 ss 寄存器
4. 将寄存器 ecx 的值装载到 esp 寄存器
5. 将特权级切换到 Ring3
6. 继续执行 Ring3 的代码
由此可知,在调用 SYSENTER 进入 Ring0 之前,一定需要通过 wrmsr 指令设置好 Ring0 代码的相关信息,在调用 SYSEXIT 之前,还要保证寄存器edx、ecx 的正确性。
如何得知 CPU 是否支持 sysenter/sysexit 指令
根据 Intel 的 CPU 手册,我们可以通过 CPUID 指令来查看 CPU 是否支持 sysenter/sysexit 指令,做法是将 EAX 寄存器赋值 1,调用 CPUID 指令,寄存器 edx 中第 11 位(这一位名称为 SEP)就表示是否支持。在调用 CPUID 指令之后,还需要查看 CPU 的 Family、Model、Stepping 属性来确认,因为据称 Pentium Pro 处理器会报告 SEP 但是却不支持 sysenter/sysexit 指令。只有 Family 大于等于 6,Model 大于等于 3,Stepping 大于等于 3 的时候,才能确认 CPU 支持 sysenter/sysexit 指令。
责编:豆豆技术应用
- Linux/Unix 新闻
- Linux/Unix 入门
- Linux/Unix 命令
- Linux/Unix 安装
- Linux 嵌入式系统
- Linux/Unix 编程
- Linux/Unix 管理
- Linux/Unix 桌面
- Linux/Unix 内核
- Linux/Unix 软件
- SCO Unix
- NetBSD
- OpenBSD
- Redhat/Fedora Linux
- 手机
- Linux/Unix find 搜索命令
- Linux/Unix vi 命令
- Linux/Unix kde 桌面环境
- Linux/Unix GNOME 桌面环境
- Linux/Unix Make 命令
- Linux/Unix crontab 命令
- Linux/Unix ext3 文件系统
- Linux/Unix 文件系统详解
- Linux/Unix ADSL 拨号设置
- Linux/Unix GRUB 配置及应用
- Linux/Unix nfs配置
- Linux/Unix 硬件信息查看及管理
- Linux/Unix 优化
- Linux/Unix 交换分区Swap管理及应用
- Linux/Unix 用户管理
- Linux/Unix Ramdisk
- Linux/Unix 密码恢复管理
- Linux/Unix 文件删除恢复
- Linux/Unix fdisk分区
- Linux/Unix lvs负载均衡管理
- Linux/Unix root用户
- Linux/Unix 集群
- Linux/Unix 日志
- 更多Linux/Unix专题……