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

发布于 2024-07-30 18:04:32 字数 324 浏览 8 评论 0原文

受到这个问题

How can I Force GDB to disassemble?

和相关问题的 启发对于这个

什么是 INT 21h?

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

Inspired by this question

How can I force GDB to disassemble?

and related to this one

What is INT 21h?

How does an actually system call happen under linux? what happens when the call is performed, until the actual kernel routine is invoked ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浪推晚风 2024-08-06 18:04:32

假设我们讨论的是 x86:

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

可能几年过去了,我对此有些生疏了……

Assuming we're talking about x86:

  1. The ID of the system call is deposited into the EAX register
  2. Any arguments required by the system call are deposited into the locations dictated by the system call. For example, some system calls expect their argument to reside in the EBX register. Others may expect their argument to be sitting on the top of the stack.
  3. An INT 0x80 interrupt is invoked.
  4. The Linux kernel services the system call identified by the ID in the EAX register, depositing any results in pre-determined locations.
  5. The calling code makes use of any results.

I may be a bit rusty at this, it's been a few years...

╰ゝ天使的微笑 2024-08-06 18:04:32

给出的答案是正确的,但我想补充一点,还有更多进入内核模式的机制。 每个最近的内核都将“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 可以适合那里,就像出色地。

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:

 
0xffffe000: int $0x80
0xffffe002: ret

But on my 64-bitsystem I have access to the way more efficient method using the syscall/sysenter instructions


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. I know certain gettimeofday, time and getcpu are mapped there, but I imagine getpid could fit in there just as well.

初与友歌 2024-08-06 18:04:32

这已经在
上得到了回答
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.

寒江雪… 2024-08-06 18:04:32

基本上,它非常简单:内存中的某个位置有一个表,其中存储每个系统调用号和相应处理程序的地址(请参阅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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文