Linux内核启动时跳过GIC分发器初始化的实现方法咨询
可行性说明
该需求完全可以实现,属于AMP异构多核架构下共享硬件资源分区使用的典型场景。无需修改Linux内核核心调度/中断框架,仅通过驱动层面的适配和配置即可完成,不需要完全删除irqchip_init()这类内核核心入口函数。
内核编译配置调整
- GIC相关配置:保留
CONFIG_ARM_GIC/CONFIG_ARM_GIC_V3(根据实际使用的GIC版本选择)基础上,关闭CONFIG_ARM_GIC_CONFIG_REGION_LOCK等会主动改写GIC全局配置的选项,无需使用的GIC虚拟化扩展配置也可全部关闭,避免Linux尝试修改GIC的全局控制寄存器。 - SMMU相关配置:保留
CONFIG_ARM_SMMU/CONFIG_ARM_SMMU_V3基础上,关闭CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT这类默认会改写SMMU全局控制寄存器的配置项。若使用5.15及以上版本主线内核,可直接开启CONFIG_ARM_SMMU_SKIP_INIT配置;低版本内核需要给SMMU驱动打极小编成补丁,识别设备树标记后跳过全局初始化流程即可。 - 通用AMP配置:开启
CONFIG_AMP、CONFIG_REMOTEPROC基础支持,关闭CONFIG_HOTPLUG_CPU中涉及非Linux核控制的相关选项,避免Linux尝试操作RTOS占用的核心的中断路由。
设备树对应配置
需要对共享硬件的节点新增自定义属性,明确限制Linux可用的资源范围:
GIC节点修改示例
gic@2c000000 { compatible = "arm,gic-v3"; reg = <0x0 0x2c000000 0 0x10000>, /* GICD 寄存器基地址 */ <0x0 0x2c040000 0 0x200000>; /* GICR 寄存器基地址 */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>; /* 自定义属性,驱动识别后直接跳过GIC全局初始化流程 */ skip-init; /* 明确Linux仅可使用SPI中断号32~127,剩余范围归属RTOS使用 */ linux,spi-irq-range = <32 127>; };
若内核原生GIC驱动不支持skip-init属性,仅需要在GIC驱动的probe函数开头加一行判断:if (of_property_read_bool(np, "skip-init")) return 0;即可,无需改动其他逻辑。
SMMU节点修改示例
smmu@2d000000 { compatible = "arm,smmu-v3"; reg = <0x0 0x2d000000 0 0x100000>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH 0>, <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH 0>; /* 自定义属性,驱动识别后跳过SMMU全局初始化 */ skip-init; /* 写死Linux可用的上下文Bank范围,剩余范围归属RTOS */ linux,context-bank-range = <0 3>; /* 提前定义好Linux侧设备的Stream ID映射关系,避免动态分配 */ iommu-map = <0 &smmu 0 0x10>; #iommu-cells = <1>; };
额外配置要求
在/chosen节点下通过mem参数明确限定Linux的可用内存范围,不要和RTOS的内存空间重叠;设备树中仅描述Linux运行的2个Cortex-A53核心,不要声明RTOS占用的另外2个核心,避免Linux尝试操作非归属核心。
相关实践参考
该方案已经在车载、工业控制领域的AMP场景有大量落地,比如NXP i.MX8系列、瑞萨R-Car系列的官方AMP参考设计中,均采用RTOS初始化安全域/共享外设、Linux仅使用非安全域资源的逻辑,核心实现思路和上述配置完全一致。
需要额外注意的点:共享中断的处理要做好域隔离,RTOS和Linux各用独立的中断号范围,不要交叉使用;GIC的中断亲和性配置要限制Linux仅能绑定自己运行的2个核心,禁止向RTOS核心发送中断。
内容的提问来源于stack exchange,提问作者yoyozi
相关产品推荐
相关产品推荐

