zoukankan      html  css  js  c++  java
  • x86体系结构idt的设定

    intel x86体系结构中断向量表中包含256个中断向量,编号为0-255。这256个中断可分为两大类:异常、中断。

    异常

    异常是CPU内部的中断,异常分为故障(fault)、陷阱(trap)、夭折(abort),它们的共同特点是不使用中断控制器、也不能被屏蔽。

    中断

    通常是由外部设备产生的,分为可屏蔽中断和非屏蔽中断。

    其中非屏蔽中断和异常的向量号是固定的,而屏蔽中断的向量号可以通过对中断控制器的编程来实现。

    如上图所示,外设通过中断线连接到中断控制器,中断控制器连接到CPU的中断引脚。外设如要中断CPU,需要通过中断线申请,如键盘可以通过IRQ1申请中断。因为IDT表的前一部分用于处理异常,故而这里IRQ申请的向量号从32开始;但是可以通过编程中断控制器来修改。

    IDT

    在实模式下,内存最开始的1K字节存储中断向量表。每个表项都有4个字节,前两个字节表示中断服务程序的段基址,后两个字节表示偏移量。

    在保护模式下,中断向量表中的表项由8个字节组成,中断向量表也改称中断描述符表(Interrupt Descriptor Table);其中的每个表项称为一个门描述符。

     

     同时,在保护模式下,中断描述符表也不需要在地址为0的地方开始,可以常驻于内存的任何地方。

    为查询IDT的起始地址,在CPU中专门设置了一个IDTR——中断描述符表寄存器,如下:

     神似GDTR,这是一个48位寄存器,高32位保存了IDT的基地址,低16位保存了中断描述符表的大小。

    初始化

    内核在启用中断机制之前,必须把IDT表的起始地址载入IDTR寄存器,并初始化表中的每一个表项。

    IDT被初始化两次。第一次是在BIOS程序中,此时CPU还运行在实模式下,IDT被初始化并由bootloader程序使用。一旦Linux启动,IDT会被搬运到RAM的受保护区域并被第二次初始化。

    IDT结构被存储在idt_table表中,包含256项。idt_descr变量存储IDT的大小和它的地址,在系统的初始化阶段,内核用来设置IDTR寄存器,专用汇编指令是lidt。

    异常及中断处理

    当CPU执行完当前指令后,需要判断是否发生了异常或者中断。如果确实发生,则:

    1、确定所发生的异常或者中断在IDT表中的id(0-255)

    2、通过IDTR寄存器加载IDT表的基地址,并读取对应id的表项

    CPU通过相应表项的门描述符的段选择子,跳转到异常或者中断处理程序中执行。

    但要注意下面两点:

    1、权限检查:检查CPU的当前权限CPL与IDT表中相应表项的DPL,权限低的代码可以访问权限级别高的代码

    2、检查是否发生了特权级的变化。若中断发生时CPU运行在用户空间 ,而中断处理程序运行在内核态,特权级发生了变化,会引起堆栈的更换,即从用户堆栈切换到内核堆栈。而当中断发生在内核态时,即CPU 在内核中运行时,则不会更换堆栈。

  • 相关阅读:
    测试用户网速办法
    JS 判断后端返回的对象是否为空
    优美地低于生活——读书笔记
    vue login.js登录逻辑
    vuex store index.js配置登录
    vue router的 index.js设置
    css 添加校验时的必填项前面的红色的*
    vue 的 main.js 设置
    vue.config.js配置
    vim的使用
  • 原文地址:https://www.cnblogs.com/caidi/p/15167133.html
Copyright © 2011-2022 走看看