Linux GIC 的初始化

本文深入探讨了Linux内核在启动过程中如何进行中断子系统,特别是GIC(Generic Interrupt Controller)的初始化流程。从start_kernel()开始,经过boot_cpu_init()、setup_arch()和mm_init()等多个关键步骤,重点解析init_IRQ()中的GIC初始化细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创文章,转载请注明出处.

Linux中断的初始化流程:

Linux kernel的启动入口是start_kernel(), 在init/main.c中,start_kernel()中有一系列初始化操作,比如:boot_cpu_init(),setup_arch(&command_line),mm_init()等, 本文主要分析init_IRQ()

__irqchip_of_table实际为静态定义好的一个section,其定义在驱动文件drivers/irqchip/irq-gic-v3.c中,
定义方式为IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init)。

init_IRQ() arch/arm64/kernel/irq.c
->irqchip_init()
->of_irq_init(__irqchip_of_table);
{
struct device_node *np, *parent = NULL;
        struct of_intc_desc *desc, *temp_desc;

初始化两个list, 分别为int-controller的list和int-controller-parent的list
INIT_LIST_HEAD(&intc_desc_list);
        INIT_LIST_HEAD(&intc_parent_list);

定义一个struct device_node *np, 遍历dts中所有的node,如果和__irqchip_of_table匹配, 则说明
该node是一个int-controller。 以下是gic device node的例子:
arch/arm64/boot/dts/freescale/fsl-imx8qm.dtsi
gic: interrupt-controller@51a00000 {
compatible = "arm,gic-v3";
reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
  <0x0 0x51b00000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
#interrupt-cells = <3>;
interrupt-controller;
interrupts = <GIC_PPI 9
(GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
interrupt-parent = <&gic>;
        };

for_each_matching_node_and_match(np, matches, &match) 
{
如果当前节点不是interrupt-controller或者处于disabled状态,则继续遍历
if (!of_find_property(np, "interrupt-controller", NULL) || !of_device_is_available(np))
                        continue;

如果当前节点是interrupt-controller,分配一个struct of_intc_desc的结构体并初始化。
desc = kzalloc(sizeof(*desc), GFP_KERNEL);
desc->irq_init_cb = match->data = gic_of_init;
desc->dev = of_node_get(np);

解析当前node的interrupt-parent, 如果是根中断控制器, 将interrupt_parent设为NULL
desc->interrupt_parent = of_irq_find_parent(np);
if (desc->interrupt_parent == np)
                        desc->interrupt_parent = NULL;

将该中断控制器加入intc_desc_list中
list_add_tail(&desc->list, &intc_desc_list);
}

while (!list_empty(&intc_desc_list)) 
{
找到root中断控制器
list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list)
{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值