所有的教科书和互联网资源都告诉我,int 80h是一个用于调用系统调用的陈旧样式,并且在x86平台上已被SYSENTER取代。
但我发现我的系统仍然使用int 80h。我知道教科书的东西,比如VDSO,实现系统调用服务的libc包装器,但是不明白为什么默认情况下仍然使用int 80h。
有人可以告诉我原因吗? glibc或内核太旧了?
现在默认情况下“int 80h”在什么条件下仍然使用?
如何在不安装新glibc的情况下强制执行sysenter?
以下是我的环境:
我在macbook air 2011(Core Duo CPU)上使用VMWare安装了虚拟机。 VM中的32位Ubuntu 8.04 /内核2.6.24(使用原始.config编译)/ libc 2.7。
答案 0 :(得分:2)
最有可能出于兼容性原因 - 32位Ubuntu被编译为与i386处理器兼容(好吧,现在可能不是那么老),它不支持sysenter(它只出现在Pentium 2 AFAIK上)。显然,对于int 80h使用sysenter只对某些处理器有用:
http://articles.manugarg.com/systemcallinlinux2_6.html
因此,如果在一般情况下没有明显的速度增益和更广泛的兼容性,那么使用int 80h over sysenter仍然有意义,即使在今天。如果您使用64位版本的Ubuntu,则会在整个地方使用sysenter / sysexit。
编辑:实际上要使用的系统调用机制由内核在启动时决定,而不是由glibc决定。 This page(第4.6节)解释了这是如何运作的。在您的情况下,只是发生内核认为VMware模拟的硬件使用int 80h而不是sysenter更有效。您必须调试内核才能弄清楚它是如何做出决定的。
答案 1 :(得分:2)
客户操作系统本身总是决定什么指令(int80或sysenter),正如您从Linux内核源代码中看到的那样 - 这完全取决于VMware提供给它的硬件。
查看文件arch / x86 / vdso / vdso32-setup.c(linux内核源代码):
if (vdso32_syscall()) {
vsyscall = &vdso32_syscall_start;
vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
} else if (vdso32_sysenter()){
vsyscall = &vdso32_sysenter_start;
vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
} else {
vsyscall = &vdso32_int80_start;
vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
}
从上面可以看出,只有在sysenter功能检测失败时才决定使用int80。此功能通过VMWare的仿真引擎呈现给客户。也许如果您使用最新版本的VMware以及一些现代硬件,VMware应该向访客提供更现代的操作系统。