当前课程知识点:Linux 内核分析与应用 >  第6章 系统调用 >  6.2 系统调用机制 >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好 这一讲我们来讲一下系统调用的实现机制

我们说系统调用实际上是内核的出口

系统调用顾名思义就是操作系统提供给用户程序调用的一组特殊接口

从逻辑上来说 系统调用可以被看成是一个内核与用户空间程序交互的接口

它好比一个中间人 把用户空间的请求传达给内核

在内核把请求处理完以后呢 再将处理的结果返回给用户

那么这张图呢 我们就可以看出open系统调用跟内核交互的一个过程

那么我们如何知道一个进程到底调用了哪些系统调用

在这里我们给出了一张图 这张图是Linux系统中各个子系统相关的工具

那么在这个左上角有一个strace工具

那么可以通过这个命令 我们就可以查看一个应用它所调用的所有的系统调用

比如说我们要查看ls命令到底调用了哪些系统调用呢

我们就可以用strace后面跟ls 那么就可以看到ls所调用的系统调用

前面我们介绍了中断和异常

那么中断 异常和系统调用 它们之间到底有什么样的关系呢

实际上这三者本质上是属于一类的 那么处理方式上它们也就很类似了

那么它们之间差异性表现在哪些方面呢在学了中断以后 对我们学系统调用有哪些帮助呢

那么从三个方面我们来看一下它们的差异性

首先看一下源头 实际上源头是不同的中断是外设发出的请求

而异常是什么呢 异常是应用程序意想不到的行为产生的一种错误

而系统调用是什么呢 系统调用是应用程序请求OS提供的服务

那么它们的相应方式也是不同的 中断是一种异步的 而异常呢是同步的

系统调用既可以是同步也可以是异步

那么它的处理机制也有所不同中断服务程序呢 它整个是在内核态下运行的

对用户来说完全是透明的

而异常出现的时候它实际上马上就要

执行异常处理程序 这时候或者杀死进程或者要重新执行引起异常的指令

而系统调用是用户发出请求之后就在那等待OS来给它提供服务

那么我们通过一个例子来看一下 从用户态函数到系统调用的这样一个路径

比如说我们在程序中调用了一个fwrite这个函数

这个函数它实际上是libc库中调用系统调用write

然后从用户态陷入到内核态 查找系统调用表

那么对应的系统服务例程是什么呢 就叫sys_write

系统调用的一般处理过程是什么样子

当用户态的进程调用一个系统调用的时候呢

我们说它在libc的封装例程中实际上会调用int的0x80

或者syscall的汇编指令就切换到了内核态

而且就开始执行一个内核的syscall系统调用处理程序

那么这里关键的就是系统调用处理程序

那么它做什么工作呢 首先它在内核栈

保存大多数寄存器的内容也就是压栈操作

然后调用系统调用服务例程处理系统调用

最后通过中断的返回指令从系统调用返回

下面我们介绍下系统调用的基本概念 第一个叫做系统调用号

它是用来唯一的标识每个系统调用的

它作为系统调用表的下标 当用户空间的进程执行系统调用的时候呢

该系统调用号就被用来指明到底执行哪个系统调用服务例程

第二个概念叫系统调用表

它是用来把系统调用号和相应的服务例程关联起来的一张表

该表存放在sys_call_table数组中

在这里我们要特别说明一下内核的版本不同呢

这些系统调用号 系统调用所在的头文件呢是有所差别的

这里头我们给出了一张表 给出了部分系统调用

它的系统调用号 在内核的服务例程以及所在的头文件和参数

从这张表里头 我们可以看出系统调用号是存放在eax寄存器中

每个系统调用在内核中对应的服务例程是以sys打头的

它们的实现所在的源文件也各不相同

系统调用表的参数存放在寄存器中

一般参数不超过6个包括系统调用号

那么我们这张表可以给大家看出如何从用户态跟踪一个系统调用到内核

第一步我们在用户程序中调用fork系统调用

那么在libc库中 就把fork对应的系统调用号放入寄存器eax中

第三步呢通过int 0x80就陷入到内核里头了

第四步 在中断描述符表IDT中查找到

系统调用的入口0x80

然后就进入Linux内核的int_32(64).s文件里头

从系统调用表sys_table中就找到了fork的入口地址

