中断、异常和系统调用(2-1,2-2,2-3)

news2024/11/20 10:47:04

2-1 课堂练习2.1:外部中断

本实训分析 Linux 0.11 对外部中断的响应和处理过程。在每条指令执行的末尾,如果没有关中断,CPU 会检查是否收到了外部中断信号,如果有信号,则 CPU 就切换到核心态去执行对应的中断处理程序,在处理完毕后,会执行 iret 这个中断返回指令,回到原状态(一般是用户态),继续执行原程序。

第1关时钟中断的发生

任务描述

 本关任务:通过实际操作回答在输出第一行 0/1 字符的过程中(如下图所示),共发生了几次时钟中断?

相关知识

为了完成本关任务,你需要掌握: 1.设置版本 1 内核为分析对象; 2.开始用 gdb 调试内核; 3.跟踪分析时钟中断。

设置版本1内核为分析对象

首先解压版本1内核源码。使用cp命令将/data/workspace/myshixun/exp1中的1.tgz复制到~/os/目录下;

切换到~/os/linux-0.11-lab目录下,将1.tgz解压到当前目录下;

然后调整cur的指向。先使用rm -rf curcur删除,再使用ln命令创建符号链接。

现在可以编译和测试版本 1 内核。首先进入1/linux目录下编译内核;

确认内核映像文件Image已经生成;

然后回到目录~/os/linux-0.11-lab,并使用./run启动虚拟机检测内核是否正常;

如果正常虚拟机在加载完毕之后将会出现如下画面。

第2关第一次时钟中断

 任务描述

分析版本1内核,找到第一次时钟中断的恢复点地址。

相关知识

为了完成本关任务,你需要掌握: 1.用 gdb 调试内核; 2.跟踪分析时钟中断; 3.中断/异常的恢复点分析。

准备阶段

本关卡的分析对象是版本1内核,可以基于前一关卡环境进行后续实验,如果重置实验环境则需要重新将版本1内核设置为分析对象,详见第一关的相关知识。

使用 gdb 调试内核

启动两个终端,在一个终端里切换到目录~/os/linux-0.11-lab,然后运行脚本 rungdb,以启动 bochs 虚拟机并等待 gdb 连接;

在另一个终端里切换到目录~/os/linux-0.11-lab,然后执行脚本./mygdb,以启动 gdb 并读入符号信息,跟踪到 main 函数入口。

跟踪分析时钟中断

在函数 do_timer(由时钟中断的处理函数 timer_interrupt 调用)处设置断点; 跟踪到该断点第 1 次出现;

中断/异常的恢复点分析

当一个中断/异常被 gdb 捕获时,通常正在运行中断处理程序,这时可以继续跟踪,直至回到恢复点指令。以时钟中断为例,为了从函数 do_timer 跟踪到恢复点,可以如下操作:

由上图可见时钟中断处理程序的入口是 timer_interrupt 函数。 跟踪到当前函数(do_timer)执行完毕返回到 timer_interrupt 函数;

跟踪到 timer_interrupt 函数(用汇编语言写的)末尾的 iret 指令;

通过单步执行命令 si 来执行该 iret 指令,返回到恢复点;

再通过反汇编命令:disas ,分析恢复点指令的地址。

关闭 gdb 调试: 在评测通关之后为了保证环境的正常,不影响下一关的操作,需要先输入 kill 指令关闭虚拟机,然后输入 quit 退出 gdb 调试。

答案

第3关第六次时钟中断

 任务描述

本关任务:通过相关知识以及实验回答:版本 1 内核的第 6 次时钟中断发生时,断点和恢复点(指令地址)分别是多少?此时 bochs 虚拟机输出的 0/1 字符串是什么?(忽略空格)

相关知识

为了完成本关任务,你需要掌握: 1.使用 gdb 调试内核; 2.跟踪分析时钟中断。

准备阶段

本关卡基于前面关卡环境进行后续实验,如果重置实验环境请从第一关重新开始。

使用 gdb 调试内核

启动两个终端,在一个终端里切换到目录~/os/linux-0.11-lab,然后运行脚本 rungdb,以启动 bochs 虚拟机并等待 gdb 连接;

