中断处理程序

news2025/1/12 21:03:27

文章目录

  • 前言
  • 前置知识
    • 中断概念
    • 中断分类
  • 实验操作
    • 实验一
    • 实验二
    • 实验三

前言

博客记录《操作系统真象还原》第七章实验的操作~

实验环境:ubuntu18.04+VMware , Bochs下载安装

实验内容

  1. 编写中断处理程序( 操作 8259A 打开中断)。
  2. 改进中断处理程序(在汇编版本的 intrXXentry 中调用 C 语言版本的中断处理函数)。
  3. 用计数器/定时器 8253 来设置时钟中断发生的频率。(给中断信号提速)。

前置知识

中断概念

中断处理(中断)的概念:由于 CPU 获知了计算机中发生的某些事,CPU 暂停正在执行的程序,转而去执行处理该事件的程序, 当这段程序执行完毕后,CPU 继续执行刚才的程序。整个过程称为中断处理,也称为中断。

OS 操作系统是中断驱动的。没有中断,操作系统几乎什么都做不了!

中断分类

中断可以分为以下2种类型。

  1. 外中断:来自 CPU 外部的中断就称为外部中断。
  2. 内中断:来自 CPU 内部的中断称为内部中断。

中断机制的本质:中断机制的本质是传入一个中断信号后,调用相应的中断处理程序。所以,CPU 将来自外部设备、内部指令的各种中断类型都归结为一种管理方式,即为每个中断信号分配一个整数,用此整数作为中断的 ID(整数即中断向量),然后用此 ID 作为中断描述符表中的索引,从而找到对应的表项,进而从中找到对应的中断处理程序。

外中断

外部中断是指来自 CPU 外部的中断,而这个外部的中断源一定是某个硬件。因此,外部中断又称为硬件中断。

外部硬件的中断是通过两根信号线通知 CPU 的,分别是INTR(INTeRrupt)和 NMI(Non Maskable Interrupt)。如下图所示

在这里插入图片描述

因为任务有轻重缓急,因此可以再细分位可屏蔽中断(maskable interrupt)和不可屏蔽中断(non-maskable interrupt,NMI)。

  • 可屏蔽中断
    概念:此外部设备发出的中断,CPU 可以不理会,因为它不会让系统宕机。
    【注】CPU也可以理会,把中断分为上半部和下半部分开处理。

  • 不可屏蔽中断
    概念:紧急的中断,严重可让让 CPU 宕机。
    中断处理流程:CPU 收到中断后,需要得知道发生了什么事情才能执行相应的处理办法。这是通过中断向量号进而查中断向量表或中断描述符表(中断向量表是实模式下的中断处理程序数组,在保护模式下已经被中断描述符表代替)来实现的。

内中断

内部中断可分为软中断和异常。

  • 软中断:软中断是指由软件主动发起的中断。(ex. “int 8 位立即数”)
  • 异常:异常是指令执行期间 CPU 内部产生的错误引起的。(ex. “int3”)

实验操作

实验一

开启中断流程

  1. init_all 函数用来初始化所有的设备及数据结构。
  2. init_all 调用 idt_init 初始化中断相关的内容。
  3. 初始化分为2个部分完成,分别是 pic_init 和 idt_desc_init。其中,pic_init (Programmable Interrupt Controller )用来初始化可编程中断控制器 8259A ,ide_desc_init 用来初始化中断描述符表 IDT。
  4. idt_init 完成,便加载 IDT 啦

在这里插入图片描述
实验1用汇编语言实现中断处理程序,该程序保存在 kernel.S 文件中。

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim kernel.S

完成了中断处理程序的编写,咱现在要把它们安装到中断描述符表中。即,创建中断描述符表 IDT,安装中断处理程序。该程序保存在 interrupt.c 文件中(文件 interrupt.c 包含目前有关中断的内容)。

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim interrupt.c