然后呢执行fork.c中的do_fork代码

这个时候就真正进入到内核来执行这个系统调用了

那么当这个系统调用执行完以后呢 就通过ret指令返回用户态了

前面我们对系统调用机制做了简要的介绍

实际上如果要去看源代码的话 那么它的整个过程是比较复杂的

那么这里头我们对系统调用的机制如何做一个优化作简要的概述

在2.6以前的版本中 系统调用的实现是用

int0x80或ret指令

因为系统调用的实现是从用户态切换到内核态

执行完系统调用程序后又要从内核态切换回用户态

这样来回切换的代价实际上是很大的

因此为了加快系统调用的执行速度

随后先后引入了两种机制

vsycalls和vDSO

这两种机制都是从机制上对系统调用的速度进行的优化

但是使用软中断来进行系统调用呢

还是需要进行特权级的切换 这一根本问题并没有得到解决

为了解决这一问题 Intel x86CPU从Pentium ll之后

开始支持快速系统调用

这里有两条指令叫sysenter/sysexit

这两条指令是Intel在32位下提出的

而AMD提出了syscall/sysret 那么这两条指令是在64位下提出的

所以现在呢64位下就统一使用这两条指令了

我们前面对系统调用的机制做了介绍以后呢 那么系统调用

到底如何应用起来呢 我们给大家一个例子

叫系统调用的实例就是日志收集系统

我们说系统调用是用户程序与系统打交道的入口

系统调用的安全直接关系到系统的安全

如果一个用户恶意不断地调用fork 就会导致系统负载增加

所以如果能收集到谁调用了一些有危险的系统调用

以及系统调用的时间和其他信息的话

将有助于管理员进行事后的追踪 从而提高系统的安全性

本实例的实现过程将在下一讲给予具体的演示

并且说明如何添加一个系统调用

通过前面的介绍 我们对本章做一个简要的概述

我们说系统调用实际上是应用与内核之间的一个接口

那么Linux内核中系统调用的具体实现是与体系结构相关的

因此我们说在x86下和在arm下你去看系统调用源代码的话 它实际上是很不一样的

所以呢对不同的体系架构呢

大家要有针对性的去看相关的源码 在这里我们只给出了一般性的原理

么我们对在下一讲的例子里头 我们会给大家给出去添加一个系统调用

那么在实际的系统中 是不是要添加一个系统调用实际上是需要认真评估的

关于系统调用我们一定要动手实践

在我们Linux内核之旅网站的电子杂志栏目第四期“系统调用”讨论了系统调用的机制

其中涉及了一些与系统调用相关的性能上下文切换的深层次的问题

同时也穿插着讲述了一些内核的调试方法

那么希望大家动手实践 在较早的2.6.x

和最新的5.x内核版本下调试系统调用日志收集系统并给出分析结果

最后大家带着思考离开

前面我们说了系统调用的实现机制进行了多次优化

为什么要进行这样的优化 未来还有优化的空间吗

谢谢大家

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-4.1 Linux内存管理机制

--Video

-4.2 进程用户空间管理机制

--Video

-4.3 物理内存分配与回收机制(上)

--Video

-4.4 物理内存分配与回收机制(下)

--Video

-4.5 动手实践-Linux内存映射基础(上)

--Video

-4.6 动手实践-Linux内存映射实现(中)

--Video

-4.7 动手实践-Linux内存映射测试(下)

--Video

-4.8 初学者对内存管理的常见疑惑

--初学者对内存管理的常见疑惑(一)

--初学者对内存管理的常见疑惑(二)

--初学者对内存管理的常见疑惑(三)

-第4章 内存管理--章节测验

第5章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-9.1 设备驱动概述

--Video

-9.2 I/O空间管理

--Video

-9.3 设备驱动模型

--Video

-9.4 字符设备驱动程序简介

--Video

-9.5 块设备驱动程序简介

--Video

-9.6 动手实践-编写字符设备驱动程序

--Video

-9.7工程实践-编写块设备驱动的基础(上)

--Video

-9.8 工程实践-块设备驱动程序分析(中)

--Video

-9.9 工程实践-块设备驱动程序实现(下)

--Video

-第9章 设备驱动--章节测验

致谢与说明

-致谢与说明

--Video

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。