2018-2019-1 20189206 《Linux内核原理与分析》第五周作业
linux内核分析学习笔记 ——第四章 系统调用的三层机制
学习重点——系统调用
用户态、内核态和中断
- Intel x86 CPU有四种不同的执行级别,分别是0,1,2,3其中数字越小,特权越高。
- Linux操作系统只采用了其中的0和3两个特权级别,分别对应内核态和用户态。
- 内核态:对应高执行级别,代码可以执行特权指令,访问任意物理内存,CPU执行级别对应的内核态。
内核态的CS:EIP指向范围是任意地址 - 用户态:对应底执行级别,代码能够掌控的范围会受到限制。
用户态时,以32位x86机器为例,4G的进程地址空间只能访问0x000000~0xbfffffff的地址空间。
- 内核态:对应高执行级别,代码可以执行特权指令,访问任意物理内存,CPU执行级别对应的内核态。
- 每个进程都有一个4G大小的虚拟地址空间,在这个4G大小的虚拟地址空间中,前0~3G为用户空间,每个进程的用户空间之间是相互独立的,互不相干。
- Linux操作系统只采用了其中的0和3两个特权级别,分别对应内核态和用户态。
以下图示表示x86 32位机器的进程内存

- 中断
- 进入内核态一般是由终端触发的,以下时进入内核态的两种情况
- 硬件中断,在用户进程执行时,硬件中断信号到来进入内核态,就会执行这个中断对应的中断服务历程。
- 用户态程序执行过程中,调用了一个系统中断,陷入内核态(Trap)。系统调用就是一种特殊的中断
- 从用户态到内核态的寄存器上下文的切换
- 从用户态切换到内核态,将用户态寄存器的上下文保存起来,同时将内核态寄存器的值放入当前CPU中。
- int指令触发中断机制
- 会在内核栈内保存一些寄存器的值
- 包括 用户态栈顶地址%esp 当前状态字 当前CS:EIP的值
- 同时会将内核态的栈顶地址、内核态状态字放入CPU对应的寄存器中。CS:EIP指向中断处理程序的入口,对于系统来讲就是system_call
- 会在内核栈内保存一些寄存器的值
中断处理的过程
Linux系统调用通过中断向量0x80实现
int 0x80,中断保存了用户态CS:EIP的值,及当前堆栈段寄存器的栈顶(注意在这里的栈顶是用户栈的栈顶,入栈到内核栈),EFLAGS寄存器的当前值保存到内核堆栈。利用int指令将系统调用的中断服务程序的入口加载在CS:EIP中。- 完成中断服务程序,发生进程调度
- 如果没有发生进程调度,直接恢复现场,
iret回到原来的状态。 - 如果发生了进程调度,当前这些状态暂时保存在内核堆栈中,下一次发生进程调度再切换回当前进程。
- 如果没有发生进程调度,直接恢复现场,
- 完成中断服务程序,发生进程调度
- 进入内核态一般是由终端触发的,以下时进入内核态的两种情况

系统调用
概述
系统调用的意义是操作系统为用户态进程与硬件设备之间进行交互提供了一组接口。
操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境来使应用程序具有更好的兼容性,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序
- 把用户从底层的硬件编程中解放出来
- 极大的提高了系统的安全性
- 使用户程序具有可移植性
系统调用的3层机制
系统调用的库函数就是我们使用的操作系统提供的API,系统调用是通过软中断向内核发出中断请求,int指令触发中断请求。
libc函数库内部定义的一些API内部就使用了系统调用的封装历程。
每个系统调用对应一个系统调用的封装例程,函数库再使用这些封装例程定义给出程序员可以调用的API一个API可能只对应一个系统调用,也可能由多个系统调用实现。

