图解Linux系统调用

以下内容已屏蔽图片优化访问速度
在Linux下面,我们经常调用系统API来完成内核的操作,例如调用open打开一个文件。



这个过程看似简单,其实已经包括了一次从用户态到内核态,然后由内核态返回用户态的过程。


[IMG]
当然用户不会直接调用系统调用,而是调用glibc中的函数open打开文件。


在glibc中维护了一张表格,在syscalls.list里面,是c函数到系统调用的映射。


编译的过程会将这个映射表格变成代码。


真正调用系统调用的时候,会将参数放入CPU寄存器中,然后通过trap陷入内核,这里调用的是syscall。


ENTRY (syscall)
movq %rdi, %rax /* Syscall number -> rax.  */
movq %rsi, %rdi /* shift arg1 - arg5.  */
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp),%r9 /* arg6 is on the stack.  */
syscall /* Do the system call.  */
cmpq $-4095, %rax /* Check %rax for error.  */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */
ret /* Return to caller.  */


在内核中,也是有一个sys_call_table数组的。


数组中的内容来自与syscall_64.tbl,这是一个文本,编译的时候会将里面的系统调用名称放入代码中。


在内核中首先从CPU寄存器中拿到系统调用号,然后在这个表中查找open系统调用对应的内核函数,经过查抄对应的是sys_open,于是开始调用sys_open真正的打开一个文件。
金错刀X诺贝尔奖得主X巴勒斯坦首富X犹太教领袖X创业教父9天8夜考察以色列“二十”大爆品,探索犹太商道的逻辑 网易轻舟微服务框架在不同场景下的设计与实现 与努力同样重要的是,学会做好这6点! 100万东北人“攻占”海南:这大茬子味儿太魔性了! 又爆裁员、欠薪200人,餐饮SaaS还有未来吗?
好看吗?
总执行时间0.012531280517578125,文章查询时间0.0019223690032958984,分类查询时间0.009664297103881836,其他脚本5.91278076171875e-05,模板渲染0.0008854866027832031