无法在Linux内核中找到方法__kernel_vsyscall

时间:2012-10-16 00:14:13

标签: linux linux-kernel kernel

我在linux内核中寻找用于进行系统调用的__kernel_vsyscall方法。我想观察它的代码以了解更多信息,但我的grep搜索似乎无法找到它,我无法在互联网上找到它的位置。任何人都能指出我的确切位置吗?它可以被操纵吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

假设您当前的目录位于linux内核源代码的头部,以下是定义__kernel_vsyscall符号的文件的位置。 (以下所示仅适用于x86,它在许多其他硬件架构中尚不存在)。

./arch/x86/vdso/vdso32/syscall.S:
__kernel_vsyscall:

./arch/x86/vdso/vdso32/sysenter.S:
__kernel_vsyscall:

./arch/x86/vdso/vdso32/int80.S:
__kernel_vsyscall:

正如您所看到的,它基本上是在三个文件中声明和实现的:int80.S,sysenter.S和syscall.S。

采取系统调用:

__kernel_vsyscall:
.LSTART_vsyscall:
        push    %ebp
.Lpush_ebp:
        movl    %ecx, %ebp
        syscall
        movl    $__USER32_DS, %ecx
        movl    %ecx, %ss
        movl    %ebp, %ecx
        popl    %ebp

如果您阅读上述文件并且“arch / x86 / vdso / vdso32 / sigreturn.S”合并,则上面的“syscall”实际上解析为“int 0x80”。

对于sysenter.S,它使用intel汇编指令“sysenter”来实现系统调用转换。

对于int80.S,它使用“int 0x80”进行系统调用转换。

如果你问的是用于系统调用实现的方法,那么请查看arch / x86 / vdso / vdso32-setup.c:

int __init sysenter_setup(void)
{
        void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
        const void *vsyscall;
        size_t vsyscall_len;

        vdso32_pages[0] = virt_to_page(syscall_page);

#ifdef CONFIG_X86_32
        gate_vma_init();
#endif

        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;
        }

        memcpy(syscall_page, vsyscall, vsyscall_len);
        relocate_vdso(syscall_page);

        return 0;
}

正如您所看到的,现代操作系统更喜欢sysenter方法,因为它比int80方法更快。 (象征性地,“vds32_syscall_start”将回退到int80)。

答案 1 :(得分:1)

在您的互联网搜索中,您没想到要搜索stackoverflow.com:What is __kernel_vsyscall?

要回答您更具体的问题,看起来符号本身是在(对于x86)arch / x86 / vdso中定义的。它是在装配中,而不是C。