在另一个终端里切换到目录~/os/linux-0.11-lab,然后执行脚本./mygdb,以启动 gdb 并读入符号信息,跟踪到 main 函数入口。

跟踪分析时钟中断

开始用 gdb 调试内核,跟踪到 main 函数入口。方法与第 1 关的步骤(2)一样。 (点击右下角上一关可以直接查看上一关内容,不会对关卡造成影响,但是不要点击评测,会改变环境)

捕获第 6 次时钟中断的发生

方法与第 2 关的步骤(3)类似,跟踪到断点 do_timer 第 6 次出现时即可,此时 jiffies 的值也是 6 。

中断/异常的恢复点分析

当一个中断/异常被 gdb 捕获时,通常正在运行中断处理程序,这时可以继续跟踪,直至回到恢复点指令。以时钟中断为例,为了从函数 do_timer 跟踪到恢复点,可以类似如下操作:

由上图可见时钟中断处理程序的入口是 timer_interrupt 函数。 跟踪到当前函数(do_timer)执行完毕返回到 timer_interrupt 函数;

跟踪到 timer_interrupt 函数(用汇编语言写的)末尾的 iret 指令;

使用调试命令 si 来执行该 iret 指令,返回到恢复点;

然后通过反汇编命令:disas ,来分析恢复点指令的地址。

断点指令和恢复点指令的分析

对于外部中断而言,恢复点指令是断点指令的后一条。需要说明的是,loop 指令的功能是先将 ecx 寄存器减一,然后检查其值,如果其值非 0 ,则继续循环,否则中止循环,执行下一条指令。以如下指令为例:

其功能是:在地址 0x7977 处循环,每次 ecx 寄存器都减一,直到其值为 0 。因此,loop 指令的上一条有可能是它自己。 在 gdb 中查看寄存器值的命令是 info reg:

断点指令和恢复点指令的分析

对于外部中断而言,恢复点指令是断点指令的后一条。需要说明的是,loop 指令的功能是先将 ecx 寄存器减一,然后检查其值,如果其值非 0 ,则继续循环,否则中止循环,执行下一条指令。以如下指令为例:

其功能是:在地址 0x7977 处循环,每次 ecx 寄存器都减一,直到其值为 0 。因此,loop 指令的上一条有可能是它自己。 在 gdb 中查看寄存器值的命令是 info reg:

答案

 

2-2 课后作业2.1:外部中断

第1关修改版本 1 内核源码,使得每次时钟中断发生时,都在屏幕上输出字符 ‘t’

任务描述

本关任务:修改版本 0 内核,使得每发生 100 次时钟中断,就在屏幕上输出一个字符‘t’和当时的进程号,如“t(0)”表示0号进程运行时发生了时钟中断。

相关知识

为了完成本关任务,你需要掌握: 1.内核态下的字符输出; 2.判断已经发生了多少次时钟中断。

内核态下的字符输出

在版本 0 内核里,可以使用函数printk来输出字符,其用法类似于printf注: 在版本 0 内核中,没有实现用int 0x81指令输出字符这个功能。

printk用法示例:

  1. printk("trying to free inode with count=%d\n",inode->i_count);
判断已经发生了多少次时钟中断

已经发生的时钟中断的次数记录在全局变量 jiffies 中,每发生一次时钟中断,该变量的值就增加 1 。

编程要求

根据相关知识,以及上课内容,对版本 0 内核进行修改,使得每发生 100 次时钟中断,就在屏幕上输出一个字符‘t’和当时的进程号。

,

使用VScode打开1/linux文件夹,获取版本1内核源代码 

在timer_interrupt函数开头添加输出字符t的汇编代码:

movb $116, %al
int $0x81

回到命令行中重新编译1/linux,再启动./rungdb和./mygdb虚拟机即可过关

第2关修改版本 0 内核

任务描述

本关任务:修改版本 0 内核,使得每发生 100 次时钟中断,就在屏幕上输出一个字符‘t’和当时的进程号,如“t(0)”表示0号进程运行时发生了时钟中断。

相关知识

为了完成本关任务,你需要掌握: 1.内核态下的字符输出; 2.判断已经发生了多少次时钟中断。

