【问题标题】:How does a syscall actually happen on linux?系统调用实际上是如何在 linux 上发生的?
【发布时间】:2010-11-17 18:21:15
【问题描述】:

受这个问题的启发

How can I force GDB to disassemble?

和这个相关的

What is INT 21h?

在 linux 下实际的系统调用是如何发生的?执行调用时会发生什么,直到调用实际的内核例程?

【问题讨论】:

标签: linux linux-kernel internals system-calls


【解决方案1】:

给出的答案是正确的,但我想补充一点,还有更多机制可以进入内核模式。每个最近的内核都在每个进程的地址空间中映射“vsyscall”页面。它只包含最有效的系统调用陷阱方法。

例如,在常规的 32 位系统上,它可能包含:

 
0xffffe000: int $0x80
0xffffe002: ret

但在我的 64 位系统上,我可以使用 syscall/sysenter 指令获得更有效的方法


0xffffe000: push   %ecx
0xffffe001: push   %edx
0xffffe002: push   %ebp
0xffffe003:     mov    %esp,%ebp
0xffffe005:     sysenter 
0xffffe007: nop    
0xffffe008: nop    
0xffffe009: nop    
0xffffe00a: nop    
0xffffe00b: nop    
0xffffe00c: nop    
0xffffe00d: nop    
0xffffe00e:     jmp    0xffffe003
0xffffe010: pop    %ebp
0xffffe011: pop    %edx
0xffffe012: pop    %ecx
0xffffe013: ret    

此 vsyscall 页面还映射了一些无需上下文切换即可完成的系统调用。我知道某些 gettimeofdaytimegetcpu 映射在那里,但我想 getpid 可以像好吧。

【讨论】:

    【解决方案2】:

    这个问题已经在
    How is the system call in Linux implemented?
    得到解答 由于“系统调用”术语的用法不同,可能与此问题不匹配。

    【讨论】:

      【解决方案3】:

      基本上,它非常简单:内存中的某处有一个表,其中存储了每个系统调用号和相应处理程序的地址(有关 x86 版本,请参阅http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S

      INT 0x80 中断处理程序然后只是从寄存器中取出参数,将它们放入(内核)堆栈,并调用适当的系统调用处理程序。

      【讨论】:

        【解决方案4】:

        假设我们谈论的是 x86:

        1. ID of the system call 存入 EAX 寄存器
        2. 系统调用所需的任何参数都存放在locations dictated by the system call 中。例如,一些系统调用期望它们的参数驻留在 EBX 寄存器中。其他人可能希望他们的论点位于堆栈顶部。
        3. 调用了INT 0x80 中断。
        4. Linux 内核为由 EAX 寄存器中的 ID 标识的系统调用提供服务,并将任何结果存放在预先确定的位置。
        5. 调用代码使用任何结果。

        我可能对此有点生疏,已经有几年了......

        【讨论】:

        • 如果我没记错的话,由于内核有自己的堆栈,没有用户空间程序可以在上面放东西,所以所有参数都必须通过寄存器传递。
        • 真的吗?我依稀记得我的教授提到 Linux 有一些用于将用户空间地址映射到内核空间的宏......我可能错了。
        • INT 0x80 仅在 SYSCALL/SYSENTER 指令不可用时使用,IIRC。
        猜你喜欢
        • 2019-04-26
        • 2010-10-04
        • 2014-04-16
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        • 2014-03-30
        • 1970-01-01
        相关资源
        最近更新 更多