视频学习

一、用户态、内核态和中断

  1. 内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态

  2. 用户态:处于低的执行级别下,代码只能在级别允许的特定范围内活动。在日常操作下,执行系统调用的方式是通过库函数,库函数封装系统调用,为用户提供接口以便直接使用。

  3. Intel x86 CPU有四种不同的执行级别0-3,Linux只使用了其中的0 3级分别表示内核态和用户态。cs寄存器的最低两位表明了当前代码的特权级,00或者11。

  4. 内核态cs:eip的值是任意的,即可以访问所有的地址空间。用户态只能访问其中的一部分内存地址(0x00000000-0xbbbbbbbf),0xc0000000以上的地址(逻辑地址而不是物理地址)只能在内核态下访问。

  5. 中断处理是从用户态进入内核态的主要方式,系统调用是一种特殊的中断。从用户态切换到内核态时,中断/int指令会在堆栈上保存用户态的寄存器上下文,其中包括用户态栈顶地址、当时的状态字、当时的cs:eip的值,还有内核态的栈顶地址、内核态的状态字、中断处理程序的入口。中断发生后的第一件事就是保存现场,保存一系列的寄存器的值;中断处理结束前的最后一件事就是恢复现场,退出中断程序,恢复保存寄存器的数据。特别说明: 保护现场:就是进入中断程序,保存需要用到的寄存器的数据;恢复现场:就是退出中断程序,恢复保存寄存器的数据。

二、系统调用概述

  1. 系统调用的意义:操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用。把用户从底层的硬件编程中解放出来,极大的提高了系统的安全性,使用户程序具有可移植性。

  2. API和系统调用:API是一个系统调用封装成的一个函数定义;系统调用通过软中断向内核发出一个明确的请求;Libc库定义的一些API引用了封装例程,目的是发布系统调用,让程序员写代码的时候可以通过函数调用而非汇编指令触发一个系统调用;一般每个系统调用对应一个封装例程,库再用这些封装例程定义出给用户的API。

  3. 应用编程接口(application program interface, API) 和系统调用是不同的

  4. 不是每个API都对应一个特定的系统调用。API可能直接提供用户态的服务,比如一些数学函数;一个单独的API可能调用几个系统调用;不同的API可能调用了同一个系统调用。

  5. 系统调用的三层皮:xyz(API)、system_call(中断向量)、sys_xyz(中断服务程序)

  6. 内核实现了很多不同的系统调用, 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数(使用eax寄存器来传递)

  7. 寄存器传递参数具有如下限制: 1)每个参数的长度不能超过寄存器的长度,即32位 2)在系统调用号(eax)之外,参数的个数不能超过6个(ebx, ecx,edx,esi,edi,ebp) 3)超过6个怎么办?超过6个的话就把某一个寄存器作为一个指针,指向某一块内存。

  8. API-int 0x80 陷入内核态-systemcall-调用函数

三、使用库函数API和C代码中嵌入汇编代码触发同一个系统调用

学习了通过使用13号系统调用time这个库函数来获取当前系统时间

如图所示的,"=m"表示写入到内存变量val3里面,"c"表示ecx接,"d"edx。下面的输入输出分别用0,1,2...编号表示,比如"addl %1,%%eax\n\t"就表示将输入输出的第2个,即"c"(ecx)的值加到eax中去,eax前面为什么有两个%,前一个%是转义符号。

实验

这次我实验所用的系统调用是mkdir,创建一个目录,在c语言中,该库函数如果执行成功则返回0,失败返回-1.代码如下:

#include <stdio.h>
int main()
{
int flag;
flag = mkdir("/home/shiyanlou/testdir");
if (flag == -1)
printf("mkdir failed!\n");
else
printf("make dirctory success!\n");
return 0;
}

先使用

vi mkdir.c

命令创建mkdir.c这个文件并进行编辑(要按i才能进入编辑模式),如图:

保存退出后(先按'esc',再输入':wq'),在终端输入ls命令,先看下当前目录下的文件和目录,如图:

再编译我们的mkdir.c文件

gcc -o makedir mkdir.c

会生成一个makedir的可执行文件,输入./makedir来执行,会弹出生成目录成功的消息,并且可以看到当前目录下多了一个testdir的目录,如图

这说明我们的代码执行成功,下面我们更改代码,将其换成嵌入汇编的代码,如图

其中我们将要生成的目录换成了testdir2,以便与之前的区分。最后我们将其编译并执行。可以看到成功创建了新的目录testdir2。

