【学习笔记06】深入了解系统调用
目的
进程访问核心资源通过系统调用。站在系统调用
的角度,层层深入下去,就能从某个系统调用的场景出发,了解内核中各个模块的实现机制。
但是在实际开发中不会直接使用系统调用,因为Linux 还提供了glibc
这个中介。它更熟悉系统调用的细节,并且可以封装成更加友好的接口。
glibc 的官网:http://www.gnu.org/software/libc/
下载glibc源码:git clone git://sourceware.org/git/glibc.git
linux kernel官网: https://www.kernel.org/
linux源码获取: https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.14.175.tar.xz
本文目标:从glibc提供的open函数出发,剖析如何从glibc的open调用到内核的open!!!
glibc封装、系统实现
1、 glibc封装
我们用户进程调用的glibc库封装的open函数,在glibc的源代码中,有以下相关文件
./sysdeps/unix/syscalls.list # 列出所有glibc的函数对应的系统调用
./sysdeps/unix/make-syscalls.sh # 根据上面的配置文件,对于每一个封装好的系统调用,生成一个文件
./sysdeps/unix/syscall-template.S # 定义了这个系统调用的调用方式
./sysdeps/hppa/sysdep.h # 通过 `vim -t PSEUDO` 找到 PSEUDO 这个宏的定义。
- 1
- 2
- 3
- 4
经过分析代码open函数的代码逻辑,得出结论: 对于任何的系统调用,会调用DO_CALL
。这也是一个宏,这个宏 32 位和 64 位的定义是不一样的。
2、 系统调用过程
# 32位系统平台
继续分析glibc源码,发现宏DO_CALL
定义处unix/sysv/linux/i386/sysdep.h
。这里做了几件事情
- 请求参数放在寄存器里面
- 系统调用名转换成系统调用号,放在寄存器 eax 里面
- 执行 ENTER_KERNE,产生一个软中断
然后中断处理entry_INT80_32
就被调用了
- 这里会将用户态的上下文保存在pt_regs结构中
- 然后调用
do_syscall_32_irqs_on
,它会将系统调用号取出,查找系统调用表,找到内核的系统调用
执行,并取出寄存器中保存的参数。 - 当系统调用结束的时候,这时中断返回,iret 指令将原来用户态保存的现场恢复回来。进程恢复用户态继续执行。
# 64位系统平台
DO_CALL定义在源码位置unix/sysv/linux/x86_64/sysdep.h
,还是将系统调用名称转换为系统调用号,放到寄存器 rax。和32位不同的是,
- 这里是真正进行调用,不是用中断了,而是改用 syscall 指令了。
- 而且传递参数的寄存器也变了
syscall指令通过一个叫做MSR的特殊模块寄存器
,拿出函数地址来调用,也就是entry_SYSCALL_64
。其中
- 保存了很多寄存器到 pt_regs 结构里面,例如用户态的代码段、数据段、保存参数的寄存器
- 调用链entry_SYSCALL64_slow_pat->do_syscall_64,其中拿到系统调用号,在系统调用表中找到对应的系统调用,取参数,执行(老方法)
- 系统调用结束,返回用户态的指令变成了 sysretq。将进程恢复为用户态
总结
结合之前对用户态、内核态模式转换的学习用户态 - 系统调用 - 保存寄存器 - 内核态执行系统调用 - 恢复寄存器 - 返回用户态
。64位系统中一个完整的系统调用,专栏中的总结图如下
补充知识
1、 系统调用表
# kernel源码位置:
数据结构定义在arch/x86/entry/syscall_64.c
,系统调用列表输出在arch/x86/entry/syscalls/syscall_64.tbl
#系统调用号 abi类型 函数名 系统调用名
2 common open sys_open
- 1
- 2
# 系统调用函数声明
声明在include/linux/syscalls.h
,找到有sys_open 的声明
# 系统调用函数实现
内核系统调用实现和声明一致,其中fs/open.c
- 1
# 编译规则
接下来,在编译的过程中,需要根据 syscall_32.tbl 和 syscall_64.tbl 生成自己的 unistd_32.h 和 unistd_64.h。在文件arch/x86/entry/syscalls/Makefile
中
- 1
参考资料
文章来源: blog.csdn.net,作者:hinzer,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/feit2417/article/details/105434281
- 点赞
- 收藏
- 关注作者
评论(0)