init/main.c:
1 asmlinkage void start_kernel(void)
2 {
3 ......
4 early_irq_init();
5 init_IRQ();
6 ......
7 }
early_irq_init()函数有两种实现,一种是基于radix tree,一种是定义静态数组,如果要使用radix tree实现的,那么需要打开SPARSE_IRQ配置选项,由于我对数据结构不了解,所以分析以下静态数组实现方式版本的。
/kernel/irq/irqdesc.c
1 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
2 [0 ... NR_IRQS-1] = {
3 .handle_irq = handle_bad_irq,
4 .depth = 1,
5 .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
6 }
7 };
8
9 int __init early_irq_init(void)
10 {
11 int count, i, node = first_online_node;
12 struct irq_desc *desc;
13
14 init_irq_default_affinity();
15
16 printk(KERN_INFO 'NR_IRQS:%dn', NR_IRQS);
17
18 desc = irq_desc;
19 count = ARRAY_SIZE(irq_desc);
20
21 for (i = 0; i < count; i++) {
22 desc[i].kstat_irqs = alloc_percpu(unsigned int);
23 alloc_masks(&desc[i], GFP_KERNEL, node);
24 raw_spin_lock_init(&desc[i].lock);
25 lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
26 desc_set_defaults(i, &desc[i], node);
27 }
28 return arch_early_irq_init();
29 }
第一次见到这种初始化数组全部成员为同样内容的方式,可以学习积累下。
NR_IRQS在arch/arm/mach-s5pv210/include/mach/irqs.h下定义:
1 #define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
上面函数的核心就是调用desc_set_defaults()来初始化上述中断描述符数组,kernel/irq/irqdesc.c:
1 static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
2 {
3 int cpu;
4
5 desc->irq_data.irq = irq;
6 desc->irq_data.chip = &no_irq_chip;
7 desc->irq_data.chip_data = NULL;
8 desc->irq_data.handler_data = NULL;
9 desc->irq_data.msi_desc = NULL;
10 irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
11 irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
12 desc->handle_irq = handle_bad_irq;
13 desc->depth = 1;
14 desc->irq_count = 0;
15 desc->irqs_unhandled = 0;
16 desc->name = NULL;
17 for_each_possible_cpu(cpu)
18 *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
19 desc_smp_init(desc, node);
20 }
最后返回时调用的arch_early_irq_init()函数并没有做事情。
接着看init_IRQ():
1 void __init init_IRQ(void)
2 {
3 machine_desc->init_irq();
4 }
machine_desc是全局变量,定义在板文件中,由于我们使用的是s5pv210,且demo板号选的是smdkv210,所以这个全局变量就在arch/arm/mach-s5pv210/mach-s5pv210.c中:
1 MACHINE_START(SMDKV210, 'SMDKV210')
2 /* Maintainer: Kukjin Kim 3 .boot_params = S5P_PA_SDRAM + 0x100, 4 .init_irq = s5pv210_init_irq, 5 .map_io = smdkv210_map_io, 6 .init_machine = smdkv210_machine_init, 7 .timer = &s5p_timer, 8 MACHINE_END arch/arm/mach-s5pv210/mach-s5pv210.c中还有如下函数定义: 1 void __init s5pv210_init_irq(void) 2 { 3 u32 vic[4]; /* S5PV210 supports 4 VIC */ 4 5 /* All the VICs are fully populated. */ 6 vic[0] = ~0; 7 vic[1] = ~0; 8 vic[2] = ~0; 9 vic[3] = ~0; 10 11 s5p_init_irq(vic, ARRAY_SIZE(vic)); 12 } arch/arm/plat-s5p/irq.c 1 void __init s5p_init_irq(u32 *vic, u32 num_vic) 2 { 3 #ifdef CONFIG_ARM_VIC 4 int irq; 5 6 /* initialize the VICs */ 7 for (irq = 0; irq < num_vic; irq++) 8 vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); 9 #endif 10 11 s3c_init_vic_timer_irq(5, IRQ_TIMER0); 12 13 s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); 14 } 上面涉及到的函数都是去操作VIC相关的寄存器,这部分操作还不是很清楚,先不往下继续追踪了。
上一篇:U-Boot bootargs简析
下一篇:04_uboot全面讲解
推荐阅读最新更新时间:2026-03-22 11:01
- RDR-142 - 35W电源
- i.MX RT1060 Evaluation Kit
- 使用 Embedded Planet 的 5CEFA9U27 的参考设计
- DC1369A-D、LTC2258-14 演示板、14 位 65 Msps ADC、LVDS 输出、5-170MHz
- LT3990EMSE-5 12V 降压转换器的典型应用
- 使用 Analog Devices 的 LTC1148 的参考设计
- LT1377IS8 具有直接反馈的正负转换器的典型应用
- 使用 NXP Semiconductors 的 TL431AI 的参考设计
- LT8304IS8E 18V 至 80Vin、5Vout 隔离反激式转换器的典型应用电路
- LT3512EMS 演示板,单片式高压隔离反激式转换器 36V VIN 75V,VOUT = 5V @ 500mA

STM32模拟串口
STC8H全系列单片机应用手册
【Follow me第三季第4期】CY8CPROTO-063-BLE开发任务汇总代码
非常经典的关于LLC的杨波博士论文
VI-27WIU






京公网安备 11010802033920号