内核态下的字符输出

在版本 0 内核里,可以使用函数printk来输出字符,其用法类似于printf注: 在版本 0 内核中,没有实现用int 0x81指令输出字符这个功能。

printk用法示例:

  1. printk("trying to free inode with count=%d\n",inode->i_count);
判断已经发生了多少次时钟中断

已经发生的时钟中断的次数记录在全局变量 jiffies 中,每发生一次时钟中断,该变量的值就增加 1 。

编程要求

根据相关知识,以及上课内容,对版本 0 内核进行修改,使得每发生 100 次时钟中断,就在屏幕上输出一个字符‘t’和当时的进程号。

,

通过vscode找到do_timer

 在函数中添加

if(jiffies%100==0)
prink("t(%d),sys_getpid());

2-3 课堂练习2.2:中断/异常的处理过程


第1关除零异常分析

任务描述

分析版本 1.1 内核,回答下列问题: 1.在函数 main 的语句jiffies = jiffies/0;所对应的汇编指令片段中,有一个 idiv 指令,此指令的地址是多少? 2.在该 idiv 指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 3.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

相关知识

为了完成本关任务,你需要掌握: 1.如何设置某版本的内核为分析对象; 2.如何开始用 gdb 调试内核; 3.查看 C 语句编译之后对应的汇编指令片段; 4.分析响应中断/异常时,CPU 做了哪些工作; 5.查看当前寄存器的状态; 6.查看当前栈顶的状态。

实验准备

本关卡使用版本 1.1 内核作为分析对象,内核文件存放在/data/workspace/myshixun/exp1文件夹中,可以将其解压到linux-0.11-lab下使用。

如何设置某版本的内核为分析对象

下面以版本1内核为例进行讲解。

首先解压版本1内核源码。使用cp命令将/data/workspace/myshixun/exp1中的1.1.tgz复制到~/os/目录下;

切换到~/os/linux-0.11-lab目录下,将1.1.tgz解压到当前目录下;

然后调整cur的指向。先使用rm -rf curcur删除,再使用ln命令创建符号链接。

如何开始用 gdb 调试内核

先关闭bochs虚拟机,然后打开两个终端,其中一个终端在linux-0.11-lab目录下运行rungdb脚本,以启动 bochs 虚拟机并等待 gdb 连接;

在另一个终端里切换到目录~/os/linux-0.11-lab/,然后启动脚本./mygdb,这个命令会启动 gdb 并读入内核符号信息,同时会通过执行0.gdb中的调试命令来连接到 bochs 虚拟机,并进而跟踪到 main 函数入口。

查看 C 语句编译之后对应的汇编指令片段

如果要查看某条 C 语句编译之后对应的汇编指令片段,可以在该 C 语句处设置断点,并跟踪到该断点,然后反汇编,所看到的当前指令之后的一段汇编指令就对应于该 C 语句。

例如,jiffies = jiffies/0;是文件 main.c 的第 147 行,可以如下方式查看:

上面显示的汇编指令中,有一行前面有箭头标识,此即为当前指令,即马上将要执行的指令。

分析响应中断/异常时,CPU 做了哪些工作
  • 切换到核心栈,并在其中保存中断现场。

  • 转到中断处理程序去运行,并切换到核心态。

如下图所示:

上图显示了栈中中断现场的结构,(OLD SS:OLD ESP) 描述了用户栈顶的位置,(OLD CS:OLD EIP) 描述了恢复点的位置。

如何查看当前寄存器的状态

使用 gdb 调试命令 info registers 即可,如下所示:

也可以单独查看某一个寄存器:

如何查看当前栈顶的状态

可以使用命令 x 来查看:

上面显示了栈顶的 5 个长字,是某异常发生时的中断现场,其中存储的用户栈顶的位置是 0x17:0x2573c ,存储的恢复点的位置是 0xf:0x7967 。需要注意的是,x86 中栈是从高地址向低地址方向增长的,这里的栈顶位置是 0x1fa0c 。

编程要求

根据相关知识,回答问题:(将答案填写在/data/workspace/myshixun/第一关.txt中) 1.在函数 main 的语句jiffies = jiffies/0;所对应的汇编指令片段中,有一个 idiv 指令,此指令的地址是多少? 2.在该 idiv 指令执行之前,当前指令位置(CS:EIP)和栈位置(SS:ESP)分别是多少? 3.使用 si 命令执行了该指令后,新指令位置和栈位置分别是多少?此时栈中保存的恢复点位置和用户栈位置分别是多少?

答案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1294251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言第十六集(前)

1.关于那个整形存储入char的 是先取好补码,再截断 例: 2.%u是以十进制的形式打印无符号整数 3.注意(背):存储的char类型变量的补码为10000000的直接解析为-128 4.signed char 类型的变量取值范围是-128~127 5.unsigned char 类型的变量取值范围是0~255 6.有符号类型的变量…

编程创意汇聚地,打造个性作品集 | 开源日报 No.97

spring-projects/spring-boot Stars: 70.4k License: Apache-2.0 Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它通过提供默认配置和约定大于配置的方式来减少开发者的工作量。Spring Boot 可以快速地创建独立的、生产级别的基于 Spring 框架的应用程序…

【论文合集】在非欧空间中的图嵌入方法(Graph Embedding in Non-Euclidean Space)

文章目录 1. Hyperbolic Models1.1 Hyperbolic Graph Attention Network1.2 Poincar Embeddings for Learning Hierarchical Representations.1.3 Learning Continuous Hierarchies in the Lorentz Model of Hyperbolic Geometry1.4 Hyperbolic Graph Convolutional Neural Net…

快速登录界面关于如何登录以及多账号列表解析以及config配置文件如何读取以及JsLogin模块与SdoLogin模块如何通信(4)

1、### Jslogin模块与前端以及JsLogin模块与Sdologin的交互 配置文件的读取: <CompanyIdForQq value"301"/> <CompanyIdForWx value"300"/><CompanyIdForWb value"302"/><qq value"https://graph.qq.com/oauth2.0/au…

使用Notepad++编辑器,安装AnalysePlugin搜索插件

概述 是一款非常有特色的编辑器&#xff0c;Notepad是开源软件&#xff0c;Notepad中文版可以免费使用。 操作步骤&#xff1a; 1、在工具栏 ->“插件”选项。 2、勾选AnalysePlugin选项&#xff0c;点击右上角“安装”即可。 3、 确认安装插件 4、下载插件 5、插件已安装…

【Linux】resolv.conf 文件

resolv.conf resolv.conf 文件 是 DNS 的 client 端使用的文件&#xff0c;用于设置 DNS 服务器的 ip 地址以及 DNS 域名&#xff0c;还可以配置域名搜索顺序等等。主要包含如下关键字&#xff1a;nameserver、domain、search、sortlist、options。设置的格式都是 关键字空格 …

Java期末复习题之抽象类、接口

点击返回标题->23年Java期末复习-CSDN博客 第1题. 首先设计一个学生抽象类Student&#xff0c;其数据成员有name(姓名)、age(年龄)和degree(学位)&#xff0c;以及一个抽象方法show()。然后由Student类派生出本科生类Undergraduate和研究生类Graduate&#xff0c;本科生类Un…

使用ES6 async awai t进行异步处理

我们往往在项目中会遇到这样的业务需求&#xff0c;就是首先先进行一个ajax请求&#xff0c;然后再进行下一个ajax请求&#xff0c;而下一个请求需要使用上一个请求得到的数据&#xff0c;请求少了还好说&#xff0c;如果多了&#xff0c;就要一层一层的嵌套&#xff0c;就好像…

AI自动生成代码工具

AI自动生成代码工具是一种利用人工智能技术来辅助或自动化软件开发过程中的编码任务的工具。这些工具使用机器学习和自然语言处理等技术&#xff0c;根据开发者的需求生成相应的源代码。以下是一些常见的AI自动生成代码工具&#xff0c;希望对大家有所帮助。北京木奇移动技术有…

小航助学2023年9月GESP_Scratch一级真题(含题库答题软件账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号 单选题3.00分 删除编辑附件图文 答案:C 第1题我们通常说的“内存”属于计算机部件中的( ) A、输出设备B、输入设备C、存储设备D、打印设备 答案解析&#xff1a; 单选题3…

Kubernetes(K8s 1.27.x) 快速上手+实践,无废话纯享版(视频笔记)

视频源&#xff1a;1.03-k8s是什么&#xff1f;_哔哩哔哩_bilibili 1 基础知识 1.1 K8s 有用么&#xff1f; K8s有没有用 K8s要不要学&#xff1f; 参考资料: https://www.infoq.com/articles/devops-and-cloud-trends-2022/?itm_sourcearticles_about_InfoQ-trends-report…

FPGA实现电机位置环、速度环双闭环PID控制

一、设计思路 主要设计思路就是根据之前写的一篇FPGA实现电机转速PID控制&#xff0c;前面已经实现了位置环的控制&#xff0c;思想就是通过电机编码器的当前位置值不断地修正PID去控制速度。 那为了更好的实现控制&#xff0c;可以在位置环后加上速度环&#xff0c;实现电机位…

thinkphp lists todo

来由&#xff1a; 数据库的这个字段我想返回成&#xff1a; 新奇的写法如下&#xff1a; 逻辑层的代码&#xff1a; public function goodsDetail($goodId){$detail $this->good->where(id, $goodId)->hidden([type_params,user_id])->find();if (!$detail) {ret…

LinuxBasicsForHackers笔记 -- 进程管理

进程是一个正在运行和使用资源的程序。 Linux 内核是操作系统的内核&#xff0c;几乎控制着一切&#xff0c;在创建进程时&#xff0c;它会按顺序为每个进程分配一个唯一的进程 ID (PID)。 查看进程 ps – 用于在命令行查看哪些进程处于活动状态。单独使用 ps 命令并不能真正…

线上盲盒扭蛋机,开启潮玩新玩法

盲盒近几年非常火爆&#xff0c;因其不确定性、随机性吸引着盲盒爱好者&#xff0c;引起了潮玩文化风潮。扭蛋机是盲盒的一种新抽取模式&#xff0c;线上扭蛋机小程序在具有盲盒的优势外&#xff0c;还具有较大吸引力&#xff0c;用户参与率较高&#xff0c;这也使得扭蛋机成为…

Spring 依赖注入的三种方式优缺点

小王学习录 前言属性注入1. 属性注入的优点2. 属性注入的缺点 Setter注入Setter注入的优点Setter注入的缺点 构造方法注入1. 构造方法的优点 总结补充Aurowired注解和Resource注解的区别 前言 在前面的文章中介绍了基于注解的方式将Bean存储到Spring中, 接下来介绍如何基于注解…

11.Java安卓程序设计-基于SSM框架的Android平台健康管理系统的设计与实现

摘要 随着人们生活水平的提高和健康意识的增强&#xff0c;健康管理系统在日常生活中扮演着越来越重要的角色。本研究旨在设计并实现一款基于SSM框架的Android平台健康管理系统&#xff0c;为用户提供全面的健康监测和管理服务。 在需求分析阶段&#xff0c;我们明确了系统的…

LLM微调(三)| 大模型中RLHF + Reward Model + PPO技术解析

本文将深入探讨RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09;、RM&#xff08;reward model&#xff09;和PPO&#xff08;Proximal Policy Optimizer&#xff09;算法的概念。然后&#xff0c;通过代码演示使用RLHF训练自己的大模型和奖励模型RM。…

上网监控软件——安全与隐私的平衡

网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;随着网络使用的普及&#xff0c;网络安全问题也日益突出。上网监控软件作为网络安全领域的一个重要组成部分&#xff0c;在保护企业和家庭网络安全方面发挥着重要作用。 本文将探讨上网监控软件的背景、功能、优…

Java第二十一章

一.网络程序设计基础 1.网络协议 网络协议规定了计算机之间连接的物理、机械(网线与网卡的连接规定)、电气(有效的电平范围)等特征&#xff0c;计算机之间的相互寻址规则&#xff0c;数据发送冲突的解决方式&#xff0c;长数据如何分段传送与接收等内容.就像不同的国家有不同的…