操作系统实现-外中断

博客网址:www.shicoder.top
微信:18223081347
欢迎加群聊天 :452380935

这一次我们来对中断中的外中断进行讲解,先给下中断的分类和中断号分配把。

操作系统实现-外中断

中断号 分类 0x0-0x20 异常和非屏蔽中断 0x20-0x30 I/O设备引发的可屏蔽中断,比如键盘、时钟等外中断 0x30-0xff 软中断,比如常说的int 80系统调用

前面对异常进行了讲解,这次对外中断进行说明。我们下面以时钟中断举例,首先我们要知道的是,时钟中断是操作系统自己发生的,比如我们在执行一段代码时候,可能不知道啥时候,就会触发时钟中断,我们为了体现触发了时钟中断,我们就打印一句话就行。

同样我们给每个外中断号定义一个入口函数

INTERRUPT_HANDLER 0x20, 0; clock 时钟中断
INTERRUPT_HANDLER 0x21, 0; 键盘中断
INTERRUPT_HANDLER 0x22, 0
INTERRUPT_HANDLER 0x23, 0
INTERRUPT_HANDLER 0x24, 0
INTERRUPT_HANDLER 0x25, 0
INTERRUPT_HANDLER 0x26, 0
INTERRUPT_HANDLER 0x27, 0
INTERRUPT_HANDLER 0x28, 0
INTERRUPT_HANDLER 0x29, 0
INTERRUPT_HANDLER 0x2a, 0
INTERRUPT_HANDLER 0x2b, 0
INTERRUPT_HANDLER 0x2c, 0
INTERRUPT_HANDLER 0x2d, 0
INTERRUPT_HANDLER 0x2e, 0
INTERRUPT_HANDLER 0x2f, 0

在这个函数中,同样设置一个具体的函数

void idt_init()
{
    // 初始化ENTRY_SIZE个中断处理函数
    for (size_t i = 0; i < ENTRY_SIZE; i++)
    {
        gate_t *gate = &idt[i];
        // gate->offset0 = (u32)interrupt_handler & 0xffff;
        // gate->offset1 = ((u32)interrupt_handler >> 16) & 0xffff;
        handler_t handler = handler_entry_table[i];

        gate->offset0 = (u32)handler & 0xffff;
        gate->offset1 = ((u32)handler >> 16) & 0xffff;
        gate->selector = 1 << 3; // 代码段
        gate->reserved = 0;      // 保留不用
        gate->type = 0b1110;     // 中断门
        gate->segment = 0;       // 系统段
        gate->DPL = 0;           // 内核态
        gate->present = 1;       // 有效
    }
    // 异常的具体处理函数
    for (size_t i = 0; i < 0x20; i++)
    {
        handler_table[i] = exception_handler;
    }
    // 外中断的具体处理函数
    for (size_t i = 0x20; i < ENTRY_SIZE; i++)
    {
        handler_table[i] = default_handler;
    }

    idt_ptr.base = (u32)idt;
    idt_ptr.limit = sizeof(idt) - 1;

    asm volatile("lidt idt_ptr\n");
}
void default_handler(int vector)
{
    send_eoi(vector);
    LOGK("[%d] default interrupt called %d...\n", vector, counter++);
}

注意我们有一个 send_eoi函数,这是发送结束中断的函数,因为我们比如时钟中断产生,那么首先是结束中断,然后才是对其进行处理,不然后续就不会再次发生中断,其代码如下

void send_eoi(int vector)
{
    if (vector >= 0x20 && vector < 0x28)
    {
        outb(PIC_M_CTRL, PIC_EOI);
    }
    if (vector >= 0x28 && vector < 0x30)
    {
        outb(PIC_M_CTRL, PIC_EOI);
        outb(PIC_S_CTRL, PIC_EOI);
    }
}

最后就是main函数的编写

void kernel_init()
{
    console_init();
    gdt_init();
    interrupt_init();

    // asm volatile(
    // "sti\n"
    // "movl %eax, %eax\n");

    asm volatile("sti");

    u32 counter = 0;
    while (true)
    {
        DEBUGK("looping in kernel init %d...\n", counter++);
        delay(100000000);
    }
}

其中最主要的就是 asm volatile("sti"),这行表示打开中断,否则不会触发,还有一个关键,怎么让cpu知道是时钟中断呢,这就要中断控制器进行设置,下面是设置代码

// 初始化中断控制器
void pic_init()
{
    outb(PIC_M_CTRL, 0b00010001); // ICW1: 边沿触发, 级联 8259, 需要ICW4.

    outb(PIC_M_DATA, 0x20);       // ICW2: 起始端口号 0x20
    outb(PIC_M_DATA, 0b00000100); // ICW3: IR2接从片.

    outb(PIC_M_DATA, 0b00000001); // ICW4: 8086模式, 正常EOI

    outb(PIC_S_CTRL, 0b00010001); // ICW1: 边沿触发, 级联 8259, 需要ICW4.

    outb(PIC_S_DATA, 0x28);       // ICW2: 起始端口号 0x28
    outb(PIC_S_DATA, 2);          // ICW3: 设置从片连接到主片的 IR2 引脚
    outb(PIC_S_DATA, 0b00000001); // ICW4: 8086模式, 正常EOI

    outb(PIC_M_DATA, 0b11111110); // 关闭所有中断,打开时钟中断
    outb(PIC_S_DATA, 0b11111111); // 关闭所有中断
}

