趣谈 Linux 操作系统
刘超
前网易杭州研究院云计算技术部首席架构师
85458 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 72 讲
趣谈 Linux 操作系统
15
15
1.0x
00:00/00:00
登录|注册

09 | 系统调用:公司成立好了就要开始接项目

syscall-template.S
make-syscall.sh
syscalls.list
syscall_64.c
syscall_32.c
unistd_64.h
unistd_32.h
syscalltbl.sh
syscallhdr.sh
sys_open
syscalls.h
syscall_64.tbl
syscall_32.tbl
do_syscall_64
entry_SYSCALL_64
syscall_init
sysdep.h
do_syscall_32_irqs_on
trap_init()
ENTER_KERNEL
sysdep.h
open
系统调用表
64位系统调用过程
32位系统调用过程
glibc
用户态
系统调用

该思维导图由 AI 生成,仅供参考

上一节,系统终于进入了用户态,公司由一个“皮包公司”进入正轨,可以开始接项目了。
这一节,我们来解析 Linux 接项目的办事大厅是如何实现的,这是因为后面介绍的每一个模块,都涉及系统调用。站在系统调用的角度,层层深入下去,就能从某个系统调用的场景出发,了解内核中各个模块的实现机制。
有的时候,我们的客户觉得,直接去办事大厅还是不够方便。没问题,Linux 还提供了 glibc 这个中介。它更熟悉系统调用的细节,并且可以封装成更加友好的接口。你可以直接用。

glibc 对系统调用的封装

我们以最常用的系统调用 open,打开一个文件为线索,看看系统调用是怎么实现的。这一节我们仅仅会解析到从 glibc 如何调用到内核的 open,至于 open 怎么实现,怎么打开一个文件,留到文件系统那一节讲。
现在我们就开始在用户态进程里面调用 open 函数。
为了方便,大部分用户会选择使用中介,也就是说,调用的是 glibc 里面的 open 函数。这个函数是如何定义的呢?
int open(const char *pathname, int flags, mode_t mode)
在 glibc 的源代码中,有个文件 syscalls.list,里面列着所有 glibc 的函数对应的系统调用,就像下面这个样子:
# File name Caller Syscall name Args Strong name Weak names
open - open Ci:siv __libc_open __open open
另外,glibc 还有一个脚本 make-syscall.sh,可以根据上面的配置文件,对于每一个封装好的系统调用,生成一个文件。这个文件里面定义了一些宏,例如 #define SYSCALL_NAME open。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了Linux系统调用的实现机制以及glibc对系统调用的封装过程。文章首先介绍了系统调用表的形成和系统调用在内核中的实现函数声明,然后详细解析了32位和64位系统调用的执行过程。在32位系统中,系统调用通过中断方式进入内核,而在64位系统中则是通过syscall指令。不论是32位还是64位系统,都会通过系统调用表找到相应的函数进行调用,并将寄存器中保存的参数作为函数参数传递。最后,文章总结了系统调用返回用户态的过程。通过对系统调用的实现细节深入浅出的介绍,为想深入了解系统调用的读者提供了很高的参考价值。文章内容复杂,但通过对64位系统调用过程的详细分析,读者能够更好地理解系统调用的执行流程。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《趣谈 Linux 操作系统》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(126)

  • 最新
  • 精选
  • 孟晓冬
    这个专栏要有一定的知识储备才能学习,起码要熟悉c,数据结构,linux系统管理,否则只会一脸懵逼的进来,一脸懵逼的出去

    作者回复: 是的

    2019-04-15
    19
    252
  • 江山未
    宏是什么?给像我一样不懂C的人: 1,使用命令 #define 定义宏。该命令允许把一个名称指定成任何所需的文本,例如一个常量值或者一条语句。在定义了宏之后,无论宏名称出现在源代码的何处,预处理器都会把它用定义时指定的文本替换掉。 2,宏的名称一般使用全大写的形式。 3,宏可以定义参数,参数列表需要使用圆括号包裹,且必须紧跟名称,中间不能有空格。 4,使用#undef NAME取消宏的定义,从而可以重新定义或使用与宏重名的函数或变量。 5,出现在字符串中的宏名称不会被预编译器展开。

    作者回复: 太好了,谢谢补充

    2019-07-26
    2
    50
  • weihebuken
    我想问,想看懂这篇,我先需要看哪些书,或者贮备哪些知识先,真的很懵。。。

    作者回复: 主要理解过程,不必纠结代码

    2019-04-15
    5
    37
  • 望天
    这些东西我觉得不必要深入每一行代码,大概过一遍,知道整体流程,宏观流程就OK了(比如上面图片的概括)。反正很多细节过一段时间也会忘。

    作者回复: 对的

    2019-05-23
    2
    32
  • William
    大家可以参考glibc的源码理解,https://www.gnu.org/software/libc/started.html。 主要过程是CPU上下文切换的过程。

    作者回复: 赞

    2019-04-15
    2
    22
  • 春和景明
    开始吃力了,只能排除细节,先了解几个重要阶段了。

    作者回复: 对的,就是这个方法

    2019-04-15
    14
  • 刘強
    这个专栏,源码是linux哪个版本的?

    作者回复: https://elixir.bootlin.com/linux/v4.13.16

    2019-04-15
    5
    13
  • kdb_reboot
    参数如果超过6个存在哪里?(32/64两种情况

    作者回复: 不许超过,系统调用可以查一下,没这么多参数

    2019-04-15
    3
    10
  • Tianz
    系统调用层: 1 用户在应用空间想要用内核环境的资源,怎么办捏?linux死规定了,就只能通过系统调用层 2 用户想要用什么资源就得通过调用对应的系统调用函数并加上参数 3 什么时候才真正实现了得到你想要的资源呢?那就是进入到内核空间(在中断处理函数里就可以),并调用了对应的系统调用函数(通过你在应用空间使用的函数(这些是名字固定了的) --> 里面有函数计算出对应的(映射的)真正系统调用号(就是真正系统调用函数地址在系统调用数组里的位置) --> 通过现在得到的系统调用号从系统调用数组中拿出这个真正的系统调用函数并执行,肯定加上一起传下来的参数了 --> 返回

    作者回复: 赞

    2019-05-08
    2
    7
  • hunter
    老师你好,什么是用户态什么是内核态,

    作者回复: 前几节讲的呀,保护模式

    2019-06-12
    4
    6
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部