完成中断相关的数据准备,接下来需要设置中断代理 8259A ,这里用到内联汇编实现端口 I/O 函数。io.h 声明有关端口操作的函数定义。

(base) user@ubuntu:/home/cooiboi/bochs/lib/kernel$ sudo vim io.h

接着,需要定义初始化相关的工作的文件,即init_all。

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim init.c

init_all 是由 main.c 中的主函数 main 调用的,更新 main 函数。

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim  main.c

完成剩下文件的创建

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim global.h
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim init.h
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim interrupt.h

查看kernel下文件

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ ls
global.h  init.h       interrupt.h  kernel.S
init.c    interrupt.c  kernel.bin   main.c

新建 build 文件夹存放输出文件(将所有目标文件和编译后的内核文件)

(base) user@ubuntu:/home/cooiboi/bochs$ sudo mkdir build

完成基本文件创建工作后,现在进入到编译、链接、写入磁盘的步骤。

编译工作

sudo nasm -f elf -o build/print.o lib/kernel/print.S
sudo nasm -f elf -o build/kernel.o kernel/kernel.S
(base) user@ubuntu:/home/cooiboi/bochs$ sudo nasm -f elf -o build/print.o lib/kernel/print.S
(base) user@ubuntu:/home/cooiboi/bochs$ sudo nasm -f elf -o build/kernel.o kernel/kernel.S
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c
(base) user@ubuntu:/home/cooiboi/bochs$ sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c
(base) user@ubuntu:/home/cooiboi/bochs$ sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c
(base) user@ubuntu:/home/cooiboi/bochs$ sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c

链接工作

这里注意新 kernel.bin 的目录,是在 build 目录下

sudo ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o
(base) user@ubuntu:/home/cooiboi/bochs$ sudo ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o

写入磁盘

sudo dd if=/home/cooiboi/bochs/build/kernel.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=200 seek=9 conv=notrunc
(base) user@ubuntu:/home/cooiboi/bochs$ sudo dd if=/home/cooiboi/bochs/build/kernel.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=200 seek=9 conv=notrunc
14+1 records in
14+1 records out
7236 bytes (7.2 kB, 7.1 KiB) copied, 0.00014881 s, 48.6 MB/s

如果硬盘内容存在问题可以删掉重新写入,下面是之前写入的内容(贴出来方便实现)

sudo dd if=/home/cooiboi/bochs/boot/mbr.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=1 conv=notrunc
sudo dd if=/home/cooiboi/bochs/boot/loader.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=3 seek=2 conv=notrunc

启动Bochs

sudo bin/bochs -f boot/bochsrc.disk
(base) user@ubuntu:/home/cooiboi/bochs$ sudo bin/bochs -f boot/bochsrc.disk

在这里插入图片描述

让我们看看安装后的中断描述符的样子八!命令:info idt

在这里插入图片描述

  • 第一列是中断门描述符的序号,共 0x20 个。
  • Interrupt Gate target 是门描述符中所指向的中断处理程序地址,用选择子:偏移量的形式表示。

假设查看某个中断门描述符,可以使用info idt 序号命令。【下图所示中断向量号 0x20 对应的中断门描述符】

在这里插入图片描述

实验二

改进中断处理程序,在汇编版本的 intrXXentry 中调用 C 语言版本的中断处理函数。

