2017-2018-1 20179205《Linux内核原理与设计》第五周作业
《Linux内核原理与设计》第五周作业
视频学习及操作分析
一、用户态、内核态和中断
内核态在CPU执行中对应高执行级别,执行级别为0级,具有特权指令,可以访问任意物理地址;用户态执行级别为3级,在低级别执行状态下,代码掌控范围会受到限制。
内核态和用户态的区分:两者有一显著的区分方法,就是cs:eip寄存器。内核态时,cs:eip可以是任意地址,在32位X86机器上具有4G进程地址空间,因此既可以访问0X00000000-0Xbfffffff的地址空间,也可以访问0Xc0000000以上的地址空间;而用户态,只能访问0X00000000-0Xbfffffff的地址空间。
中断处理是从用户态进入内核态主要的方式,从用户态切到内核态时,必须保存用户态寄存的上下文,中断/int指令会在堆栈上保存寄存器的值。进入中断程序,首先要保存现场,保存需要用到的寄存器数据,通过
#define SAVE_ALL
把其他寄存器的值push到内核堆栈中;退出程序时,回复现场,恢复保存寄存器的数据,通过RESTORE_ALL
把值popl出来。
interrupt(ex:int 0x80)-save
cs:eip/ss:esp/eflags(current)to kernel stack,
then load cs:eip(entry of a specific ISR)and
ss:esp(point to kernel stack) //中断保存系统调用,
保存了cs:eip的值,堆栈段寄存器,当前栈顶,标志寄存器到内核堆栈,
然后加载了中断服务程序入口到cs:eip, 并把堆栈段和esp指向内核堆栈
二、系统调用概述
API和系统调用:
API是应用程序编程接口,只是一个函数定义,Libc库定义的一些API引用了封装历程,可以发布系统调用,一般每个系统调用对应一个封装历程,库再用这些封装例程定义给用户的API,这样调用系统不需要再进行汇编,只需要调用一个函数即可;而系统调用是通过软中断向内核发出一个明确的请求。API和系统调用并往往不是一一对应关系。
系统调用的三层皮:xyz、system_call和sys_xyz,系统调用将xyz和sys_xyz关联起来了;在使用系统调用时,需要输入输出参数,通过eax寄存器,传递一个名为系统调用号的参数,来指明需要调用的那个系统。寄存器在传递参数时需要注意的是:
(1)每个参数长度不能超过寄存器的长度,即32位;
(2)除eax系统调用外,参数的个数不能超过六个(ebc,ecx,edx,esi,edi,ebp)超过6个参数需将某寄存器作为指针指向内存,通过内存来传递数据。
使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
这里我们在系统调用列表中选择fork函数进行系统调用
首先我们用C语言编写fork()函数如下:
接下来我们编写C语言嵌入式汇编语言:
分析嵌入式代码:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t fpid; //传递参数
asm volatile( //进入嵌入式汇编,volatile表示禁止服务器优化
"mov $0, %%ebx\n\t" //将ebx寄存器清零
"mov $0x2, %%eax\n\t" //通过系统调用列表查到fork函数参数为2,因此把2号系统调用赋给eax寄存器
"int $0x80\n\t" //执行命令,系统中断
"mov %%eax, %0\n\t" //将eax的值赋给第0个变量
: "=m"(fpid) //0号变量对应,即把eax的值放到内存中
);
if (fpid < 0){
printf("error!\n");
}
if (fpid == 0){ //进程标记为0
printf("I am the child process!\n"); //输出“这是子进程!”
} else{ //否则
printf("I am the father process!\n"); //输出“这是父进程!”
}
return 0;
}
在fork.c以及fork_asm.c文件中编好代码,ls可以查看到这两个可执行文件,那么我们来查看两个程序的执行结果,发现两者运行结果一致。
教材七、八章学习
1、不同的设备对应的中断不同,每个设备都通过一个唯一的数字标志,这些中断值通常被称为中断请求IRQ线,这样操作系统才能给不同的中断提供对应的中断处理程序。它是一种由设备使用的硬件资源异步向处理器发信号,由硬件来打断操作系统。在相应一个特定中断时,内核会执行一个函数,该函数叫做中断处理程序。由于中断处理程序既想运行的快,又想完成的工作量多,因此把中断切分为上半部(立即执行)和下半部(稍后执行)。
2、中断处理程序上、下半步处理逻辑分配原则:
上半部:任务对时间非常敏感;任务和硬件相关;任务保证不被其他中断打断,不并发,不阻塞。其余情况分配到下半步。
3、注册中断处理程序:通过request_irq()函数可注册一个中断处理程序,并且激活给定的中断线,irq表示分配的中断号;handler为指针,指向实际中断处理程序;flags参数可以为0,也可能是下列一个或多个标志的位掩码(IRQF_DISABLED、IRQF_SAMPLE_RANDOM、IRQF_TIMER、IRQF_SHARED)第四个参数name与中断相关的设备的ASCII文本表示。 第五个参数dev用于共享中断线,当中断需要退出时,dev提供唯一的标志信息,以便从共享中断线的中断处理程序中删除指定程序。
注:request_irq()函数可能会睡眠,所以不能在中断上下文或其他不允许阻塞的代码中调用该函数。
4、在内核中,中断的旅程开始于预定义入口点,这类似于系统调用。对于每条中断线,处理器都会跳到对应的一个唯一的位置。这样,内核就可以知道所接收中断的IRQ号了。初始入口点只是在栈中保存这个号,并存放当前寄存器的值(这些值属于被中断的任务);然后,内核调用函数do_IRQ().从这里开始,大多数中断处理代码是用C写的。书中P100页给出了从中断从硬件到内核的路由过程,总结的很明白:
5、下半部的实现机制主要有三种,软中断、tasklet和工作队列,工作队列的机制与它们完全不同,工作队列可把工作推后,交由一个内核线程去执行。在机制的选择上,有休眠需求,选工作队列;追求更高的性能,考虑软中断,它是在编译期间静态分配的,一个软中断不会抢占另外一个软中断,唯一可以抢占软中断的是中断处理程序;;否则最好用tasklet,而tasklet是通过软中断实现的,所以不能睡眠,可以动态地注册或注销(也可以静态)。
三种实现机制的流程如下:
遇到的问题
同步执行和异步执行有什么根本的差别?
同步和异步关注的是消息通信机制,所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。知乎上有个打电话的例子,感觉通俗易懂。
参考链接:异步执行
2017-2018-1 20179205《Linux内核原理与设计》第五周作业的更多相关文章
- 2017-2018-1 20179205《Linux内核原理与设计》第九周作业
<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第二周作业
<Linux内核原理与分析>第二周作业 本周视频学习情况: 通过孟老师的视频教程,大致对风诺依曼体系结构有了一个初步的认识,视频从硬件角度和程序员角度对CPU和Main Memory(内存 ...
- 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 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第四周作业
<Linux内核原理与分析> 视频学习及实验操作 Linux内核源代码 视频中提到了三个我们要重点专注的目录下的代码,一个是arch目录下的x86,支持不同cpu体系架构的源代码:第二个是 ...
随机推荐
- redis——持久化方式RDB与AOF分析
https://blog.csdn.net/u014229282/article/details/81121214 redis两种持久化的方式 RDB持久化可以在指定的时间间隔内生成数据集的时间点快照 ...
- C# lamda表达式
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Request"
(1) 网上下载了一个android应用:死活用不了,查了以下,原来是android studio版本不对,于是把android studio的版本从2.2 升级到3.0,后来发现没法升级,只能下载, ...
- Django 2.0 学习(09):Django 静态文件(样式和背景图片)
应用的定制化:静态文件 首先,在polls目录中创建一个名叫static的目录.Django会在该目录里面查找静态文件,类似于Django在polls/template目录下查找模板文件. Djang ...
- 封装一个jquery库
现在Javascript库海量,流行的也多,比如jQuery,YUI等,虽然功能强大,但也是不万能的,功能不可能涉及方方面面,自己写一个的JS库是对这些的补充,很多也比较实用,把应用到项目中中去也比较 ...
- hadoop 使用Avro排序
在上例中,使用Avro框架求出数据的最大值,本例使用Avro对数据排序,输入依然是之前的样本,输出使用文本(也可以输出Avro格式). 1.在Avro的Schema中直接设置排序方向. dataRec ...
- CentOS 安装MariaDB
1.安装 #同时安装mariadb和mariadb-server [root@bigdata-senior01 yum.repos.d]# yum -y install mariadb mariadb ...
- [洛谷P5057][CQOI2006]简单题
题目大意:有一个长度为$n$的$01$串,两个操作: $1\;l\;r:$把区间$[l,r]$翻转($0->1,1->0$) $2\;p:$求第$p$位是什么 题解:维护前缀异或和,树状数 ...
- some of the properties associated with the solution could not be read解决方法
基于TFS管理的解决方案打开时提示:“some of the properties associated with the solution could not be read”,并不影响项目加载,O ...
- Spring面试,IoC和AOP的理解(转)
spring 的优点?1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实 ...