20169219《linux内核原理与分析》第六周作业
网易云课堂学习
1、intel x86 CPU有四种不同的执行级别0-3,linux只使用了其中的0级和3级分贝来表示内核态和用户态。
2、一般来说在linux中,地址空间是一个显著的标志:0xc0000000以上的地址空间只能在内核态下访问,0x00000000-0xbfffffff的地址空间在两种状态下都可访问。(地址空间指逻辑地址不是物理地址)。
3、系统调用的三层皮:xyz(API)、system_call(中断向量)、sys_xyz(不同种类的服务程序)。
4、Libc库定义个一些API引用了封装例程(wrapper routine,唯一的目的就是发布系统调用,程序员在写代码的时候不需要用汇编指令来触发一个系统调用,而是直接触发一个函数就能进行系统调用了。)
5、system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。
实验部分
本次实验内容是使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用。我选的是4号系统调用write。在屏幕上打印输出“hello world!”,对应的API就是printf。
用API实现,创建hello.c文件,代码如下:
#include <stdio.h>
#include <string.h>
int main()
{
char* msg = "Hello World";
printf("%s", msg);
return 0;
}
用汇编代码实现,创建hello-asm.c文件,代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char* msg = "hello world!";
int len = 12;
int result = 0;
asm volatile (
"movl %2, %%edx;\n\r" /*传入参数:要显示的字符串长度*/
"movl %1, %%ecx;\n\r" /*传入参赛:文件描述符(stdout)*/
"movl $1, %%ebx;\n\r" /*传入参数:要显示的字符串*/
"movl $4, %%eax;\n\r" /*系统调用号:4 sys_write*/
"int $0x80" /*触发系统调用中断*/
:"=m"(result) /*输出部分*/
:"m"(msg),"r"(len) /*输入部分:绑定字符串和字符串长度变量*/
:"%eax");
return 0;
}
要在 "asm" 内使用寄存器 %eax,%eax 的前面应该再加一个 %,换句话说就是 %%eax,因为 "asm" 使用 %0、%1 等来标识变量。任何带有一个 % 的数都看作是输入/输出操作数,而不认为是寄存器。
在汇编中用 %序号 来代表这些输入/输出操作数, 序号从 0 开始。为了与操作数区分开来, 寄存器用两个%引出,如:%%eax。
$表示当前位置。
运行结果如图:

