Linux 上的系统调用实际上是如何发生的?
受到这个问题
How can I Force GDB to disassemble?
和相关问题的 启发对于这个
在 Linux 下实际系统调用是如何发生的? 执行调用时会发生什么,直到调用实际的内核例程?
Inspired by this question
How can I force GDB to disassemble?
and related to this one
How does an actually system call happen under linux? what happens when the call is performed, until the actual kernel routine is invoked ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
假设我们讨论的是 x86:
INT 0x80
中断。可能几年过去了,我对此有些生疏了……
Assuming we're talking about x86:
INT 0x80
interrupt is invoked.I may be a bit rusty at this, it's been a few years...
给出的答案是正确的,但我想补充一点,还有更多进入内核模式的机制。 每个最近的内核都将“vsyscall”页面映射到每个进程的地址空间中。 它只包含最有效的系统调用陷阱方法。
例如,在常规 32 位系统上,它可能包含:
但在我的 64 位系统上,我可以使用 syscall/sysenter 指令访问更有效的方法。
此 vsyscall 页面还映射了一些无需上下文切换即可完成的系统调用。 我知道某些 gettimeofday、time 和 getcpu 映射到那里,但我想 getpid 可以适合那里,就像出色地。
The given answers are correct but I would like to add that there are more mechanisms to enter kernel mode. Every recent kernel maps the "vsyscall" page in every process' address space. It contains little more than the most efficient syscall trap method.
For example on a regular 32 bit system it could contain:
But on my 64-bitsystem I have access to the way more efficient method using the syscall/sysenter instructions
This vsyscall page also maps some systemcalls that can be done without a context switch. I know certain gettimeofday, time and getcpu are mapped there, but I imagine getpid could fit in there just as well.
这已经在
上得到了回答
Linux中的系统调用是如何实现的?
由于“系统调用”术语用法不同,可能与此问题不匹配。
This is already answered at
How is the system call in Linux implemented?
Probably did not match with this question because of the differing "syscall" term usage.
基本上,它非常简单:内存中的某个位置有一个表,其中存储每个系统调用号和相应处理程序的地址(请参阅http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S 对于 x86 版本
)然后,INT 0x80 中断处理程序只是从寄存器中取出参数,将它们放入(内核)堆栈,并调用适当的系统调用处理程序。
Basically, its very simple: Somewhere in memory lies a table where each syscall number and the address of the corresponding handler is stored (see http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S for the x86 version)
The INT 0x80 interrupt handler then just takes the arguments out of the registers, puts them on the (kernel) stack, and calls the appropriate syscall handler.