网易云课堂学习

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内核原理与分析》第六周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  3. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. 《python基础教程(第二版)》学习笔记 基础部分(第1章)

    <python基础教程(第二版)>学习笔记 基础部分(第1章)python常用的IDE:Windows: IDLE(gui), Eclipse+PyDev; Python(command ...

  2. Linux查看端口占用进程

    Linux查看端口占用进程 netstat -anlp|grep 8081 tcp /java 此处3195为进程ID

  3. java 中的拦截器和过滤器

    区别: 1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几 ...

  4. Delpih - Format

    Format是一个很常用,却又似乎很烦的方法,本人试图对这个方法的帮助进行一些翻译,让它有一个完整的概貌,以供大家查询之用: 首先看它的声明:function Format(const Format: ...

  5. jQuery 对表单、表格的操作及更多应用-简略笔记

    [jQuery 对表单.表格的操作及更多应用] jquery对表单及表格的操作是实际应用中相当广泛. 对于表单的操作,可以实现 (1)获取和失去焦点改变样式: (2)在多行文本框中可以实现网站评论框的 ...

  6. Unity3D之Mesh(三)绘制四边形

    前言: 由於之前的基本介紹,所以有關的知識點不做贅述,只上案例,知識作爲自己做試驗的記錄,便於日後查看. 步驟: 1.創建一個empty 的gameobject: 2.添加一個脚本給這個game ob ...

  7. 关于IDT报错乱码总结

    可算是把我折腾坏了.一筹莫展.最后才把这些问题搞好.有些事不知道做以前,怎么都想不到.发现了方法之后,原来也不过这样.我觉得自己记性太差.还是好好写下来吧.写下来顺便会帮我重新再梳理一遍.原先乱码是因 ...

  8. linux命令学习笔记(19):find 命令概览

    Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能 很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花 ...

  9. AngularJS方法 —— angular.copy

    描述: 复制一个对象或者一个数组(好吧,万物皆对象,数组也是一个对象). 如果省略了destination,一个新的对象或数组将会被创建出来: 如果提供了destination,则source对象中的 ...

  10. 【C/C++】scanf,printf 函数

    摘自http://www.cplusplus.com 1. scanf 函数 int scanf ( const char * format, ... ); Parameters format C s ...