🤖 roboto_origin_03 Wiki
首页 / 固件 / 双内核编译与实时内核

RDK X5 镜像工程采用双内核并行构建策略,在同一构建流程中同时产出标准 Linux 内核与 PREEMPT_RT 实时内核。这种设计的核心目标是让同一套硬件平台既能运行通用的桌面/服务器工作负载,又能满足机器人控制、传感器融合等硬实时场景的确定性时序需求。本文档将从源码管理、补丁策略、编译流程、产物集成与启动切换五个维度,完整解析这一架构的实现机制与工程约束。

Sources: build.sh

双内核源码管理与补丁策略

双内核构建并非维护两套独立的源码仓库,而是采用基线复制 + 增量补丁的轻量级策略。标准内核源码位于 source/kernel,而实时内核源码 source/kernel-rt 仅在构建时动态生成:若该目录不存在,mk_kernel_rt.sh 会首先将标准内核源码完整复制到 source/kernel-rt,随后应用 PREEMPT_RT 补丁与产品级定制补丁。这种机制确保了两个内核的驱动基线、设备树和 Kconfig 选项在源头上保持一致,极大降低了维护分叉代码树的成本。对于 X5 平台,应用的补丁包括 patch-6.1.83-rt28.patchbuild_params/gs_usb.patch,前者将标准内核转换为完全可抢占的实时内核,后者将 GS_USB CAN 驱动的最大接口数从 3 扩展到 4,以适配 RDK 的 USB2CAN 外设需求。

Sources: mk_kernel_rt.sh

flowchart TD
    A[source/kernel<br/>标准内核基线] -->|cp -rf| B[source/kernel-rt<br/>实时内核工作区]
    C[patch-6.1.83-rt28.patch] -->|patch -p1| B
    D[gs_usb.patch] -->|patch -p1| B
    B --> E[make<br/>hobot_x5_rdk_ubuntu_rt_defconfig]
    E --> F[编译生成 Image-rt]

标准内核编译流程

标准内核的编译由 mk_kernel.sh 驱动,面向 X5 平台时,它锁定 hobot_x5_rdk_ubuntu_defconfig 配置与 6.1.83 内核版本,使用 gcc-arm-11.2-2022.02 交叉工具链进行 arm64 构建。脚本首先根据 CPU 核心数计算并行编译任务数(保留 2 个核心给系统),然后依次执行生成 .config、编译 Image dtbs、编译并安装内核模块、编译外部模块(bpu-hw_io)、执行 depmod 生成模块依赖、以及 strip 去除调试符号。最终产物包括 deploy/kernel/Imagedeploy/kernel/dtb/ 下的设备树文件,以及按版本号隔离的模块目录 deploy/kernel/modules/lib/modules/6.1.83/。脚本还通过 make_kernel_headers 函数提取内核头文件,为标准内核外部模块开发提供构建环境。

Sources: mk_kernel.sh mk_kernel.sh

实时内核编译流程

实时内核的编译由 mk_kernel_rt.sh 负责,其整体阶段与标准内核保持一致,但在四个关键点上存在差异。第一,源码目录与配置名称均带有 RT 标识:source/kernel-rthobot_x5_rdk_ubuntu_rt_defconfig。第二,版本号追加 -rt28 后缀,模块安装路径相应变为 lib/modules/6.1.83-rt28/,从而与标准内核模块完全隔离。第三,外部模块目录切换为 source/hobot-drivers/bpu-hw_io_rt,说明 BPU 硬件 IO 驱动针对实时内核做了专门的同步原语适配。第四,编译产物命名为 Image-rt 而非 Image,并在 make_kernel_headers 中将头文件目录标记为 linux-headers-6.1.83-rt,避免与标准内核头文件冲突。

Sources: mk_kernel_rt.sh mk_kernel_rt.sh

flowchart LR
    subgraph 标准内核
        A1[mk_kernel.sh] --> B1[source/kernel]
        B1 --> C1[Image]
        B1 --> D1[bpu-hw_io]
        C1 --> E1[6.1.83 模块]
    end
    subgraph 实时内核
        A2[mk_kernel_rt.sh] --> B2[source/kernel-rt]
        B2 --> C2[Image-rt]
        B2 --> D2[bpu-hw_io_rt]
        C2 --> E2[6.1.83-rt28 模块]
    end

构建产物与部署架构

