linux系统FW升降级步骤,[Fw]初探linux中断系统(2)

中断系统初始化的过程

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

67d0865f17d9be527254bf8a8ff6c5b4.gif

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();

}

67d0865f17d9be527254bf8a8ff6c5b4.gif

函数写的很简单,留下的疑问是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的初始默认赋值:

67d0865f17d9be527254bf8a8ff6c5b4.gif

struct x86_init_ops x86_init __initdata = {

...

.irqs = {

.pre_vector_init = init_ISA_irqs,

.intr_init = native_init_IRQ,

.trap_init = x86_init_noop,

},

...

};

67d0865f17d9be527254bf8a8ff6c5b4.gif

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

67d0865f17d9be527254bf8a8ff6c5b4.gif

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

}

67d0865f17d9be527254bf8a8ff6c5b4.gif

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

67d0865f17d9be527254bf8a8ff6c5b4.gif

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");

}

}

67d0865f17d9be527254bf8a8ff6c5b4.gif

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值