2012-10-16 56 views
0

我正在尋找用於進行系統調用的linux內核中的__kernel_vsyscall方法。我想觀察它的代碼以瞭解更多信息,但是我的grep搜索似乎無法找到它,並且我無法在Internet上找到它的位置。任何人都可以指出它到底在哪裏?它可以被操縱嗎?無法在Linux內核中找到方法__kernel_vsyscall

感謝您的幫助!

回答

0

有趣的是在你的互聯網搜索你沒有想到搜索stackoverflow.com:What is __kernel_vsyscall?

要回答你的更具體的問題,它看起來像本身中定義的符號(86)弓/ 86/VDSO。它是在彙編中,而不是C.

2

假設您的當前目錄位於linux內核源代碼的頭部,以下是定義__kernel_vsyscall符號的文件的位置。 (以下所有內容僅適用於x86,但在許多其他硬件架構中並不存在)。你可以看到,它基本上是在三個文件中聲明和實現的:int80.S,sysenter.S和syscall.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 

和 「系統調用」 上述實際解析爲 「int 0x80的」 如果你看了上面的文件和 「弓/ 86/VDSO/vdso32/sigreturn.S」 相結合。

對於sysenter.S,它使用intel彙編指令「sysenter」來實現系統調用轉換。

而對於int80.S,它使用「int 0x80」作爲系統調用轉換。

如果你問它是用於執行系統調用的方法,然後看看在arch/86/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)。