遇到的问题

  1. 就是关于系统调用函数编号的问题,mkdir的编号是39,我在看实验楼给的那些系统调用列表,将前面的编号48当成编程里面的系统调用号了,总是出错,后来仔细看才发现是39,对应十六进制为0x27。
  2. 编写嵌入汇编代码的时候,将 asm volatile()写成了asm volatitle(),以至于编译的时候也总是报错,由于是新手,也不知道错在哪,很是痛苦,不过最终还是发现问题了。而且,我发现,这里的这个写对了volatile是会变色的,错了不会变色,以后就不会犯错了。
  3. 关于调用中断服务的时候,例子里面只传入eax的值就开始调用了,而我这里还有一个参数dir(保存了一串字符串)需要传递,当时有点不知道怎么做,于是上网查资料,虽然类型不一样,但是我看他们都是接着用ebx传参数,那么我想我是否也可以用ebx传参数试试?然后又想起视频里讲了寄存器传递参数的限制:在系统调用号(eax)之外,参数的个数不能超过6个(ebx, ecx,edx,esi,edi,ebp)。那么,传参的次序是不是也依次是ebx, ecx,edx,esi,edi,ebp呢,然后试着也用ebx进行参数的传递,果然最后成功了。所以,碰到问题,多上网搜索办法,总是可以解决的。

教材内容学习

  1. 中断使得硬件得以发出通知给处理器,不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标志,这些中断值通常被称为中断请求IRQ线;在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序或中断服务例程;上半部:中断处理程序,下半部:稍后完成的工作;注册中断:注册中断 request_irq()。irq 中断号。handle 一个指针,指向中断处理程序。flags参数可以为0,也可能是下列一个或多个标志的位掩码。第四个参数name 与中断相关的设备的ASCII文本表示。 第五个参数dev用于共享中断线,当中断需要退出时,dev提供唯一的标志信息,从共享中断线的中断处理程序中删除指定程序。
  2. 中断处理程序 irqreturn_t intr_handle(int irq, void *dev_id),内核接收一个中断后,它将依次调用在该中断线上注册的每一个处理程序;当执行一个中断处理程序时,内核处于中断上下文中;Linux内核提供了一组接口用于操作机器上的中断状态;中断上下文不可以睡眠,不能从中断上下文中调用睡眠函数。
  3. 下半部的任务就是执行与中断处理密切相关但中断处理本身不执行的工作;下半部:缩短中断屏蔽时间,执行期间可以响应所有中断。下半部的环境:BH,任务队列,软中断和tasklet,工作队列,内核定时器。
  4. 软中断的实现,软中断是在编译期间静态分配的,它不像tasklet那样可以动态地注册或注销;一个软中断不会抢占另外一个软中断,唯一可以抢占软中断的是中断处理程序;软中断的执行时机:(1)从一个硬件中断代码返回时;(2)在ksoftirq内核线程中;(3)显示检查和执行处;理的软中断代码中,如网络子系统中;软中断保留给系统中对时间要求最严格以及最重要的下半部使用。
  5. tasklet通过软中断实现,本身也是软中断,有两种:HI_SOFTIRQ和TASKLET_SOFTIRQ;state成员只能在 0、TASKLET_STATE_SCHED(已经被调度,正准备投入运行)和TASKLET_STATE_RUN(正在运行)之间取值;使用tasklet:声明tasklet、编写tesklet程序、调度tasklet、ksoftirq 辅助软中断内核线程。
  6. 工作队列是另外一种将工作推后执行的形式,工作队列可把工作推后,交由一个内核线程去执行。使用工作队列:创建推后的工作,工作队列处理函数,对工作进行调度,刷新操作,创建新的工作队列。
  7. 两个相同类型的tasklet不允许同时执行即使在不同的处理器上也不行;任何在工作队列中被共享的数据也需要使用锁机制。

20169212《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. java 使用jar包

    //主类 路径 /home/fly/flywww/c/java import mypackage.One; import mypackage.Two; public class Test { publ ...

  2. css的权重

    标签的权值为1,类选择符的权值为10,ID选择符的权值最高为100.例如下面的代码: p{color:red;} /*权值为1*/ p span{color:green;} /*权值为1+1=2*/ ...

  3. IO流知识点总结

    IO流的使用:(Input  OutPut)       输入输出流: 输入:将文件读到内存中 输出:将文件从内存输出到其他地方   IO技术的作用: 主要就是解决设备和设备之间的数据传输问题.比如: ...

  4. Struts框架2ActionError类 内部资料 请勿转载 谢谢合作

    ActionError类从不独立进行错误处理,它们总是被存储在ActionErrors对象中.ActionErrors对象保存ActionError类的集合以及它们特定的属性值,我们可以使用自己定义的 ...

  5. Android 本地/网路下载图片实现放大缩小

     Android 本地加载/网路下载图片实现放大缩小拖拉效果,自定义控件. package com.example.ImageViewCustom; import android.app.Activi ...

  6. webapi 通过dynamic 接收可变参数

    public class JsonParamModel { /// <summary> /// json key /// </summary> public string Js ...

  7. selenium-JS点击(项目应用)

    public static JavascriptExecutor jse; 声明一个js public LogoutWebElements(WebDriver driver){        Logo ...

  8. Android first---xml文件生成与解析

    一.使用append进行xml生成 Message类属性:private String body;        private String date;       private String a ...

  9. ssh远程执行命令

    ssh -p $port $user@$p 'cmd' $port : ssh连接端口号 $user: ssh连接用户名 $ip:ssh连接的ip地址 cmd:远程服务器需要执行的操作 ssh -p ...

  10. 【leetcode❤python】 168. Excel Sheet Column Title

    class Solution(object):    def convertToTitle(self, n):        """        :type n: in ...