local APIC 初期化の続き init_IRQ での処理編 (その3)
次は intr_init_hook() の呼び出し。
/* setup after call gates are initialised (usually add in * the architecture specific gates) */ intr_init_hook();
これについては、amazon:Linuxカーネル解析入門にフォローあり。
ソースは arch/i386/mach-default/setup.c との事にて定義は以下。
intr_init_hook()#arch/i386/mach-default/setup.c
void __init intr_init_hook(void) { #ifdef CONFIG_X86_LOCAL_APIC apic_intr_init(); #endif if (!acpi_ioapic) setup_irq(2, &irq2); }
ちなみにamazon:Linuxカーネル解析入門における apic_intr_init() の解説は p.152 から p.154 に、又、その後の条件分岐の部分については、p.154 から p.155 に解説がある。
ようやくココまでキましたな、との感慨の共に M-. で apic_intr_init() を検索。amazon:Linuxカーネル解析入門にもソースが引用されていますが、以下。
apic_intr_init()#arch/i386/kernel/apic.c
void __init apic_intr_init(void) { #ifdef CONFIG_SMP smp_intr_init(); #endif /* self generated IPI for local APIC timer */ set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); /* IPI vectors for APIC spurious and error interrupts */ set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); /* thermal monitor LVT interrupt */ #ifdef CONFIG_X86_MCE_P4THERMAL set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); #endif }
む。現時点でアレなのは
- smp_intr_init() で何してるんだ
- set_intr_gate() って何だ
という二点。
早速、掘りサゲる。とりあえずは set_intr_gate() を。
って、結構簡単にめっかったんですが、これはマニュアルの助けが必要ですな。以下にソースを貼っておいてちょっとだけ暇を頂ければ幸いッス。
set_intr_gate()#arch/i386/kernel/traps.c
#define _set_gate(gate_addr,type,dpl,addr,seg) \ do { \ int __d0, __d1; \ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ "movw %4,%%dx\n\t" \ "movl %%eax,%0\n\t" \ "movl %%edx,%1" \ :"=m" (*((long *) (gate_addr))), \ "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ "3" ((char *) (addr)),"2" ((seg) << 16)); \ } while (0) /* * This needs to use 'idt_table' rather than 'idt', and * thus use the _nonmapped_ version of the IDT, as the * Pentium F0 0F bugfix can have resulted in the mapped * IDT being write-protected. */ void set_intr_gate(unsigned int n, void *addr) { _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); }
これはキアイいるなぁ。とりあえずインライン・アセンブラの引数のナニをもっかい思い出す必要あり。(とほほほ
てか、_set_gate() って難解だぞ。