初探linux中断系统(2)

中断系统初始化的过程

用来初始化中断系统的函数位于arch/x86/kernel/irqinit.c,定义如下

void __init init_IRQ(void)
{
int i;

/*
* On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
* If these IRQ's are handled by legacy interrupt-controllers like PIC,
* then this configuration will likely be static after the boot. If
* these IRQ's are handled by more mordern controllers like IO-APIC,
* then this vector space can be freed and re-used dynamically as the
* irq's migrate etc.
*/
for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
per_cpu(vector_irq,
0)[IRQ0_VECTOR + i] = i;

x86_init.irqs.intr_init();
}

函数写的很简单,留下的疑问是x86_init是做什么的?

在arch/x86/include/asm/x86_init.h中可以找到,x86_init是一个x86_init_ops类型的结构体,其中irqs是一个x86_init_irqs类型的结构体。

struct x86_init_irqs {
void (*pre_vector_init)(void);
void (*intr_init)(void);
void (*trap_init)(void);
};

在arch/x86/kernel/x86_init.c中找到x86_init的初始默认赋值:

struct x86_init_ops x86_init __initdata = {

...

.irqs
= {
.pre_vector_init
= init_ISA_irqs,
.intr_init
= native_init_IRQ,
.trap_init
= x86_init_noop,
},

...
};

对于这几个函数,我们又要回到开头的irqinit.c中来寻找了。先看之前调用的intr_init,也就是native_init_IRQ:

void __init native_init_IRQ(void)
{
int i;

/* Execute any quirks before the call gates are initialised: */
x86_init.irqs.pre_vector_init();

apic_intr_init();

/*
* Cover the whole vector space, no vector can escape
* us. (some of these will be overridden and become
* 'special' SMP interrupts)
*/
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
if (!test_bit(i, used_vectors))
set_intr_gate(i, interrupt[i
-FIRST_EXTERNAL_VECTOR]);
}

if (!acpi_ioapic)
setup_irq(
2, &irq2);

#ifdef CONFIG_X86_32
/*
* External FPU? Set up irq13 if so, for
* original braindamaged IBM FERR coupling.
*/
if (boot_cpu_data.hard_math && !cpu_has_fpu)
setup_irq(FPU_IRQ,
&fpu_irq);

irq_ctx_init(smp_processor_id());
#endif
}

其中pre_vector_init对应着init_ISA_irqs,主要完成了irq_desc的初始化分配。

void __init init_ISA_irqs(void)
{
int i;

#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
init_bsp_APIC();
#endif
legacy_pic
->init(0);

/*
* 16 old-style INTA-cycle interrupts:
*/
for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
struct irq_desc *desc = irq_to_desc(i);

desc
->status = IRQ_DISABLED;
desc
->action = NULL;
desc
->depth = 1;

set_irq_chip_and_handler_name(i,
&i8259A_chip,
handle_level_irq,
"XT");
}
}

完成数据结构的初始化后就是对硬件资源的分配了,不做深究。

在完成初始化后,每当用户request一个新的中断操作后,成功注册将更新系统维护的链表,具体可见前篇。

posted on 2011-02-28 10:27  gary_chen  阅读(754)  评论(0编辑  收藏  举报

导航