热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

IDT表的初始化

来源: 作者: 时间:2008-08-18 Tag: 点击:


以下以图说明:



图所示的结构对应idt_table数组中的一个表项,也就是一个idt_desc类型的数据。上面说的idt_struct->a对应0到31共32位,idt_struct->b对应32到63共32位。其中16-31共16位是中断处理程序所在的段选择符,0-15位和48-64位组合起来形成32位偏移量,也就是中断处理程序所在段(由16-31位给出)的段内偏移。40-43位共4位表示描述符的类型,45-46两位标识描述符的访问特权级(DPL,Descriptor Privilege Level),47位标识段是否在内存中。如果为1则表示段当前不再内存中。此处对每一个数据项的初始化为:



32到47位就是0x8E00,其中43到40位为1110,表明此次对idt表的初始化是将其全部初始化为中断门描述符,相应的如果是0101则是任务门描述符,1111表示时陷阱门描述符。

47位为1。

要说明的是ignore_int()中断处理程序实际上是一个“空”处理。随后对IDT再次进行初始化的时候,会使其最终初始化为有效的处理程序,也就是在start_kernel()函数中。当系统跳转到start_kernel()函数时,内核才进行真正的初始化。其中调用trap_init()函数对IDT进行最终初始化。调用set_trap_gate()将其初始化为陷阱门,调用set_intr_gate()将其初始化为中断门,调用set_system_gate()将其初始化为访问特权级为3的陷阱门,调用set_task_gate()将其初始化为任务门,调用set_system_intr_gate()将其初始化为访问特权级为3的中断门。

除了set_task_gate(),其它4个函数的接口都一样,行如:

void set_xxx_gate(unsigned int n,void *addr)

{

_set_gate(n,DESCTYPE_XXX,addr,__KERNEL_CS);

}

这样的形式,其中参数n给出要初始化的IDT表项(idt_table数组的下标),addr给出对应的处理程序的地址。在这些函数的内部均是调用_set_gate()。下面就看看_set_gate()函数:


static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)

{

__u32 a, b;

pack_gate(&a, &b, (unsigned long)addr, seg, type, 0);

write_idt_entry(idt_table, gate, a, b);

}




static inline void pack_gate(__u32 *a, __u32 *b,

unsigned long base, unsigned short seg, unsigned char type, unsigned char flags)

{

*a = (seg << 16) | (base & 0xffff);

*b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff);

}




#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)




static inline void write_dt_entry(struct desc_struct *dt,

int entry, u32 entry_low, u32 entry_high)

{

dt[entry].a = entry_low;

dt[entry].b = entry_high;

}



以上函数均摘自include/asm-i386/desc.h。这些代码的功能和上面摘出的汇编的功能是一样的。首先看_set_gate()函数,参数gate和addr当然是set_xxx_gate()传给的中断号和处理程序的地址,type参数指明要将idt_table[gate]初始化为什么类型的描述符,这些类型被定义为:


相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析