中断描述符寄存器idt
存在两个指令lidt和sidt分别是存储到寄存器和加载到内存
// 16byte gate
struct gate_struct {
u16 offset_low;//函数地址低16位
u16 segment;//段地址
//ist表示使用per-cpu中断栈还是ist中断栈,type是何种类型的中断,dpl则是权限位
unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
u16 offset_middle;//函数地址中间16位
u32 offset_high;//函数地址高32位
u32 zero1;
} __attribute__((packed));//告诉编译器不对齐优化,实际多少字节则就是多少字节
相关函数
static inline void set_intr_gate(int nr, void *func)
{
_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0);//设置中断门类型
}
static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)
{
struct gate_struct s;
s.offset_low = PTR_LOW(func);
s.segment = __KERNEL_CS;//内核代码段的段地址
s.ist = ist;
s.p = 1;
s.dpl = dpl;
s.zero0 = 0;
s.zero1 = 0;
s.type = type;
s.offset_middle = PTR_MIDDLE(func);
s.offset_high = PTR_HIGH(func);
/* does not need to be atomic because it is only done once at setup time */
memcpy(adr, &s, 16);
}
看下set_intr_gate函数调用传入的全局变量idt_table,
extern struct gate_struct idt_table[];,也就是引用外部的一个中断门结构体数组
在start_kernel里的调用的是trap_init,下面看看trap_init函数做了什么
void __init trap_init(void)
{
set_intr_gate(0,÷_error);
set_intr_gate_ist(1,&debug,DEBUG_STACK);
set_intr_gate_ist(2,&nmi,NMI_STACK);
set_system_gate(3,&int3);