keil5 不进入中断_Linux中断一网打尽(2) IDT及中断处理的实现

女主宣言

通过阅读本文,您可以了解到:IDT是什么,它如何被初始化,什么是门,传统系统调用是如何实现的,以及硬件中断的实现。

PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!

1

如何设置IDT

IDT 中断描述符表定义

中断描述符表简单来说说是定义了发生中断/异常时,CPU按这张表中定义的行为来处理对应的中断/异常。

#define IDT_ENTRIES         256gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;

从上面我们可以知道,其包含了256项,它是一个gate_desc的数据,其下标0-256就表示中断向量,gate_desc我们在下面马上介绍。

中断描述符项定义

当中断发生,cpu获取到中断向量后,查找IDT中断描述符表得到相应的中断描述符,再根据中断描述符记录的信息来作权限判断,运行级别转换,最终调用相应的中断处理程序。这里涉及到Linux kernel的分段式内存管理,我们这里不详细展开,有兴趣的同学可以自行学习。如下简述之:

1. 我们知道CPU只认识逻辑地址,逻辑地址经分段处理转换成线性地址,线性地址经分页处理最终转换成物理地址,这样就可以从内存中读取了;

2. 逻辑地址你可以简单认为就是CPU执行代码时从CS(代码段寄存器) :IP (指令计数寄存器)中加载的代码,实际上通过CS可以得到逻辑地址的基地址,再加上IP这个相对于基地址的偏移量,就得到真正的逻辑地址;

3. CS寄存器16位,它不会包含真正的基地址,它一般被称为段选择子,包括一个index索引,指向GDT或 LDT的一项;一个指示位,指示index索引是属于GDT还是LDT; 还有CPL, 表明当前代码运行权限;

4. GDT: 全局描述符表,每一项记录着相应的段基址,段大小,段的访问权限DPL等,到这里终于可以获取到段基地址了,再加上之前IP寄存器里存放的偏移量,真正的逻辑地址就有了。

0fd5141bfd56ae71ed289d23d767f6ac.png

我们先看中断描述符的定义:

struct gate_struct {
      u16     offset_low;  u16     segment;  struct idt_bits bits;  u16     offset_middle;#ifdef CONFIG_X86_64  u32     offset_high;  u32     reserved;#endif} __attribute__((packed));

其中:

1. offset_high,offset_middle和offset_low合起来就是中断处理函数地址的偏移量;

2. segment就是相应的段选择子,根据它在GDT中查找可以最终获取到段基地址;

3. bits是该中断描述符的一些属性值:

struct idt_bits {
       u16     ist : 3,           zero    : 5,           type    : 5,           dpl : 2,           p   : 1;} __attribute__((packed));

ist表示此中断处理函数是使用pre-cpu的中断栈,还是使用IST的中断栈;

type表示所中断是何种类型,目前有以下四种:

enum {
       GATE_INTERRUPT = 0xE, //中断门   GATE_TRAP = 0xF, // 陷入门   GATE_CALL = 0xC, // 调用门
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值