在Linux内核中找不到方法__kernel_vsyscall时遇到问题 [英] Having trouble finding the method __kernel_vsyscall within the Linux kernel

查看:186
本文介绍了在Linux内核中找不到方法__kernel_vsyscall时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Linux内核中寻找__kernel_vsyscall方法,该方法用于进行系统调用.我想观察它的代码以了解更多信息,但是我的grep搜索似乎无法将其选中,并且无法在Internet上找到它的位置.谁能指出我的确切位置?可以操纵吗?

I am looking for the __kernel_vsyscall method within the linux kernel which is used to make system calls. I would like to observe its code to learn more about it, but my grep searches cannot seem to pick it out and I can't find its location on the internet. Can anyone point to me exactly where it is located? And can it be manipulated?

感谢您的帮助!

推荐答案

假设当前目录位于linux内核源代码的开头,那么这是定义__kernel_vsyscall符号的文件的位置. (下面显示的全部仅用于x86,它在许多其他硬件体系结构中尚不存在.)

Assuming your current directory is at the head of the linux kernel source, here are the locations of the files that define the __kernel_vsyscall symbol. (all shown below are only for x86, it does not exists in many other hardware architecture yet).

./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.

As you can see, it is essentially declared and implemented inside three file: int80.S, sysenter.S, and syscall.S.

正在执行syscall.S:

Taking 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".

And "syscall" above actually resolved to "int 0x80" if you read the above file and "arch/x86/vdso/vdso32/sigreturn.S" combined.

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

And for sysenter.S, it is using intel assembly instruction "sysenter" to implement system call transition.

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

And for int80.S, it is using "int 0x80" for the system call transition.

如果您询问用于syscall实现的方法,请查看arch/x86/vdso/vdso32-setup.c:

And if you asked which is the method used for syscall implementation, then look into 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;
}

如您所见,现代OS首选sysenter方法,因为它比int80方法更快. (象征性地,"vds32_syscall_start"将退回到int80).

As you can see, modern OS preferred the sysenter approach, as it is faster than the int80 approach. (symbolically the "vds32_syscall_start" will fall back to int80).

这篇关于在Linux内核中找不到方法__kernel_vsyscall时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