首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux下X86架构IDT解析(2)

linux下X86架构IDT解析(2)

二、IDT初始化过程
        当计算机还运行在实模式时,IDT被初始化并由BIOS使用。然而一旦linux接管,IDT就被移到RAM的另一个区域,并进行第二次初始化,因为linux没有利用任何BIOS例程。
        1. 首先在head_32.S文件中会调用setup_once局部汇编初始化IDT,本文要讲的head_32.S函数定义在\arch\x86\kernel文件中。
        __INIT
        setup_once:
       
movl $idt_table,%edi
       
movl $early_idt_handlers,%eax
       
movl $NUM_EXCEPTION_VECTORS,%ecx
        1:
       
movl %eax,(%edi)
       
movl %eax,4(%edi)
       
/* interrupt gate, dpl=0, present */
       
movl $(0x8E000000 + __KERNEL_CS),2(%edi)
       
addl $9,%eax
       
addl $8,%edi
       
loop 1b
       

       
movl $256 - NUM_EXCEPTION_VECTORS,%ecx
       
movl $ignore_int,%edx
       
movl $(__KERNEL_CS << 16),%eax
       
movw %dx,%ax
/* selector = 0x0010 = cs */
       
movw $0x8E00,%dx
/* interrupt gate - dpl=0, present */
        2:
       
movl %eax,(%edi)
       
movl %edx,4(%edi)
       
addl $8,%edi
       
loop 2b
        这段汇编将IDT表分为两部分初始化,前一部分0- 32NUM_EXCEPTION_VECTORS)表项的偏移量的地址设为early_idt_handlers的地址,32-256的表项偏移量的地址设为ignore_int的地址。

        2.第二次对IDT初始化是在start_kernel()函数中通过调用trap_init()函数对IDT进行最终初始化。调用set_trap_gate()将其初始化为陷阱门,调用set_intr_gate()将其初始化为中断门,调用set_system_gate()将其初始化为访问特权级为3的陷阱门,调用set_task_gate()将其初始化为任务门,调用set_system_intr_gate()将其初始化为访问特权级为3的中断门。
继承事业,薪火相传
返回列表