答案 0 :(得分:8)
假设我们正在谈论x86:
INT 0x80
中断。我可能有点生疏,已经有几年......
答案 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中断处理程序然后将参数从寄存器中取出,将它们放在(内核)堆栈上,并调用相应的系统调用处理程序。