如上图所示,在用户态中
- 用户态中的
xyz()函数属于API函数 - 该API中
SYSTEMCALL就是一个系统调用的封装例程由操作系统给,出会触发int $0x80中断
在内核态中
- 触发中断后进入内核态,
system_call对应内核代码的起点,即中断向量0x80对应的终端服务程序的入口 - 内核代码中的
sys_xyz()系统调用处理函数- 处理结束后,如果发生进程调度会
ret_from_sys_call - 如果没有发生进程调度,会执行
iret返回用户态继续执行
- 处理结束后,如果发生进程调度会
触发系统调用及参数传递方式
- 触发系统调用的方式
- 当用户执行系统调用时,CPU切换到内核态执行
system_call这是中断的入口函数也是内核代码的起点。 - linux中使用0x80触发系统调用所对应的中断异常。
- 内核通过给每个系统调用一个编号来区分,即系统调用号,实现将API函数
xyz()和系统调用内核函数sys_xyz() - 用户进程必须指明需要哪一个系统调用,需要使用EAX寄存器
- 当用户执行系统调用时,CPU切换到内核态执行
- 参数传递的方式
- 系统调用从用户态切换到内核态时使用的不同的堆栈,所以参数的传递无法通过参数压栈的方式进行传递。
- 参数按照顺序赋值给EBX ECX EDX ESI EDI EBP 参数的个数不能超过6个寄存器。如果参数过多,就把寄存器作为指针指向内存,以传递更多的参数
实验:使用两种方法实现触发系统调用
使用库函数API触发系统调用

利用上面的代码实现的是查看当前进程的pid和其父进程的pid,首先是利用库函数提供的API实现查看。下面是运行结果。

使用内嵌汇编的方式实现系统调用
将上面的调用API转换成内嵌汇编代码的方式。通过查找可以看到对应的操作系统给出的系统调用的封装对应的系统调用号



下面对汇编代码解释其含义
movl $0,%%ebx\n\t表示传入参数,这里不需要传递参数,就将EBX寄存器清零
movl $0x14,%%eax\n\tEAX用于传递系统调用号,表示这里调用的是20号系统调用。
int $0x80\n\t是触发系统调用陷入内核执行20号系统调用的内核处理函数
movl %eax,%0\n\t系统调用会有一个返回值,通过EAX寄存器返回。
这样就完成了系统调用。

通用的触发系统调用函数
当libc没有提供某个系统调用的封装,可以利用libc提供的syscall函数直接调用


2018-2019-1 20189206 《Linux内核原理与分析》第五周作业的更多相关文章
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第二周作业
读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- LeetCode38.报数
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 被读作 "one 1" ...
- laravel orm
###多对多关系 多对多关系和之前的关系完全不一样,因为多对多关系可能出现很多冗余数据,用之前自带的表存不下了. 我们定义两个模型:Article 和 Tag,分别表示文章和标签,他们是多对多的关系. ...
- 配置hdfs之后发现9000端口未被监听[玄学]
1. 按照apache的官网的文档配置hdfs 2. 在 core-site.xml 中配置了 fs.defaultFS 的值为 hdfs://0.0.0.0:9000 3. 执行 start-dfs ...
- efcore从数据库快速生成实体及context
有些项目开发时先建立数据库,再用codefirst来书写entity和EntityConfiguration,比较耗费功夫. 1.在vs2017中新建个asp.net core的web项目,或者其他项 ...
- ef entity转json引起的Self referencing loop
问题简介:前段时间做项目时,将取到的entity往Redis cache里存放时报多重引用的错误. Self referencing loop detected for property 'Check ...
- Unity shader学习之半兰伯特光照模型
半兰伯特光照模型,为Valve公司在开发游戏<半条命>时提出的一种技术,用于解决漫反射光无法到达区域无任凭明暗变化,丢失模型细节表现的问题. 其公式如下: Cdiffuse = Cligh ...
- RocketMQ的使用
1 在resources目录下创建config目录,新建文件rocketmq.properties文件 # 指定namesrv地址 suning.rocketmq.namesrvAddr=localh ...
- Cocos Creator学习目录
目录 安装和启动 文件结构 编辑器基础 基本概念 (场景树 节点 坐标 组件 ) Cocos Creator 脚本简介 Cocos Creator调试 节点 cc.Node 组件开发cc.Compon ...
- 大数据权限管理工具 Apache Ranger 初识
资料参考: Apache Ranger – Introduction http://ranger.apache.org/ 阿里云 Ranger简介 Apache Ranger初识 - 阿里云 大数据权 ...
- react系列笔记1 用npx npm命令创建react app
react系列笔记1 用npx npm命令创建react app create-react-app my-app是开始构建新的 React 单页应用程序的最佳方式.它已经为你设置好了开发环境,以便您可 ...