Kernel启动流程源码解析 10 init_IRQ

一 init_IRQ
本文以arm,gic-v3兼容的中断控制器为例,介绍中断控制器的初始化过程。

1.0 init_IRQ

定义在arch/arm64/kernel/irq.c中
void __init init_IRQ(void)
{
    irqchip_init();
    if (!handle_arch_irq)
        panic("No interrupt controller found.");
}

void __init irqchip_init(void)
{
    of_irq_init(__irqchip_begin);
}

// 在drivers/irqchip/irq-gic-v3.c中
IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);

// 在drivers/irqchip/irqchip.h中
#define IRQCHIP_DECLARE(name,compstr,fn)                \
    static const struct of_device_id irqchip_of_match_##name    \
    __used __section(__irqchip_of_table)                \
    = { .compatible = compstr, .data = fn }

// 在include\asm-generic\vmlinux.lds.h中
    VMLINUX_SYMBOL(__irqchip_begin) = .;                \
    *(__irqchip_of_table)                          \
    *(__irqchip_of_end)

以上三个宏实际上定义了一个
static const struct of_device_id irqchip_of_match_gic_v3 __used __section(__irqchip_of_table) = { .compatible = "arm,gic-v3", .data = gic_of_init }

而irqchip_of_match_gic_v3保存在__irqchip_of_table

device tree中包含中断控制器node为
    intc: interrupt-controller@09bc0000 {
        compatible = "arm,gic-v3";
        reg = <0x9bc0000 0x10000>,       /* GICD */ // GIC Distributor interface
              <0x9c00000 0x100000>;      /* GICR * 4 */ // GIC Redistributors
        #interrupt-cells = <3>;
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
        interrupt-controller;
        #redistributor-regions = <1>;
        redistributor-stride = <0x0 0x40000>;

        interrupts = <1 9 4>;

        gic-its@09BE0000 {
            compatible = "arm,gic-v3-its";
            msi-contoller;
            reg = <0x9be0000 0x20000>;
        };
    };

1.1 of_irq_init

void __init of_irq_init(const struct of_device_id *matches)
{
    struct device_node *np, *parent = NULL;
    struct intc_desc *desc, *temp_desc;
    struct list_head intc_desc_list, intc_parent_list;

    INIT_LIST_HEAD(&intc_desc_list);
    INIT_LIST_HEAD(&intc_parent_list);

    for_each_matching_node(np, matches) { // 遍历device tree找到与arm,gic-v3兼容的中断控制器node
        if (!of_find_property(np, "interrupt-controller", NULL))
            continue;
        /*
         * Here, we allocate and populate an intc_desc with the node
         * pointer, interrupt-parent device_node etc.
         */
        desc = kzalloc(sizeof(*desc), GFP_KERNEL); // 从内存中分配中断控制器描述符
        if (WARN_ON(!desc))
            goto err;

        desc->dev = np; // 为中断控制器描述的device_node赋值
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值