两个内核的产物统一汇聚到 deploy/kernel/ 目录,形成如下部署结构:标准内核镜像 Image 与实时内核镜像 Image-rt 并列存放;设备树 dtb/ 与源码文件 *.dts/*.dtsi 共用一套输出(因为设备树未因 RT 补丁而改变);模块则按内核版本号分目录存储于 modules/lib/modules/ 下。这种结构使得后续打包阶段无需关心内核类型差异,只需按文件名规则拷贝即可。内核头文件方面,标准内核头文件位于 kernel_headers/usr/src/linux-headers-6.1.83/,而实时内核头文件位于 kernel_headers/usr/src/linux-headers-6.1.83-rt/,两者同时存在但路径隔离。

Sources: mk_kernel.sh mk_kernel_rt.sh

Deb 包集成与启动切换机制

mk_debs.sh 构建 hobot-boot Deb 包时,标准内核镜像 Image 与实时内核镜像 Image-rt 会被同时拷贝到包的 /boot 目录下,两个内核的模块也会被合并安装到包的 /lib/modules 下。这意味着用户通过 APT 安装或更新 hobot-boot 包时,系统中将同时存在两套可启动的内核。镜像打包阶段,pack_image.sh 针对 X5 平台执行了一个关键操作:读取 source/hobot-boot/debian/boot/boot.cmd 中的 U-Boot 启动脚本,将变量 imagefile="Image" 替换为 imagefile="Image-rt",然后重新生成 boot.scr 并写入根文件系统的 /boot 目录。这一设计使得出厂镜像默认以实时内核启动,用户若需回退到标准内核,只需反向修改 boot.scr 或在 U-Boot 命令行中覆盖 imagefile 变量即可。

Sources: mk_debs.sh pack_image.sh

sequenceDiagram
    participant 构建系统 as build.sh kernel
    participant 标准编译 as mk_kernel.sh
    participant 实时编译 as mk_kernel_rt.sh
    participant Deb包 as mk_debs.sh
    participant 镜像 as pack_image.sh
    participant 设备 as RDK X5

    构建系统->>标准编译: 编译标准内核
    构建系统->>实时编译: 编译实时内核
    标准编译-->>Deb包: 提供 Image + 模块
    实时编译-->>Deb包: 提供 Image-rt + 模块
    Deb包-->>镜像: hobot-boot.deb
    镜像->>镜像: 修改 boot.scr 指向 Image-rt
    镜像-->>设备: 烧录出厂镜像
    设备->>设备: U-Boot 加载 Image-rt 启动

标准内核与实时内核特性对比

下表从源码管理、配置、产物命名、外部模块与启动策略五个维度,对双内核进行系统性对比。

维度 标准内核 实时内核 (PREEMPT_RT)
构建脚本 mk_kernel.sh mk_kernel_rt.sh
源码目录 source/kernel source/kernel-rt(构建时从标准内核复制)
配置文件 hobot_x5_rdk_ubuntu_defconfig hobot_x5_rdk_ubuntu_rt_defconfig
内核版本 6.1.83 6.1.83-rt28
镜像文件名 Image Image-rt
模块路径 lib/modules/6.1.83/ lib/modules/6.1.83-rt28/
外部模块 bpu-hw_io bpu-hw_io_rt
附加补丁 patch-6.1.83-rt28.patch + gs_usb.patch
头文件目录 linux-headers-6.1.83 linux-headers-6.1.83-rt
出厂默认启动 否(作为备选) 是(通过 boot.scr 切换)

Sources: mk_kernel.sh mk_kernel_rt.sh

开发者操作指引

对于需要调整内核配置或切换内核的高级开发者,构建系统提供了直接操作入口。若需修改实时内核配置,可在 source/kernel-rt 目录下执行 bash mk_kernel_rt.sh menuconfig,脚本会先加载 hobot_x5_rdk_ubuntu_rt_defconfig,启动 menuconfig 交互界面,退出后自动通过 savedefconfig 将差异保存回 arch/arm64/configs/hobot_x5_rdk_ubuntu_rt_defconfig。若需在已烧录的设备上从实时内核回退到标准内核,可挂载 boot 分区后修改 boot.scr,或直接在 U-Boot 倒计时阶段打断自动启动,手动设置 setenv imagefile Image; boot。由于 hobot-boot Deb 包同时携带两套内核镜像,回退操作无需重新刷写整个系统。

Sources: mk_kernel_rt.sh pack_image.sh

关联阅读

理解双内核编译后,下一步可以深入了解整个构建流程的入口编排与依赖关系,请参阅 全量构建与子命令解析;若需研究 Deb 包的本地编译逻辑与自定义包集成方式,请参阅 Deb 包本地编译与依赖管理