主要看最后两行,设置打开哪些中断,下面是支持的中断图,可以看到有支持15个中断,上面的 outb(PIC_M_DATA, 0b11111110)表示打开时钟中断,当值为0,打开中断。

操作系统实现-外中断

下面是实验的结果图,第一张图是没有设置 send_eoi,可以看到只接收到了一次中断

操作系统实现-外中断

下面是设置了 send_eoi

操作系统实现-外中断

我们下面来尝试下键盘中断,将 outb(PIC_M_DATA, 0b11111110);设置为 outb(PIC_M_DATA, 0b11111101);,开启程序,我们按下键盘,可以看到,当按下键盘触发,但是我们再次按下,却发现没有用,这是因为针对键盘中断,我们要编写对应的处理函数,比如处理收到的字符,然后编写对应的中断结束函数,才能再次接受中断

操作系统实现-外中断

Original: https://www.cnblogs.com/shilinkun/p/16305628.html
Author: 小坤学习园
Title: 操作系统实现-外中断

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607195/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 《kasini3000》批量修改linux被控机密码

    《卡死你3000》,是开源,免费,跨平台的devops批量脚本框架。 网址:码云家 https://gitee.com/chuanjiao10/kasini3000 批量生成密码之…

    Linux 2023年6月13日
    090
  • Golang中通过go-redis操作Redis

    参考地址:https://github.com/go-redis/redis 定义上下文以及连接的相关信息 var ctx = context.Background() var r…

    Linux 2023年5月28日
    0108
  • 网络设备配置–8、利用ospf配置动态路由

    一、前言 同系列前几篇:网络设备配置–1、配置交换机enable、console、telnet密码网络设备配置–2、通过交换机划分vlan网络设备配置&#8…

    Linux 2023年6月8日
    0113
  • 数据结构 二叉树

    cpp;gutter:true;</p> <h1>include</h1> <p>using namespace std;</…

    Linux 2023年6月13日
    084
  • 制作pip离线源

    一、下载指定的包到相应的文件夹 (1)、创建存放安装包的目录:(联网环境) bash;gutter:true; pip list #查看安装的包 mkdir packs pip i…

    Linux 2023年6月8日
    0121
  • Oracle 恢复delete误删数据

    — 开启行移动功能 alter table 表名 enable row movement; — 查询删除前的数据 select * from 表名 as of timestam…

    Linux 2023年6月8日
    095
  • MySQL安装和配置

    一、关闭防火墙并安装epel源 1、关闭selinux ①修改selinux的配置文件 [root@localhost ~]# vim /etc/selinux/config SE…

    Linux 2023年6月7日
    094
  • mycat数据库集群系列之mycat读写分离安装配置

    最近在梳理数据库集群的相关操作,现在花点时间整理一下关于mysql数据库集群的操作总结,恰好你又在看这一块,供一份参考。本次系列终结大概包括以下内容:多数据库安装、mycat部署安…

    Linux 2023年6月14日
    0133
  • SSM 集成 Freemarker 模板引擎

    在前后端分离的大趋势下,项目开发过程中,应尽量减少前端和后台的依赖和耦合,前端和后台尽可能采用 ajax 进行交互;但是全站 ajax,不利于网站 SEO,所以引入模板引擎,尽量减…

    Linux 2023年6月14日
    096
  • Tomcat

    Tomcat Tomcat tomcat简介 tomcat的用处 部署tomcat 测试访问 访问Host Manager界面 访问Server Status tomcat简介 T…

    Linux 2023年6月6日
    0137
  • 每周一个linux命令(tree)

    安装tree命令 yum install tree -y 显示当前目录下的一级目录结构 tree -L 1 目录信息说明 bin: 系统常用命令所在目录 boot: 系统启动相关的…

    Linux 2023年6月8日
    0104
  • Java秒杀系统一:环境搭建和DAO层设计

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月11日
    0126
  • redis 命令

    Redis是用C语言实现的,一般来说C语言实现的程序”距离”操作系统更近,执行速度相对会更快。 Redis使用了单线程架构,预防了多线程可能产生的竞争问题。…

    Linux 2023年5月28日
    083
  • 源码安装apache脚本部署

    源码安装apache脚本部署 [root@localhost ~]# ls anaconda-ks.cfg httpd.tar.xz [root@localhost ~]# tar…

    Linux 2023年6月6日
    0110
  • [ Skipper ] 快速 LVL

    https://www.cnblogs.com/yeungchie/ ski-flashlvl ski-flashlvl top1.gds cell1 top2.gds cell2…

    Linux 2023年6月7日
    0105
  • [随记]-SpringMVC中的handler到底是什么东西

    HandlerMapping 初始化时候的 HandlerMapping 有,按顺序排列: requestMappingHandlerMapping beanNameHandler…

    Linux 2023年6月6日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球