这里分析的是 XtratuM 1.0 的代码。
关于 XM 中断接管的代码主要在 arch/$ARCH/kernel/irq.c ($ARCH = i386) 中。还有一部分在 patch 文件中,不过那个貌似关系不是很大,主要是替换了某些 cli 和 sti 指令,但是这些替换后的代码实质上和 cli、sti 的作用是一样的,所以我也有点奇怪为什么要有这样的替换,貌似不替换也是可以的……
在 irq.c 中,替换函数是 hw_irq_takeover():
/* filename: arch/i386/kernel/irq.c */
193 int hw_irq_takeover (void) {
194 unsigned long hw_flags, vector, irq;
195
196 // Our irq and trap tables which will replace actual IDT table
197
198 irq_addr = (void (**) (void)) &__start_irq_handlers_addr;
199 trap_addr = (void (**) (void)) &__start_trap_handlers_addr;
200
201 real_idt_table = hw_get_idt_table_addr ();
202
203 hw_save_flags_and_cli(&hw_flags);
204
205 __root_sti = XM_root_func.__sti;
206 __root_cli = XM_root_func.__cli;
207 __root_save_flags = XM_root_func.__save_flags;
208 __root_restore_flags = XM_root_func.__restore_flags;
209 __root_is_cli = XM_root_func.__is_cli;
210
211 XM_root_func.__sti = vsti;
212 XM_root_func.__cli = vcli;
213 XM_root_func.__save_flags = vsave_flags;
214 XM_root_func.__restore_flags = vrestore_flags;
215 XM_root_func.__is_cli = vis_cli;
216 XM_root_func.__emulate_iret = emulate_iret;
217
218 for (vector = 0; vector < IDT_ENTRIES; vector ++)
219 root_idt_table [vector] = hw_get_gate_addr (vector);
220
221
222 for (irq = 0; irq < NR_IRQS; irq ++) {
223 hw_xpic [irq] = ((irq_desc_t *)XM_root_func.__irq_desc)[irq].handler;
224 ((irq_desc_t *)XM_root_func.__irq_desc)[irq].handler = &vpic;
225 }
226
227 // In an i386 there are 16 irqs, 0..15 (besides of the apic interrupt)
228
229 for (irq = 0; irq < NR_IRQS; irq++) {
230 vector = irq + FIRST_EXTERNAL_VECTOR;
231
232 // Replacing all hw irq gates for XtratuM routines
233 hw_set_irq_gate(vector, irq_addr [irq]);
234 }
235
236 hw_set_trap_gate(0, trap_addr[0]);
237 hw_set_trap_gate(1, trap_addr[1]);
238 hw_set_sys_gate(3, trap_addr[3]);
239 hw_set_sys_gate(4, trap_addr[4]);
240 hw_set_sys_gate(5, trap_addr[5]);
241 hw_set_trap_gate(6, trap_addr[6]);
242 hw_set_trap_gate(7, trap_addr[7]);
243 hw_set_trap_gate(8, trap_addr[8]);
244 hw_set_trap_gate(9, trap_addr[9]);
245 hw_set_trap_gate(10, trap_addr[10]);
246 hw_set_trap_gate(11, trap_addr[11]);
247 hw_set_trap_gate(12, trap_a