修改 interrupt.c 和 kernel.S 文件

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim interrupt.c
(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim  kernel.S 

之后的步骤和实验一的一模一样~

运行图中不断打印“int vector: 0x20”(只打开了时钟中断,并且时钟的中断向量号是 0x20)

在这里插入图片描述

实验三

新建device 目录下,存放设备代码。

(base) user@ubuntu:/home/cooiboi/bochs$ sudo mkdir  device

创建 timer.c 和 timer.h。

(base) user@ubuntu:/home/cooiboi/bochs/device$ sudo vim timer.c
(base) user@ubuntu:/home/cooiboi/bochs/device$ sudo vim timer.h

接下来,把 timer_init 函数加在文件 init.c 中

(base) user@ubuntu:/home/cooiboi/bochs/kernel$ sudo vim  init.c

完成基本文件创建工作后,现在进入到编译、链接、写入磁盘的步骤。

下面命令均在/home/cooiboi/bochs$下执行。

编译

sudo nasm -f elf -o build/print.o lib/kernel/print.S
sudo nasm -f elf -o build/kernel.o kernel/kernel.S
sudo gcc -m32 -I lib/kernel -c -o build/timer.o device/timer.c
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c
sudo gcc -m32 -I lib/kernel/ -m32 -I lib/ -m32 -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c

链接工作

sudo ld -m elf_i386 -Ttext 0xc0001500 -e main -o build/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o build/timer.o

写入磁盘

sudo dd if=/home/cooiboi/bochs/build/kernel.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=200 seek=9 conv=notrunc

启动Bochs

sudo bin/bochs -f boot/bochsrc.disk

在这里插入图片描述
参考资料

  • 《操作系统真象还原》
  • 《操作系统真象还原》第七章 ---- 终进入中断处理拳打脚踢 操作系统日渐成熟 目前所有代码总览

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

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

相关文章

2023年浙江食品安全管理员考试真题题库及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 一、多选题 1.餐具清洗消毒水池与以下哪些水池应分开&#xff…

机器学习— —导入数据

DAY1集成开发环境原始数据展示主要函数介绍data.iloc()函数dataset.iloc[0]dataset.iloc[:,:-1]dataset.iloc[:,3]dataset.iloc[1:3,1]可执行代码导入结果展示我的写在最后集成开发环境 Spyder (前身是 Pydee) 是一个强大的交互式 Python 语言开发环境,提供高级的代…

如何搭建Python环境和安装Pycharm

1、 搭建Python的基础环境 Anaconda简介 Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些…

【Kotlin】标准库函数 ② ( run 标准库函数 | run 函数传入 Lambda 表达式作为参数 | run 函数传入函数引用作为参数 )

文章目录一、run 标准库函数1、run 函数传入 Lambda 表达式作为参数2、run 函数传入函数引用作为参数Kotlin 语言中 , 在 Standard.kt 源码中 , 为所有类型定义了一批标准库函数 , 所有的 Kotlin 类型都可以调用这些函数 ; 一、run 标准库函数 1、run 函数传入 Lambda 表达式作…

Odoo丨5步轻松实现在Odoo中打开企微会话框

文章目录一、前言二、实现方案三、接口调用步骤一、前言 企业微信作为一个很好的企业级应用发布平台,尤其是提供的数据和接口,极大地为很多企业级应用提供便利,在日常中应用广泛! 最近在项目中就遇到一个与企业微信相关的场景开…

商标异议解读

商标异议解读《商标法》第三十五条规定,对初步审定公告的商标提出异议的,商标局应当听取异议人和被异议人陈述事实和理由,经调查核实后,自公告期满之日起十二个月内做出是否准予注册的决定,并书面通知异议人和被异议人…

Python初次实现MapReduce——WordCount

前言 Hadoop 本身是用 Java 开发的,所以之前的MapReduce代码小练都是由Java代码编写,但是通过Hadoop Streaming,我们可以使用任意语言来编写程序,让Hadoop 运行。 本文用Python语言实现了词频统计功能,最后通过Hadoo…

Redis从青铜到王者,从环境搭建到熟练使用

一、常见的非关系型数据库NOSQL分类NOSQL类型主要数据库产品类型特色K-V键值对存储类型Redis、Memcached使用key可以快速的查询到value,Memcached可以支持String类型的值value,Redis支持的值的数据类型很多如:String\set\hash\sortset\list等…

1月重磅福利——Softing在线培训课程上线

尽管有标准化和界面友好的工具,但车辆诊断的复杂性仍需要或多或少的专业知识支持,其具体取决于应用领域和要求。无论是初学者还是高级工程师,我们都很乐意为您日常遇到的问题提供相关支持,并就车辆诊断、ODX和OTX标准以及工具的使…

LeetCode 179. 最大数

🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓LeetCode 179. 最大数,做好准备了么,那么开始吧。 🌲🌲🐴🐴 一、题目名称 LeetCode 179. …

01Hashmap并发问题-ConcurrentHashMap-线程安全集合类-并发编程(Java)

1 概述 线程安全类可以分为3个大类: 遗留的的线程安全集合Hashtable,Vector使用Collections装饰的线程安全集合,如: Collections.syncronizedCollectionCollections.syncronizedListCollections.syncronizedMapCollections.sync…

Linux系列文章 —— vim的基本操作(误入vim退出请先按「ESC」再按:q不保存退出,相关操作请阅读本文)

系列文章目录 文章目录系列文章目录前言一、vim的基本概念二、vim的基本操作1.退出vim编辑器2.进入vim编辑器3.模式功能及切换三、vim命令模式命令集1.光标移动2.查找字符3.复制粘贴删除4.撤销、重做与重复做5.插入模式6.保存与退出7.环境修改四、总结1.vim的三种基本模式2.vim…

springboot之webmvc和webflux浅析

webmvc和webflux作为spring framework的两个重要模块,代表了两个IO模型,阻塞式和非阻塞式。 1、webmvc webmvc是基于servlet的阻塞式模型,一个请求到达服务器后会单独分配一个线程去处理请求,如果请求包含IO操作,线程…

车载以太网 - DoIP时间参数 - 06

时间参数在所有的协议定义中都无法被忽略的一块重要部分,之前的CAN&CANFD诊断协议总,ISO 16765就有相关的诊断时间参数的定义;在DoIP中,也有同样的时间参数定义,不过他是放在ISO 13400 - 2中,今天我们一起来看下这一块的内容。 ISO 13400原文文档 中文释义 时间参数定…

北大硕士LeetCode算法专题课-基础算法之排序

接连上篇:北大硕士LeetCode算法专题课---算法复杂度介绍_骨灰级收藏家的博客-CSDN博客 冒泡排序 冒泡排序(Bubble Sort)是一种很原始的排序方法,就是通过不断地交换“大数”的位置达到排序的目的。 因为不断出现“大数”类似于水…

HTML实现狗屁不通文章生成器

演示 实现 css html, body {background: radial-gradient(#181818, #000000);margin: 0;padding: 0;border: 0;-ms-overflow-style: none;}.btn {display: inline-block;color: #fff;cursor: pointer;font-size: 1em;font-weight: 400;max-weight: 20%;position: relative;tex…

【零基础】学python数据结构与算法笔记8

文章目录前言46.数据结构介绍47.列表48.栈的介绍49.栈的应用:括号匹配问题50.队列的介绍51.队列的实现52.队列的内置模块总结前言 学习python数据结构与算法,学习常用的算法, b站学习链接 46.数据结构介绍 数据结构是指相互之间存在着一种…

双点双向重发布以及路由策略

目录前言实验要求基础配置启动rip 及 ospf 协议双向重发布路由策略前言 1,由于ASBR在重发布路由条目时,将清除原有协议携带的度量,会添加新协议的度量种子,一旦2,使用双点双向重发布时,可能会出现选路不佳…

docker容器日志清理

最近发现linux(Centos 7)虚拟机的空间不够了,想创建新的容器都失败。剩下不到100M。之前还有好几个G。然后每天不定期查看磁盘空间,发现不断被蚕食。今天比昨天就少了100M;然后下午比上午又少了50M。谁在吞噬服务器的硬…

Nacos学习之使用Nacos作为配置中心

使用Nacos作为配置中心 简单使用 1、导入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-nacos-config</artifactId></dependency>2、创建bootstrap.properties文件&#xff0c;在其中对nacos…