Linux中断一 打尽(2) – IDT及中断处理的实现

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

其中:

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

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

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

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

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

门的概念这里主要用作权限控制,我们从一个区域进到另一个区域需要通过一扇门,有门禁权限才可以通过,因此 dpl就是这个权限,实际中我们一般称为RPL;

我们后面会通过一个例子来讲一下CPL,RPL和DPL三者之间的关系。

IDT中断描述符本身的存储

IDT 中断描述符表的物理地址存储在IDTR寄存器中,这个寄存器存储了IDT的基地址和长度。查询时,从 IDTR 拿到 base address ,加上向量 * IDT entry size,即可以定位到对应的表项(gate)。

上面的函数主要是填充好idt_data,然后调用idt_setup_from_table;

首先使用 idt_data结构来填充中断描述符变量idt_init_desc, 然后将这个中断描述符变量copy进idt_table。

看,就是这么简单~~~

  • gate_desc的多种初始化方法:

    因为gate_desc是通过ida_dat填充的,所以这里关键是idt_data的初始化,我们详细看一下:

我们再来看下G这个宏的实现:

实际上就是填充idt_data的各个字段。

2

传统系统调用的实现

这里所说的传统系统调用主要指旧的32位系统使用 int 0x80软件中断来进入内核态,实现的系统调用。因为这种传统系统调用方式需要进入内核后作权限验证,还要切换内核栈后作大量压栈方式,调用结束后清理栈作恢复,两个字太慢,后来CPU从硬件上支持快速系统调用sysenter/sysexit, 再后来又发展到syscall/sysret, 这两种都不需要通过中断方式进入内核态,而是直接转换到内核态,速度快了很

传统系统调用相关IDT的设置

Linux系统启动过程中内核压解后最终都调用到start_kernel, 在这里会调用trap_init, 然后又会调用idt_setup_traps:

我们来看这里的def_idts的定义:

上面的SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32)就是设置系统调用的异常中断处理程序,其中  #define IA32_SYSCALL_VECTOR 0x80

再看一下SYSG的定义:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年2月10日
下一篇 2020年2月10日

相关推荐