linux内核设计与实现
中断和中断处理
为了提高CPU和外围硬件(硬盘,键盘,鼠标等等)之间协同工作的性能,引入了中断的机制。
没有中断的话,CPU和外围设备之间协同工作可能只有轮询这个方法。
在接收到来自外围硬件(相对于中央处理器和内存)的异步信号,或来自软件的同步信号之后,处理器将会进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。
中断的类型
在PC机系统中,根据中断源的不同,中断常分为两大类:硬件中断和软件中断。
硬件中断也称为外部中断,它又可以分为两种:可屏蔽中断(INTR)和非屏蔽中断NMI。
中断有优先级之分,中断优先级指中断的响应级别。
软件中断优先级最高,非屏蔽中断次之,可屏蔽中断优先级最低。
我们经常可以看到IRQ和INT的缩写。IRQ是主板提供的硬件中断端口,一般有8或16个;INT则是操作系统提供的中断处理程序的入口标记,一般有256个。
中断处理函数
- irg 表示要分配的中断号
- handler 一个指针,指向实际的中断处理程序
- flags 标志位,表示此中断的具有特性
- name 是与中断相关的设备的ASCII文本表示
- dev 用于共享中断线,多个中断程序共享一个中断线时(共用一个中断号),依靠dev来区别各个中断程序
- 返回值:执行成功返回0;执行失败返回非0
中断控制方法表
| 函数 | 说明 |
|---|---|
| local_irq_disable() | 禁止本地中断传递 |
| local_irq_enable() | 激活本地中断传递 |
| local_irq_save() | 保存本地中断传递的当前状态,然后禁止本地中断传递 |
| local_irq_restore() | 恢复本地中断传递到给定的状态 |
| disable_irq() | 禁止给定中断线,并确保该函数返回之前在该中断线上没有处理程序在运行 |
| disable_irq_nosync() | 禁止给定中断线 |
| enable_irq() | 激活给定中断线 |
| irqs_disabled() | 如果本地中断传递被禁止,则返回非0;否则返回0 |
| in_interrupt() | 如果在中断上下文中,则返回非0;如果在进程上下文中,则返回0 |
| in_irq() | 如果当前正在执行中断处理程序,则返回非0;否则返回0 |
下半部和推后执行的工作
上半部的功能是"登记中断",当一个中断发生时,它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去。因此,上半部执行的速度就会很快,可以服务更多的中断请求。但是,仅有"登记中断"是远远不够的,因为中断的事件可能很复杂。因此,Linux引入了一个下半部,来完成中断事件的绝大多数使命。下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的,下半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断!下半部则相对来说并不是非常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不在中断服务上下文中执行。
上半部和下半部的划分
- 如果一个任务对时间十分敏感,将其放在上半部
- 如果一个任务和硬件有关,将其放在上半部
- 如果一个任务要保证不被其他中断打断,将其放在上半部
- 其他所有任务,考虑放在下半部
- 中断下半部实现的机制主要有三种:软中断、tasklet和工作队列。
tasklet
tasklet由tasklet_struct结构表示,它在<linux/interrupt.h>中定义为:
struct tasklet_struct{
struct tasklet_struct *next;//链表中下一个tasklet
unsigned long state; //tasklet的状态
atomic_t count; //引用计数器
void (*func)(unsigned long);//tasklet处理函数
unsigned long data; //给tasklet处理函数的参数
}
工作队列
工作队列子系统是一个用于创建内核线程的接口。工作队列可以把工作推后,交由一个内核线程去执行,也就是说,这个下半部分可以在进程上下文中执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的就是工作队列允许被重新调度甚至是睡眠。
- 工作队列的使用
- 创建推后的工作
DECLARE_WORK(name,void (*func) (void *),void *date- 工作队列处理函数
void work_handler(void *date)- 对工作进行调度
schedule_work(&work)- 刷新指定工作队列
void flush_scheduled_work(void)
三种机制的差别与联系。
软中断:
1、软中断是在编译期间静态分配的。
2、最多可以有32个软中断。
3、软中断不会抢占另外一个软中断,唯一可以抢占软中断的是中断处理程序。
4、可以并发运行在多个CPU上(即使同一类型的也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保护其数据结构。
5、目前只有两个子系直接使用软中断:网络和SCSI。
6、执行时间有:从硬件中断代码返回时、在ksoftirqd内核线程中和某些显示检查并执行软中断的代码中。
tasklet:
1、tasklet是使用两类软中断实现的:HI_SOFTIRQ和TASKLET_SOFTIRQ。
2、可以动态增加减少,没有数量限制。
3、同一类tasklet不能并发执行。
4、不同类型可以并发执行。
5、大部分情况使用tasklet。
工作队列:
1、由内核线程去执行,换句话说总在进程上下文执行。
2、可以睡眠,阻塞。
20169219《linux内核原理与分析》第六周作业的更多相关文章
- 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文件处理内容 ...
- 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语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- php中删除数组的第一个元素和最后一个元素的函数
对于一个php数组,该如何删除该数组的第一个元素或者最后一个元素呢?其实这两个过程都可以通过php自带的函数 array_pop 和 array_shift 来完成,下面就具体介绍一下如何来操作. ( ...
- logstash的output插件
logstash 的output插件 nginx,logstash和redis在同一台机子上 yum -y install redis,vim /etc/redis.conf 设置bind 0.0.0 ...
- adobe flash player 下载地址
1. https://www.adobe.com/cn/products/flashplayer/distribution3.html
- Codeforces 402D Upgrading Array:贪心 + 数学
题目链接:http://codeforces.com/problemset/problem/402/D 题意: 给你一个长度为n的数列a[i],又给出了m个“坏质数”b[i]. 定义函数f(s),其中 ...
- poj3177边-双连通分量
题意和poj3352一样..唯一区别就是有重边,预先判断一下就好了 #include<map> #include<set> #include<list> #incl ...
- codeforces 553B B. Kyoya and Permutation(找规律)
题目链接: B. Kyoya and Permutation time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- jQuery插件:图片放大镜--jQuery Zoom
本文转载于http://blog.csdn.net/xinhaozheng/article/details/4085644, 这是一款非常不错的给图片添加放大镜效果,可以应用在诸如zen cart,m ...
- OpenCV - Windows(win10)编译opencv + opencv_contrib
在之前的几篇文章中,我提到了在Android.Linux中编译opencv + opencv_contrib,这篇文章主要讲在Windows中编译opencv + opencv_contrib. 首先 ...
- iOS使用NSURLSession发送POST请求,后台无法接受到请求过来的参数
iOS中发送POST请求,有时需要设置Content-Type,尤其是上传图片的时候. application/x-www-form-urlencoded: 窗体数据被编码为名称/值对.这是标准的编码 ...
- BZOJ1345:[Baltic2007]序列问题
浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...