中断描述符表的初始化

本文详细介绍了Linux内核在系统初始化时如何设置中断描述符表(IDT),包括设置中断门、陷阱门和系统门的过程,以及如何初始化IDT以确保安全性和功能性的实现。内容涉及IDT的布局、门类型的设置方法以及如何处理中断处理程序的填充。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    Linux内核在系统初始化要进行大量的初始化工作,其与中断相关的工作有,初始化可编程控制器8259A;将中断描述符表的起始地址装入IDTR寄存器,并初始化表中的每一项,

    用户进程可以通过INT指令发出 一个中断请求向量在0~255之间。为了防止用户使用INT指令模拟非法的中断和异常,必须对中断描述符表进行谨慎的初始化。其措施之一就是将中断门或陷阱门中的请求特权级DPL域置为0,如果用户进程确实发出了这样一个中断请求,CPU会检查出其当前特权级CPL(3)与所请求的特权级DPL(0)有冲突,因此产生一个“通用保护”异常。

    但是,有时候必须让用户进程能够使用内核所提供的功能(比如系统调用),也就是说从用户态进入内核态,这可以通过把中断门和陷阱门的DPL置为3来达到。

    当计算机运行在实模式时,中断描述表被初始化,并由BIOS使用。然而,一旦真正进入Linux内核,中断描述符表 就被移动到内存的另一个区域,并为进入保护模式进行预初始化,把中断描述符表IDT的起始地址装入IDTR。

    用setup_idt()函数填充中断描述符表中的256个表项。在对这个表进行填充时,使用了一个空的中断处理程序。因为现在处于初始化阶段,还没有任何中断处理程序,因此,用空的中断处理程序填充每个表项。

    在对中断描述符表进行初始化后,内核将在其用分页功能后对IDT进行第二遍初始化,也就是说,用实际的陷阱和中断处理程序替换这个空的处理程序。一旦这个过程完成,对于每个异常,IDT都有一个专门的陷阱门或系统门,而对每个外部中断,IDT都包含专门的中断门。


1.IDT表项的设置

IDT表项的设置是通过_get_gate()函数实现的,下面给出如何调用该函数在IDT表中插入的一个门。

(1)插入一个中断门

    void set_intr_gate(unsigned int n, void *addr) {

      _set_gate(idt_table+n, 14, 0 , addr);

    }

    其中,idt_table时中断描述符表IDT在程序中的符号表示,n表示在第n个表项中插入一个中断门。这个们的段选择符设置成代码段的选择符(addr表示偏移域)。DPL设置成0(第三个参数代表权限),14表示D标志位为1(表示32位),而类型码位110(由14决定),所以set_intr_gate()设置的时中断门,偏移域设置成中断处理程序的地址addr。

(2)插入一个陷阱门

    static void  __init set_trap_gate(unsigned int n, void *addr)

    {

      _set_gate(idt_table+n, 15, 0, addr);

    }

    在第n个表项中插入一个陷阱门。这个门的断选择符设置成代码段的选择符,DPL设置成0,15表示D标志位为1,而类型码位111,所以set_system_gate()设置的时陷阱门,偏移域设置成异常处理程序的地址addr。

(3)插入一个系统门

    static void __init set_system_gate(unsigned int n, void *addr)
    {

      _set_gate(idt_table+n, 15, 3, addr);

    }

    在第n个表项中插入一个系统门。这个门的段选择符设置成代码段的选择符,DPL域设置成3, 15表示D标志位为1,而类型码为111,所以set_system_gate()设置的也是陷阱门,但因为DPL为3,因此,系统调用在用户态可以通过“INT 0x80”顺利穿过系统门,从而进入内核态。


3.中断门的设置

中断门的设置是由init_IRQ()函数种的一段代码完成的:

for(i=0; i<(NR_VECTORS  - FIRST_EXTERNAL_VECTOR); i++)

{

   int  vector =  FIRST_EXTERNAL_VECTOR + i;

   if( i >= NR_IRQS)

      break;

   if(vector != SYSCALL+VECTOR)

      set_intr_gate(vector, interrupt[i]);

}

从FIRST_EXTERNAL开始,设置 NR_IRQS(NR_VECTORS-FIRST_EXTERNAL_VECTOR)个IDT表项。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值