系统调用如何在Linux上实际发生?

时间:2009-08-07 16:48:21

标签: linux linux-kernel internals system-calls

受此问题的启发

How can I force GDB to disassemble?

与此相关

What is INT 21h?

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

4 个答案:

答案 0 :(得分:8)

假设我们正在谈论x86:

  1. ID of the system call已存入EAX注册
  2. 系统调用所需的任何参数都存入locations dictated by the system call。例如,某些系统调用期望它们的参数驻留在EBX寄存器中。其他人可能希望他们的论点位于筹码的顶端。
  3. 调用INT 0x80中断。
  4. Linux内核为EAX寄存器中的ID标识的系统调用提供服务,将任何结果存放在预先确定的位置。
  5. 调用代码使用任何结果。
  6. 我可能有点生疏,已经有几年......

答案 1 :(得分:7)

给出的答案是正确的,但我想补充一点,有更多机制进入内核模式。每个最近的内核都映射每个进程的地址空间中的“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页面还映射了一些可以在没有上下文切换的情况下完成的系统调用。我知道某些 gettimeofday 时间 getcpu 被映射到那里,但我想 getpid 可以适合那里好。

答案 2 :(得分:4)

这已经在回答了 How is the system call in Linux implemented?
可能与这个问题不匹配,因为术语使用的“系统调用”不同。

答案 3 :(得分:3)

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

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