主要解析trap_init()部分:设置中断门和陷阱门,cpu_init()则与CPU的初始化有关。

set_trap_gate(0,&divide_error);
set_trap_gate(1,&debug);
set_intr_gate(2,&nmi);
set_system_gate(3,&int3);	/* int3-5 can be called from all */
set_system_gate(4,&overflow);
set_system_gate(5,&bounds);
set_trap_gate(6,&invalid_op);
set_trap_gate(7,&device_not_available);
set_trap_gate(8,&double_fault);
set_trap_gate(9,&coprocessor_segment_overrun);
set_trap_gate(10,&invalid_TSS);
set_trap_gate(11,&segment_not_present);
set_trap_gate(12,&stack_segment);
set_trap_gate(13,&general_protection);
set_trap_gate(14,&page_fault);
set_trap_gate(15,&spurious_interrupt_bug);
set_trap_gate(16,&coprocessor_error);
set_trap_gate(17,&alignment_check);
set_trap_gate(18,&machine_check);
set_trap_gate(19,&simd_coprocessor_error);

set_system_gate(SYSCALL_VECTOR,&system_call);

/*
 * default LDT is a single-entry callgate to lcall7 for iBCS
 * and a callgate to lcall27 for Solaris/x86 binaries
 */
set_call_gate(&default_ldt[0],lcall7);
set_call_gate(&default_ldt[4],lcall27);

/*
 * Should be a barrier for any external CPU state.
 */
cpu_init();

硬件基础

一般由三种:中断、陷阱和异常。CPU对于这三者的响应过程基本是一致的:

  1. 在执行指令期间,或执行完指令之后,根据中断源所提供的中断向量,在内存中找到中断处理程序的入口并调用该程序。外部中断的向量则是由软件或硬件设置好的。
  2. 陷阱的向量,是在 trap指令当中产生的(例如 INT n
  3. 异常,则是由CPU的硬件实现确定好的。

x86体系结构在保护模式当中,提供了四种门:任务门、中断门、调用门和陷阱门。除任务门以外,其他三种门基本相同。

任务门通过优先级检查后,保存当前的运行上下文,并切换到TSS段选择码指向的TSS段开始运行。TSS作为一个任务进行运行。Linux中使用task_struct 来描述进程的控制块,并非CPU所设计的那样利用TR和TSS段来进行任务切换。

                                                                                 任务门结构图

                                                                             任务门结构图

                                                             中断门、陷阱门、调用门

                                                         中断门、陷阱门、调用门

中断门和陷阱门的唯一区别在于:通过中断门进入中断服务程序时,CPU会自动关闭中断,即将EFLAGS当中的IF清零,防止嵌套中断。而陷阱门进入服务程序时则维持IF标志位不变。