[英]How does a syscall actually happen on linux?
Inspired by this question 灵感来自这个问题
How can I force GDB to disassemble? 如何强制GDB反汇编?
and related to this one 并与此相关
How does an actually system call happen under linux? 如何在Linux下实际发生系统调用? what happens when the call is performed, until the actual kernel routine is invoked ? 执行调用时会发生什么,直到调用实际的内核例程?
Assuming we're talking about x86: 假设我们在谈论x86:
INT 0x80
interrupt is invoked. 调用INT 0x80
中断。 I may be a bit rusty at this, it's been a few years... 我可能有点生疏,已经有几年......
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. 每个最近的内核都映射每个进程的地址空间中的“vsyscall”页面。 It contains little more than the most efficient syscall trap method. 它只包含最有效的系统调用陷阱方法。
For example on a regular 32 bit system it could contain: 例如,在常规32位系统上,它可以包含:
0xffffe000: int $0x80
0xffffe002: ret
But on my 64-bitsystem I have access to the way more efficient method using the syscall/sysenter instructions 但是在我的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
This vsyscall page also maps some systemcalls that can be done without a context switch. 此vsyscall页面还映射了一些可以在没有上下文切换的情况下完成的系统调用。 I know certain gettimeofday , time and getcpu are mapped there, but I imagine getpid could fit in there just as well. 我知道某些gettimeofday , time和getcpu被映射到那里,但我想getpid也适合那里。
This is already answered at 这已经回答了
How is the system call in Linux implemented? 如何在Linux中实现系统调用?
Probably did not match with this question because of the differing "syscall" term usage. 可能与这个问题不匹配,因为不同的“系统调用”术语用法。
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) 基本上,它非常简单:内存中的某个位置是一个表,其中存储了每个系统调用号和相应处理程序的地址(请参阅http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32 .S for x86版本)
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. 然后INT 0x80中断处理程序将参数从寄存器中取出,将它们放在(内核)堆栈上,并调用相应的系统调用处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.