logo
0
0
WeChat Login
cnb<cnb@cnb.local>
docs: 更新README.md

device_rockchip

一、 命令概述

执行命令:

./build.sh rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig

该命令完成两件事:

  • 选择芯片系列:rk3566_rk3568
  • 选择板级默认配置:LubanCat_rk3568_debian_lite_defconfig

最终产物为 RK3568 芯片 LubanCat 开发板的 Debian 12 (bookworm) lite 版本完整固件(update.img)。

二、 入口脚本分析

1. build.sh 软链接

build.sh 是一个软链接,指向:

build.sh -> device/rockchip/common/scripts/build.sh

主入口脚本为 build.sh,核心函数为 main()build.sh: 506)。

2. main() 整体流程

main() # build.sh:506 │ ├─ [阶段 0] 前置处理 │ ├─ Makefile 选项拦截 (make-*) # build.sh:509 │ ├─ 错误处理设置 (set -eE, trap ERR) # build.sh:515-516 │ └─ 保存初始环境变量 # build.sh:520-521 │ ├─ [阶段 1] 环境初始化 │ ├─ setup_environments() # build.sh:526 设置全局环境变量 │ ├─ setup_developer_environments() # build.sh:529 加载 devenv │ └─ check_sdk() # build.sh:557 检查 SDK 完整性 │ ├─ [阶段 2] 参数预处理 # build.sh:580-592 │ 输入: rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig │ 输出: chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig │ ├─ [阶段 3] INIT 阶段 # build.sh:665 │ └─ run_build_hooks init $OPTIONS → 生成 output/.config │ ├─ [阶段 4] 配置加载 # build.sh:674-727 │ ├─ source output/.config # 加载所有配置变量 │ ├─ kernel_version() # 确定实际内核版本 │ ├─ 自定义环境变量检测与覆盖 # build.sh:681-717 │ └─ partition-helper # 解析分区表 │ ├─ [阶段 5] PRE-BUILD 阶段 # build.sh:783 │ └─ run_build_hooks pre-build $OPTIONS # 子模块配置(可选) │ ├─ [阶段 6] BUILD 阶段 # build.sh:786 │ └─ run_build_hooks build $OPTIONS # 实际编译(kernel, rootfs, loader) │ └─ [阶段 7] POST-BUILD 阶段 # build.sh:789 └─ run_build_hooks post-build $OPTIONS # 固件打包(firmware, update.img)

注意:对于纯配置命令(如 chip:defconfig 格式),执行完 INIT 阶段 后即返回,不会继续后续的 pre-build / build / post-build 阶段(build.sh: 669-671)。

3. 参数预处理逻辑

build.sh: 582-592 中,命令参数被自动预处理:

# 遍历所有选项参数 for opt in $OPTIONS; do # 如果参数是 .chips/ 下已有的目录名,添加 "chip:" 前缀 if [ -d "$RK_CHIPS_DIR/${opt%%:*}" ]; then # rk3566_rk3568:xxx → chip:rk3566_rk3568:xxx # 如果参数匹配 *_defconfig 模式,添加 "defconfig:" 前缀 elif echo "$opt" | grep -q "^[0-9a-z_]*_defconfig$"; then # xxx_defconfig → defconfig:xxx_defconfig fi done

在前后加打印是这样的:

OPTIONS=rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig OPTIONS=chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig

4. 全局环境变量

setup_environments()build.sh: 379-420)定义了构建系统所需的所有关键路径变量:

变量说明
RK_SDK_DIR/root/rk356x_devSDK 根目录
RK_DEVICE_DIR$SDK/device/rockchip设备目录
RK_CHIPS_DIR$DEVICE/.chips芯片配置集合
RK_CHIP_DIR$DEVICE/.chip当前芯片(软链接)
RK_COMMON_DIR$DEVICE/common公共脚本/配置
RK_CONFIG_IN$COMMON/configs/Config.inKConfig 主文件
RK_CONFIGoutput/.config最终输出配置
RK_OUTDIRoutput/输出根目录
RK_FIRMWARE_DIRoutput/firmware/固件输出目录
RK_BUILD_HOOK_DIRbuild-hooks构建钩子目录
RK_DEFCONFIG_LINKoutput/defconfigdefconfig 软链接

我们直接函数里加打印:

# ----- 打印所有变量 ----- echo "======== Exported variables ========" echo "LC_ALL=$LC_ALL" echo "RK_SCRIPTS_DIR=$RK_SCRIPTS_DIR" echo "RK_COMMON_DIR=$RK_COMMON_DIR" echo "RK_SDK_DIR=$RK_SDK_DIR" echo "RK_DEVICE_DIR=$RK_DEVICE_DIR" echo "RK_CHIPS_DIR=$RK_CHIPS_DIR" echo "RK_CHIP_DIR=$RK_CHIP_DIR" echo "RK_CHIP_SCRIPTS_DIR=$RK_CHIP_SCRIPTS_DIR" echo "RK_DEFAULT_TARGET=$RK_DEFAULT_TARGET" echo "RK_DATA_DIR=$RK_DATA_DIR" echo "RK_TOOLS_DIR=$RK_TOOLS_DIR" echo "RK_EXTRA_PARTS_DIR=$RK_EXTRA_PARTS_DIR" echo "RK_KBUILD_DIR=$RK_KBUILD_DIR" echo "RK_CONFIG_IN=$RK_CONFIG_IN" echo "RK_BUILD_HOOK_DIR=$RK_BUILD_HOOK_DIR" echo "RK_POST_HOOK_DIR=$RK_POST_HOOK_DIR" echo "RK_BUILD_HELPER=$RK_BUILD_HELPER" echo "RK_POST_HELPER=$RK_POST_HELPER" echo "RK_PARTITION_HELPER=$RK_PARTITION_HELPER" echo "RK_OUTDIR=$RK_OUTDIR" echo "RK_EXTRA_PART_OUTDIR=$RK_EXTRA_PART_OUTDIR" echo "RK_SESSION_DIR=$RK_SESSION_DIR" echo "RK_SESSION=$RK_SESSION" echo "RK_LOG_DIR=$RK_LOG_DIR" echo "RK_LOG_BASE_DIR=$RK_LOG_BASE_DIR" echo "RK_ROCKDEV_DIR=$RK_ROCKDEV_DIR" echo "RK_FIRMWARE_DIR=$RK_FIRMWARE_DIR" echo "RK_CONFIG=$RK_CONFIG" echo "RK_DEFCONFIG_LINK=$RK_DEFCONFIG_LINK" echo "RK_OWNER=$RK_OWNER" echo "RK_OWNER_UID=$RK_OWNER_UID" echo "RK_PARSED_CMDS=$RK_PARSED_CMDS" echo "RK_MAKE_USAGE=$RK_MAKE_USAGE" echo "===================================="

就可以看到:

# ./build.sh rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig ======== Exported variables ======== LC_ALL=C RK_SCRIPTS_DIR=/root/rk356x_dev/device/rockchip/common/scripts RK_COMMON_DIR=/root/rk356x_dev/device/rockchip/common RK_SDK_DIR=/root/rk356x_dev RK_DEVICE_DIR=/root/rk356x_dev/device/rockchip RK_CHIPS_DIR=/root/rk356x_dev/device/rockchip/.chips RK_CHIP_DIR=/root/rk356x_dev/device/rockchip/.chip RK_CHIP_SCRIPTS_DIR=/root/rk356x_dev/device/rockchip/.chip/scripts RK_DEFAULT_TARGET=all RK_DATA_DIR=/root/rk356x_dev/device/rockchip/common/data RK_TOOLS_DIR=/root/rk356x_dev/device/rockchip/common/tools RK_EXTRA_PARTS_DIR=/root/rk356x_dev/device/rockchip/common/extra-parts RK_KBUILD_DIR=/root/rk356x_dev/device/rockchip/common/linux-kbuild RK_CONFIG_IN=/root/rk356x_dev/device/rockchip/common/configs/Config.in RK_BUILD_HOOK_DIR=build-hooks RK_POST_HOOK_DIR=post-hooks RK_BUILD_HELPER=/root/rk356x_dev/device/rockchip/common/scripts/build-helper RK_POST_HELPER=/root/rk356x_dev/device/rockchip/common/scripts/post-helper RK_PARTITION_HELPER=/root/rk356x_dev/device/rockchip/common/scripts/partition-helper RK_OUTDIR=/root/rk356x_dev/output RK_EXTRA_PART_OUTDIR=/root/rk356x_dev/output/extra-parts RK_SESSION_DIR=/root/rk356x_dev/output/sessions RK_SESSION=2026-04-11_17-50-18 RK_LOG_DIR=/root/rk356x_dev/output/sessions/2026-04-11_17-50-18 RK_LOG_BASE_DIR=/root/rk356x_dev/output/log RK_ROCKDEV_DIR=/root/rk356x_dev/rockdev RK_FIRMWARE_DIR=/root/rk356x_dev/output/firmware RK_CONFIG=/root/rk356x_dev/output/.config RK_DEFCONFIG_LINK=/root/rk356x_dev/output/defconfig RK_OWNER=root RK_OWNER_UID=0 RK_PARSED_CMDS=/root/rk356x_dev/output/.parsed_cmds RK_MAKE_USAGE=/root/rk356x_dev/output/.make_usage

三、 Hook 调度机制

1. 核心调度函数

构建系统采用 Hook 调度模式,核心调度链为:

run_build_hooks() # build.sh:344 └─ run_hooks() # build.sh:328 └─ do_run_hooks() # build.sh:308 └─ 遍历执行 $HOOK_DIR/*.sh # 按文件名排序

run_build_hooks()build.sh: 703这里被调用一次:

run_build_hooks init $OPTIONS

2. Hook 目录优先级

每次调用 run_hooks() 时,按以下优先级遍历两个目录(build.sh: 336-339):

优先级高: ./.chip/scripts/ # 芯片专用钩子 优先级低: ./common/build-hooks/ # 公共钩子

对于 usage 阶段则相反:公共目录优先,芯片目录在后(build.sh: 332-333)。

3. Hook 执行过滤

每个 hook 脚本通过声明自己支持的命令来决定是否被执行(build.sh: 288-305):

# 各脚本声明的支持命令: INIT_CMDS="chip defconfig lunch *_defconfig olddefconfig savedefconfig menuconfig config default" PRE_BUILD_CMDS="kernel-config kconfig kernel-make kmake buildroot-config bconfig buildroot-make bmake" BUILD_CMDS="kernel-* kernel recovery-kernel modules rootfs buildroot debian ubuntu yocto loader uboot" POST_BUILD_CMDS="linux-headers buildroot-sdk bsdk"

4. 各 Hook 脚本职责

脚本INIT 阶段PRE-BUILD 阶段BUILD 阶段POST-BUILD 阶段
00-config.sh芯片选择、defconfig 切换、KConfig 触发---
10-kernel.sh内核版本选择、创建 kernel 软链接内核 menuconfig/make内核编译 + extbootlinux-headers 打包
30-rootfs.shrootfs 类型确认Buildroot 配置/编译Debian/Ubuntu/Buildroot/Yocto 构建Buildroot SDK 打包
70-loader.sh--U-Boot 编译和镜像打包-

四、 INIT 阶段详细分析

1. 总体调用链

run_build_hooks init "chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig" │ ├─ [.chip/scripts/] (芯片钩子,优先执行) │ └─ (无芯片专用 init 钩子) │ └─ [common/build-hooks/] (公共钩子) │ ├─ [00-config.sh]────────────────────────────────────────────┐ │ init_hook("chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig") # L170 │ │ │ │ ├─ case 匹配到 "chip" # L173 │ │ ├─ shift # 移除 "chip" │ │ └─ choose_chip("rk3566_rk3568" "LubanCat_rk3568_debian_lite_defconfig") # L65 │ │ │ │ │ │ ├─ 在 .chips/ 目录中查找匹配 "rk3566_rk3568" 的项 # L67 │ │ ├─ CHIP = "rk3566_rk3568" # L75 (唯一匹配) │ │ ├─ ln -rsf .chips/rk3566_rk3568 .chip # L96 创建芯片软链接 │ │ └─ choose_defconfig("LubanCat_rk3568_debian_lite_defconfig") # L98 │ │ │ # L32 │ │ ├─ 列出 .chip/ 下所有 *_defconfig 文件 # L34 │ │ ├─ 精确匹配到 LubanCat_rk3568_debian_lite_defconfig # L45 │ │ └─ switch_defconfig("LubanCat_rk3568_debian_lite_defconfig") # L62 │ │ │ # L3 │ │ ├─ DEFCONFIG = .chip/LubanCat_rk3568_debian_lite_defconfig # L7 │ │ ├─ ln -rsf $DEFCONFIG output/defconfig # L16 创建 defconfig 软链接 │ │ ├─ 更新 .chip 软链接指向 defconfig 所在目录 # L19-20 │ │ └─ make LubanCat_rk3568_debian_lite_defconfig # L22 ← KConfig! │ │ │ │ └─ source build-helper # L190 │ │ ├─ [10-kernel.sh]───────────────────────────────────────────┐ │ init_hook("default") # L426 │ │ │ │ ├─ load_config RK_KERNEL_CFG # L427 (从 .config 读取) │ ├─ KERNEL_LAST = cat output/.kernel # L430 (上次选择的版本) │ ├─ KERNEL_CURRENT = kernel_version() # L31 (当前软链接指向) │ ├─ load_config RK_KERNEL_PREFERRED # L433 → "6.1" │ │ │ │ ├─ [版本选择优先级判断] # L436-454 │ │ ① 命令行参数? → 否(传入的是 default) │ │ ② 环境变量 RK_KERNEL_VERSION? → 否 │ │ ③ 上次选择的版本? → 否(.kernel 不存在或为空) │ │ ④ RK_KERNEL_PREFERRED("6.1")? → ✓ 使用此项 # L446 │ │ │ │ ├─ RK_KERNEL_VERSION = "6.1" # L446 │ ├─ 对比 KERNEL_CURRENT != "6.1"? # L459 │ │ └─ rm kernel; ln -rsf kernel-6.1 kernel # L469-470 创建内核软链接 │ │ │ │ └─ source build-helper # L585 │ │ └─ [30-rootfs.sh]──────────────────────────────────────────┐ init_hook("default") # L305 │ │ ├─ load_config RK_ROOTFS # L307 ├─ check_config RK_ROOTFS → 失败(尚未配置) → return 0 # L308 └─ (无操作,rootfs 类型由 defconfig 中的隐含值决定) │ │ output/.config 已生成 ✓

2. switch_defconfig() 函数详解

位置:00-config.sh: 3-23

switch_defconfig() { DEFCONFIG="$1" # 如果传入的是相对路径,尝试在芯片目录下查找 [ -f "$DEFCONFIG" ] || DEFCONFIG="$RK_CHIP_DIR/$DEFCONFIG" # 校验文件存在性 [ -f "$DEFCONFIG" ] || { error "No such defconfig"; exit 1; } # 操作 1: 创建 output/defconfig 软链接指向目标 defconfig rm -f "$RK_DEFCONFIG_LINK" ln -rsf "$DEFCONFIG" "$RK_DEFCONFIG_LINK" # 操作 2: 更新 .chip 软链接指向 defconfig 所在目录 DEFCONFIG="$(realpath "$DEFCONFIG")" rm -rf "$RK_CHIP_DIR" ln -rsf "$(dirname "$DEFCONFIG")" "$RK_CHIP_DIR" # 操作 3: 执行 make 触发 KConfig 配置系统 make $(basename "$DEFCONFIG") }

3. prepare_config() 函数详解

位置:00-config.sh: 101-147

init_hook 接收到 default 命令时(即非首次配置后的重复运行),会调用此函数进行增量配置检查:

prepare_config() │ ├─ .chip 软链接不存在? → choose_chip() # 完整交互式选择芯片 │ ├─ output/defconfig 不存在? → choose_defconfig() │ ├─ defconfig 与 .chip 目录不匹配? → choose_defconfig() │ ├─ output/.config 比 defconfig 更旧? → make $defconfig # 重新生成 │ ├─ Config.in 文件比 .config 更新? → make $defconfig # 重新生成 │ ├─ .config 中 RK_DEFCONFIG 不匹配? → make $defconfig # 重新生成 │ └─ .config 有变动? → make olddefconfig # 同步更新

五、 Makefile Kconfig 配置系统

1. 配置入口

顶层 Makefile 定义了 %_defconfig 目标规则(Makefile: 143-146):

%_defconfig: $(BUILD_DIR)/conf $(CHIP_DIR)/%_defconfig $(Q)$(COMMON_CONFIG_ENV) $< --defconfig=$(CHIP_DIR)/$@ $(CONFIG_CONFIG_IN)

switch_defconfig() 执行 make LubanCat_rk3568_debian_lite_defconfig 时,触发过程如下:

make LubanCat_rk3568_debian_lite_defconfig │ ├─ TARGET_DEFCONFIG = "LubanCat_rk3568_debian_lite_defconfig" # Makefile:108 ├─ DEFCONFIG = realpath(.chip/LubanCat_rk3568_debian_lite_defconfig) # Makefile:116 ├─ DEFCONFIG_NAME = "LubanCat_rk3568_debian_lite_defconfig" # Makefile:117 │ ├─ 自动推导: │ RK_CHIP_FAMILY = basename(realpath(.chip)) = "rk3566_rk3568" # Makefile:120 │ RK_CHIP = cut -d'_' -f2 = "rk3568" # Makefile:121-122 │ ├─ COMMON_CONFIG_ENV 设置环境变量: # Makefile:124-131 │ RK_DEFCONFIG, RK_CHIP_FAMILY, RK_CHIP, │ KCONFIG_AUTOCONFIG, KCONFIG_AUTOHEADER, KCONFIG_TRISTATE, │ srctree, RK_CONFIG │ └─ 执行: output/kconf/conf --defconfig=.chip/LubanCat... Config.in │ ├─ 读取输入 defconfig: .chip/LubanCat_rk3568_debian_lite_defconfig ├─ 解析 KConfig 主文件: common/configs/Config.in │ ├── Config.in.rootfs (根文件系统: buildroot/debian/ubuntu/yocto) │ ├── Config.in.loader (U-Boot 配置) │ ├── Config.in.kernel (内核配置) │ ├── Config.in.boot (启动镜像配置) │ ├── Config.in.recovery (Recovery 配置) │ ├── Config.in.security (安全配置) │ ├── Config.in.extra-parts (额外分区) │ ├── Config.in.firmware (固件打包) │ ├── Config.in.update (升级配置) │ └── Config.in.others (其他配置) │ └─ 输出: output/.config (完整的 SDK 配置文件)

2. 输入 defconfig 内容

LubanCat_rk3568_debian_lite_defconfig 是一个最小化配置片段,仅包含用户自定义的关键选项:

# RK_BUILDROOT is not set ← 非 Buildroot 系统 # RK_YOCTO is not set ← 非 Yocto 系统 RK_ROOTFS_TARGET_LITE=y ← 目标变体: lite (轻量版) RK_ROOTFS_IMAGE="linaro-rk356x-${RK_ROOTFS_TARGET}-rootfs.img" ← 镜像名模板 RK_KERNEL_PREFERRED="6.1" ← 偏好内核版本 RK_KERNEL_CFG="lubancat_linux_rk356x_defconfig" ← 内核 defconfig RK_KERNEL_DTS_NAME="rk356x-lubancat-generic" ← 设备树名称 RK_KERNEL_EXTBOOT=y ← 启用扩展启动分区 # RK_RECOVERY is not set ← 无 Recovery RK_EXTRA_PARTITION_NUM=0 ← 无额外分区 RK_PARAMETER="parameter-extboot.txt" ← 分区表文件 RK_USE_FIT_IMG=y ← 使用 FIT 格式镜像 RK_PACKAGE_FILE_CUSTOM=y ← 自定义打包清单 RK_PACKAGE_FILE="package-file-extboot" ← 打包清单名称

3. KConfig 关键推导逻辑

KConfig 系统根据上述最小配置 + Config.in 中的依赖关系,自动推导出完整配置。关键推导链如下:

3.1 芯片信息推导

# Config.in (自动推导) RK_CHIP_FAMILY = "rk3566_rk3568" # 来自 Makefile 的 basename(.chip) RK_CHIP = "rk3568" # 来自 defconfig 名称的第 2 段 RK_CHIP_ARM32 = n # rk3566_rk3568 不在 ARM32 列表中 RK_CHIP_HAS_GPU = y # rk3566_rk3568 有 GPU

3.2 根文件系统推导

# Config.in.rootfs → Config.in.debian # 因为 RK_BUILDROOT=n 且 RK_YOCTO=n 且 RK_DEBIAN_SUPPORTS=y: RK_DEBIAN_BOOKWORM = y # 默认选中 bookworm (Debian 12) RK_DEBIAN_VERSION = "bookworm" # Config.in.debian:27 RK_DEBIAN_NUMBER = "debian12" # Config.in.debian:33 RK_DEBIAN_ARCH = "arm64" # 默认 arm64 (非 ARM32 芯片) RK_DEBIAN_MIRROR = "mirrors.ustc.edu.cn" RK_ROOTFS_SYSTEM = "debian" # 隐含: 非 buildroot/yocto → debian RK_ROOTFS_TARGET = "lite" # 来自 defconfig: RK_ROOTFS_TARGET_LITE=y RK_ROOTFS_IMAGE = "linaro-rk356x-lite-rootfs.img" # 变量展开结果

3.3 内核配置推导

# Config.in.kernel RK_KERNEL = y # 默认启用 (depends on RK_LOADER) RK_KERNEL_ARCH = "arm64" # RK_KERNEL_ARM64 = y (非 ARM32 芯片) RK_KERNEL_CFG = "lubancat_linux_rk356x_defconfig" # 来自 defconfig RK_KERNEL_DTS_NAME = "rk356x-lubancat-generic" # 来自 defconfig RK_KERNEL_EXTBOOT = "y" # 来自 defconfig RK_KERNEL_IMG = "kernel/arch/arm64/boot/Image" # arm64 非压缩默认 RK_KERNEL_DTS_DIR = "kernel/arch/arm64/boot/dts/rockchip" RK_KERNEL_DTB = "kernel/arch/arm64/boot/dts/rockchip/rk356x-lubancat-generic.dtb"

3.4 U-Boot 配置推导

# Config.in.loader RK_LOADER = y # 默认启用 RK_UBOOT_CFG = "rk3568" # default RK_CHIP (Config.in.loader:20) # rk3566_rk3568 不匹配任何特殊规则 RK_UBOOT_ARCH = "arm64" # 继承内核架构 RK_UBOOT_ARM64 = y

4. 最终生成的 output/.config 关键项汇总

配置项来源
RK_DEFCONFIGLubanCat_rk3568_debian_lite_defconfigdefconfig 文件名
RK_CHIP_FAMILYrk3566_rk3568Makefile 自动推导
RK_CHIPrk3568Makefile 从文件名提取
RK_ROOTFS_SYSTEMdebian隐含推导(非 buildroot/yocto)
RK_ROOTFS_TARGETlitedefconfig 中指定
RK_DEBIAN_VERSIONbookwormConfig.in.debian 默认值
RK_DEBIAN_NUMBERdebian12KConfig 推导
RK_KERNEL_PREFERRED6.1defconfig 中指定
RK_KERNEL_CFGlubancat_linux_rk356x_defconfigdefconfig 中指定
RK_KERNEL_DTS_NAMErk356x-lubancat-genericdefconfig 中指定
RK_KERNEL_EXTBOOTydefconfig 中指定
RK_UBOOT_CFGrk3568Config.in.loader 推导
RK_PARAMETERparameter-extboot.txtdefconfig 中指定
RK_USE_FIT_IMGydefconfig 中指定

六、 Kernel(内核)配置分析

1. 基本信息

项目
内核版本6.1
源码目录kernel-6.1/
软链接kernelkernel-6.1
架构arm64 (aarch64)
内核 defconfiglubancat_linux_rk356x_defconfig
设备树rk356x-lubancat-generic.dts

2. 内核版本选择逻辑

10-kernel.sh::init_hook() (10-kernel.sh: 425-471) 中的版本选择优先级:

优先级从高到低: ┌─────────────────────────────────────────────────────┐ │ 1. 命令行参数 │ │ 如: ./build.sh kernel-6.1 │ │ → export RK_KERNEL_VERSION=${1#kernel-} │ │ │ │ 2. 环境变量 RK_KERNEL_VERSION │ │ 如: RK_KERNEL_VERSION=5.10 ./build.sh │ │ │ │ 3. 上次选择的版本 │ │ 读取 output/.kernel 文件 │ │ │ │ 4. RK_KERNEL_PREFERRED (defconfig 中定义) ← 本次使用 │ │ 值 = "6.1" │ │ │ │ 5. 当前软链接指向的版本 │ │ kernel → kernel-X.X (basename 解析) │ │ │ │ 6. 默认回退 │ │ RK_KERNEL_VERSION=5.10 │ └─────────────────────────────────────────────────────┘

选定版本后,如果与当前 kernel 软链接指向不一致,则更新软链接:

# 10-kernel.sh:462-470 KERNEL_DIR=kernel-$RK_KERNEL_VERSION # → kernel-6.1 rm -rf kernel ln -rsf kernel-6.1 kernel # 创建/更新软链接

3. 交叉编译工具链

通过 kernel-helper 脚本设置编译环境:

# kernel-helper:21 export RK_KERNEL_TOOLCHAIN="$(get_toolchain kernel "$RK_KERNEL_ARCH")" # get_toolchain() 搜索路径 (build.sh:161-203): # prebuilts/gcc/linux-x86/aarch64/ # 匹配模式: aarch64-linux-[^-]*-gcc # kernel-helper:24-25 export KMAKE="make -C kernel/ -j$((nproc+1)) \ CROSS_COMPILE=$RK_KERNEL_TOOLCHAIN ARCH=$RK_KERNEL_ARCH"

工具链详情

项目
前缀aarch64-none-linux-gnu-
GCC 版本10.3-2021.07
搜索目录prebuilts/gcc/linux-x86/aarch64/
完整路径示例prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc

4. 内核编译流程(BUILD 阶段)

当执行 ./build.sh all./build.sh kernel 时:

10-kernel.sh::build_hook("kernel") │ ├─ check_config RK_KERNEL RK_KERNEL_CFG # 校验必要配置存在 ├─ source kernel-helper # 设置工具链和 KMAKE │ └─ do_build("kernel") # [10-kernel.sh:119] │ ├─ make_kernel_config() # [10-kernel.sh:34] │ └─ do_make_kernel_config() # [10-kernel.sh:5] │ ├─ 搜索可能的 config fragments: │ │ Possible = "rk3566_rk3568 rk3568" │ │ 匹配: rk3566_rk3568.config, rk3566_rk3568_linux.config, │ │ rk3568.config, rk358_linux.config │ └─ $KMAKE lubancat_linux_rk356x_defconfig <fragments> │ # 实际等价于: │ # make -C kernel/ -jN CROSS_COMPILE=aarch64-... ARCH=arm64 │ # lubancat_linux_rk356x_defconfig │ ├─ check-kernel.sh # 编译前环境检查 │ ├─ [因为 RK_KERNEL_EXTBOOT=y]: # [10-kernel.sh:159] │ ├─ [Debian/Ubuntu 系统]: │ │ └─ do_build_kerneldeb() # 编译 linux-headers/image deb 包 │ │ └─ $KMAKE bindeb-pkg │ │ │ └─ do_build_extboot() # [10-kernel.sh:52] ★ 核心 │ ├─ $KMAKE rk356x-lubancat-generic.img # 编译 FIT 镜像 │ ├─ $KMAKE dtbs # 编译设备树 │ │ │ ├─ 构建 extboot 目录结构: │ │ │ kernel/extboot/ │ │ │ ├── Image-6.1.x │ 内核镜像 │ │ ├── config-6.1.x │ 内核配置备份 │ │ ├── System.map-6.1.x │ 符号表 │ │ ├── logo.bmp / logo_kernel.bmp │ 启动 Logo │ │ ├── boot.scr │ U-Boot 启动脚本 │ │ ├── initrd-6.1 │ 初始 ramdisk │ │ ├── rk-kernel.dtb │ 默认 DTB │ │ ├── dtb/ │ 所有 DTB 文件 │ │ │ ├── *.dtb │ │ │ └── overlay/*.dtbo │ 设备树叠加 │ │ ├── extlinux/extlinux.conf │ Extlinux 引导配置 │ │ ├── uEnv/ │ U-Boot 环境变量 │ │ │ ├── uEnv.txt │ │ │ └── rk356x/*.txt │ 板级特定配置 │ │ └── kerneldeb/ │ Deb 包 │ │ ├── linux-headers-*.deb │ │ └── linux-image-*.deb │ │ │ ├─ mkfs.ext2 -F -L "boot" -d extboot/ extboot.img # 打包 128MB ext2 │ └─ ln -rsf extboot.img output/firmware/boot.img │ └─ finish_build build_kernel

5. 内核 defconfig 特性概要

lubancat_linux_rk356x_defconfig(约 987 行)包含的主要模块类别:

类别主要特性
架构基础ARM64, Rockchip SoC, 最多 8 核, 300Hz 定时器
网络netfilter/nftables, bridge, VLAN, CAN, Bluetooth
WiFi 驱动MT76xx, RTL88xx, RTW88/89, MWIFIEX, Broadcom
以太网STMMAC + Motorcomm/Realtek/Rockchip PHY
存储SATA AHCI, NVMe, MTD (SPI NAND/NOR, UBI), MMC/SDHCI
GPU/显示Rockchip DRM (DP, HDMI, MIPI DSI, LVDS), Mali
多媒体Rockchip MPP (VDPU, VEPU, RKVDEC, RKVENC, AV1DEC)
音频I2S/TDM, PDM, SAI, SPDIF, 多种 codec
USBDWC3, DWC2, gadget, Type-C
文件系统ext4, XFS, BTRFS, UBIFS, SquashFS, NFS, NTFS3, FUSE

6. Kernel 目录最终 Make 命令详解

本节汇总在 kernel/ 目录(即 kernel-6.1/)中最终执行的完整 make 命令。所有命令均由 KMAKE 变量展开而来:

# KMAKE 变量定义 (kernel-helper:24-25) export KMAKE="make -C kernel/ -j$((nproc+1)) \ CROSS_COMPILE=$RK_KERNEL_TOOLCHAIN ARCH=$RK_KERNEL_ARCH" # 展开后的实际形式: # make -C /root/rk356x_dev/kernel/ -j<N+1> \ # CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64

6.1 配置阶段:defconfig 加载

调用位置10-kernel.sh: do_make_kernel_config()

执行的 make 命令

make -C kernel/ -j$(nproc+1) \ CROSS_COMPILE=aarch64-none-linux-gnu- \ ARCH=arm64 \ lubancat_linux_rk356x_defconfig \ <config_fragments>

参数含义

  • -C kernel/:指定内核源码目录(kernel/ 是指向 kernel-6.1/ 的软链接)
  • -j$(nproc+1):并行编译,线程数为 CPU 核心数 + 1
  • CROSS_COMPILE=aarch64-none-linux-gnu-:交叉编译工具链前缀
  • ARCH=arm64:目标架构为 ARM64
  • lubancat_linux_rk356x_defconfig:内核默认配置文件(来自 RK_KERNEL_CFG
  • <config_fragments>:芯片相关的配置片段(自动检测),可能包括:
    • rk3566_rk3568.config
    • rk3566_rk3568_linux.config
    • rk3568.config
    • rk3568_linux.config

作用】

该命令将 defconfig 和 config fragments 合并,生成内核最终的 .config 配置文件(位于 kernel/.config)。

6.2 编译阶段:FIT 镜像构建

调用位置10-kernel.sh: do_build_extboot()

执行的 make 命令

make -C kernel/ -j$(nproc+1) \ CROSS_COMPILE=aarch64-none-linux-gnu- \ ARCH=arm64 \ rk356x-lubancat-generic.img

参数含义

  • rk356x-lubancat-generic.img:目标名为设备树名称 + .img 后缀(来自 RK_KERNEL_DTS_NAME

【**作用】】

该命令触发内核构建系统完成以下工作:

  1. 编译内核源码,生成 vmlinuxImage(内核镜像)
  2. 编译指定的设备树源文件(.dts.dtb
  3. 使用 mkimage 工具将 Image + .dtb 打包为 FIT 格式镜像.img

6.3 设备树编译

调用位置10-kernel.sh: do_build_extboot()

执行的 make 命令

make -C kernel/ -j$(nproc+1) \ CROSS_COMPILE=aarch64-none-linux-gnu- \ ARCH=arm64 \ dtbs

作用】

编译内核源码树中的所有设备树文件(.dts.dtb),输出到 kernel/arch/arm64/boot/dts/rockchip/ 目录。产物包括:

  • 主 DTB 文件(如 rk356x-lubancat-generic.dtb
  • 设备树叠加文件(overlay/*.dtbo

6.4 Deb 包编译(Debian/Ubuntu 系统)

调用位置10-kernel.sh: do_build_kerneldeb()

执行的 make 命令

make -C kernel/ -j$(nproc+1) \ CROSS_COMPILE=aarch64-none-linux-gnu- \ ARCH=arm64 \ bindeb-pkg \ KDEB_PKG_VERSION=<kernel_version>

作用】

将内核打包为 Debian 软件包格式(.deb),生成的产物包括:

  • linux-image-<version>_<version>_arm64.deb:内核镜像包
  • linux-headers-<version>_<version>_arm64.deb:内核头文件包

这些 deb 包会被复制到 kernel/extboot/kerneldeb/ 目录,用于后续打包到 extboot 分区镜像中。

6.5 其他常用 Kernel Make 目标

目标完整命令示例说明
menuconfig$KMAKE menuconfig图形化内核配置界面
savedefconfig$KMAKE savedefconfig将当前配置精简保存为 defconfig
modules$KMAKE modules仅编译内核模块
modules_install$KMAKE modules_install INSTALL_MOD_PATH=<dir>安装内核模块到指定目录
clean$KMAKE clean清除编译产物(保留配置)
distclean$KMAKE distclean完全清除(包括配置)

6.6 完整 Kernel 编译命令序列总结

当执行 ./build.sh kernel 时,按以下顺序依次执行 make 命令:

# Step 1: 加载 defconfig 配置 make -C kernel/ -jN CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64 \ lubancat_linux_rk356x_defconfig [<fragments>] # Step 2: 编译 linux-headers/image deb 包(仅 Debian/Ubuntu 且启用 extboot) make -C kernel/ -jN CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64 bindeb-pkg # Step 3: 编译 FIT 镜像(内核 Image + DTB 打包) make -C kernel/ -jN CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64 \ rk356x-lubancat-generic.img # Step 4: 编译全部设备树 make -C kernel/ -jN CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=arm64 dtbs

七、 Rootfs(根文件系统)配置分析

1. 基本信息

项目
类型Debian 12 (bookworm) lite
构建目录debian12/
目标架构arm64 (RK_DEBIAN_ARCH)
镜像格式ext4
镜像名称linaro-rk356x-lite-rootfs.img
输出路径output/debian/rootfs.ext4

2. 构建方式特点

Debian 根文件系统的构建 不使用传统的交叉编译工具链,而是采用 debootstrap + QEMU user-static chroot 方式:

阶段工具说明
基础系统构建debootstrap + live-build在 x86 主机上下载并创建 Debian arm64 基础系统
系统定制qemu-user-static + chroot在主机上模拟 arm64 环境执行原生包安装
镜像打包mkfs.ext4 -d将目录结构打包为 ext4 镜像

关键区别:Kernel 和 U-Boot 使用交叉编译器在 x86 主机上直接生成 arm64 二进制;而 Debian rootfs 通过 debootstrap 下载预编译包 + QEMU 模拟执行的方式构建,等效于在真实 arm64 环境中操作。

3. 构建决策流程

30-rootfs.sh:: build_debian() 的决策逻辑:

build_debian() │ ├─ 检查 $RK_ROOTFS_IMAGE 是否已存在? # 如 linaro-rk356x-lite-rootfs.img │ ├── 存在 → 直接软链接到 output/debian/rootfs.ext4,跳过构建 │ └── 不存在 ↓ │ ├─ 检查 linaro-*-rootfs.img 是否已存在? │ ├── 存在 → 软链接使用,跳过构建 │ └── 不存在 ↓ │ └─ 完整构建流程: │ ├─ [步骤 1] mk-base-debian.sh # 生成基础 tarball │ cd debian12/ │ RELEASE=bookworm TARGET=lite ARCH=arm64 ./mk-base-debian.sh │ └→ live-build (debootstrap) │ → 生成: linaro-bookworm-lite-arm64-alip-*.tar.gz │ ├─ [步骤 2] mk-rootfs.sh → mk-bookworm-rootfs.sh # 定制根文件系统 │ RELEASE=bookworm TARGET=lite ARCH=arm64 \ │ RK_ROOTFS_IMAGE=linaro-rk356x-lite-rootfs.img SOC=rk3568 \ │ ./mk-rootfs.sh │ │ │ ├─ 解压基础 tarball 到 binary/ 目录 │ ├─ 复制 overlay/ 文件: │ │ ├── fstab (文件系统挂载表) │ │ ├── systemd 服务配置 │ │ ├── udev 规则 │ │ ├── 网络配置 │ │ └── 其他系统配置 │ ├─ 复制 overlay-firmware/ 固件文件 │ ├─ 复制 packages/arm64/ 预编译 deb 包 │ └─ chroot 到 arm64 环境 (via qemu-aarch64-static): │ ├─ apt-get install 安装基础软件包 │ ├─ 安装 Rockchip 专有组件: │ │ ├── libmali (Mali GPU 驱动) │ │ ├── mpp (多媒体处理平台) │ │ ├── rga (2D 图形加速) │ │ ├── gstreamer-rockchip (多媒体框架) │ │ └── 其他 LubanCat 专用包 │ └─ 用户定制脚本执行 │ └─ [步骤 3] 镜像打包 mk-image.sh 或内联 mkfs.ext4 → 生成: linaro-rk356x-lite-rootfs.img → 软链接: output/debian/rootfs.ext4 → firmware/rootfs.img

4. 相关构建脚本索引

脚本位置用途
check-debian.shcommon/scripts/check-debian.sh验证主机环境(QEMU、debootstrap 等)
mk-base-debian.shdebian12/mk-base-debian.sh创建 Debian 基础系统 tar.gz
mk-rootfs.shdebian12/mk-rootfs.sh分发到版本特定的构建脚本
mk-bookworm-rootfs.shdebian12/mk-bookworm-rootfs.shDebian 12 (bookworm) 专属构建脚本
mk-image.shdebian12/mk-image.sh生成 ext4 镜像文件

八、 U-Boot(引导加载程序)配置分析

1. 基本信息

项目
U-Boot defconfigrk3568
对应文件u-boot/configs/rk3568_defconfig
U-Boot 源码u-boot/(Rockchip 基于 v2017.09 定制)
架构arm64
设备树rk3568-evb(U-Boot 内部默认)

LubanCat 还提供专用 defconfig lubancat-rk3568-pcie_defconfig,使用 rk3568-lubancat-2 设备树并增加 NVMe/PCIe 支持,但当前 SDK 默认配置使用标准 rk3568

2. U-Boot Defconfig 选择逻辑

根据 Config.in.loader: 9-21 的规则链:

config RK_UBOOT_CFG default "rk1808" if RK_CHIP_FAMILY = "rk1806" default "evb-px3se" if RK_CHIP_FAMILY = "px3se" default "rk3126c" if RK_CHIP = "rk3126c" ... default RK_CHIP_FAMILY if ... rk3308 || rk3288 || rk3588 default RK_CHIP # ← rk3566_rk3568 匹配此项 # RK_CHIP = "rk3568" # 所以 RK_UBOOT_CFG = "rk3568"

3. 交叉编译工具链

70-loader.sh: 101 通过 get_toolchain() 获取:

RK_UBOOT_TOOLCHAIN="$(get_toolchain "U-Boot" "$RK_UBOOT_ARCH")" # 参数: MODULE="U-Boot", ARCH="arm64" # 搜索: prebuilts/gcc/linux-x86/aarch64/ # 结果: aarch64-none-linux-gnu- (与 Kernel 相同的工具链) export UMAKE="./make.sh CROSS_COMPILE=$RK_UBOOT_TOOLCHAIN"

4. 构建流程(BUILD 阶段)

70-loader.sh::build_hook("loader") │ ├─ [架构校验] # L94-99 │ 检查 defconfig 是否包含 aarch32 片段, │ 若有且 RK_UBOOT_ARCH=arm64 则报错切换 │ ├─ [获取工具链] # L101 │ RK_UBOOT_TOOLCHAIN = get_toolchain("U-Boot", "arm64") │ ├─ [构造编译命令] # L108 │ UMAKE = "./make.sh CROSS_COMPILE=aarch64-none-linux-gnu-" │ └─ build_uboot() # L4-72 │ ├─ 清理旧产物: rm u-boot/*.bin u-boot/*.img ├─ check-loader.sh # 验证 Python2 等环境 │ ├─ [执行编译] # L23 │ cd u-boot │ $UMAKE rk3568 [options] │ # 实际执行: │ # ./make.sh CROSS_COMPILE=aarch64-none-linux-gnu- rk3568 │ # │ # make.sh 内部流程: │ # 1. make rk3568_defconfig # 配置 U-Boot │ # 2. make -jN # 编译 │ # 3. pack_images # 打包镜像 (调用 rkbin 工具) │ ├─ check-security.sh uboot # 安全检查 │ ├─ [收集输出] # L58-71 │ LOADER = u-boot/*_loader_*.bin # MiniLoaderAll.bin │ ln -rsf $LOADER firmware/MiniLoaderAll.bin │ ln -rsf u-boot/uboot.img firmware/uboot.img │ [如果有 trust.img]: │ ln -rsf u-boot/trust.img firmware/trust.img │ └─ cd ..

5. 生成的固件组件

镜像文件大小来源说明
MiniLoaderAll.bin~KBDDR bin + SPL bin一级引导:DDR 初始化 + SPL 程序
uboot.img~MBU-Boot 二进制 + DTB二级引导:FIT 格式 U-Boot 镜像
trust.img~KBATF BL31 + OP-TEE BL32安全引导:ARM Trusted Firmware

这些闭源二进制组件来自 rkbin/ 目录:

组件文件说明
DDR 初始化rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.23.binDDR4/LPDDR4X 1560MHz
SPLrkbin/bin/rk35/rk356x_spl_v1.14.binrk356x 共享 SPL
ATF BL31rkbin/bin/rk35/rk3568_bl31_v1.44.elfARM Trusted Firmware
OP-TEE BL32rkbin/bin/rk35/rk3568_bl32_v2.15.binOP-TEE 安全 OS
USB Plugrkbin/bin/rk35/rk356x_usbplug_v1.17.binUSB 烧写模式

6. U-Boot 目录最终 Make 命令详解

本节汇总在 u-boot/ 目录中最终执行的完整编译命令。与 Kernel 不同,U-Boot 使用自有的 make.sh 脚本封装编译流程。

6.1 入口命令:make.sh

调用位置70-loader.sh: build_uboot()

执行的入口命令

cd /root/rk356x_dev/u-boot ./make.sh CROSS_COMPILE=aarch64-none-linux-gnu- rk3568

参数含义

  • CROSS_COMPILE=aarch64-none-linux-gnu-:交叉编译工具链前缀
  • rk3568:U-Boot defconfig 名称(来自 RK_UBOOT_CFG,不带 _defconfig 后缀)

【**UMAKE 变量定义】(70-loader.sh:106-108):

export UMAKE="./make.sh CROSS_COMPILE=$RK_UBOOT_TOOLCHAIN" # 展开为: # UMAKE="./make.sh CROSS_COMPILE=aarch64-none-linux-gnu-"

6.2 make.sh 内部执行流程

u-boot/make.sh 是 Rockchip 定制的 U-Boot 一键构建脚本(约 809 行),内部流程如下:

./make.sh CROSS_COMPILE=aarch64-none-linux-gnu- rk3568 │ ├─ [步骤 1] process_args $* # 解析参数, 提取 defconfig 名 ├─ [步骤 2] prepare # 检查 rkbin 目录存在性 ├─ [步骤 3] select_toolchain # 选择/验证工具链 ├─ [步骤 4] select_chip_info # 从 .config 读取芯片信息 ├─ [步骤 5] fixup_platform_configure # 确定 uboot/trust 大小、加密方式 ├─ [步骤 6] select_ini_file # 选择 RKBOOT/RKTRUST INI 文件 ├─ [步骤 7] sub_commands # 处理子命令 (loader/uboot/trust) ├─ [步骤 8] clean_files # 清理旧产物 (*.bin, *.img) │ ├─ [★★★ 步骤 9 ★★★] 核心编译 make 命令 │ └─ 见下方 6.3 节详解 │ ├─ [步骤 10] pack_images # 打包镜像 │ ├─ pack_uboot_image() → uboot.img │ ├─ pack_trust_image() → trust.img (可选) │ └─ pack_loader_image() → *loader_*.bin │ └─ [步骤 11] finish # 完成提示

6.3 核心编译 Make 命令

调用位置u-boot/make.sh 主函数中

u-boot/ 目录内实际执行的 make 命令

make \ PYTHON=python2 \ CROSS_COMPILE=aarch64-none-linux-gnu- \ all \ --jobs=<N>

参数含义

参数值示例说明
PYTHON=python2python2指定 Python 2 解释器路径(U-Boot 构建工具需要)
CROSS_COMPILEaarch64-none-linux-gnu-交叉编译工具链前缀
all-编译所有目标(U-Boot binary + SPL 等)
--jobs=<N>CPU 核心数并行编译线程数

作用】

该命令使用 U-Boot 自身的 kbuild 构建系统u-boot/Makefile),完成:

  1. 编译 U-Boot 主程序(生成 u-boot-nodtb.bin
  2. 编译 SPL(Secondary Program Loader,如有)
  3. 设备树编译和链接(生成带 DTB 的 u-boot.bin

注意:此命令在 u-boot/ 目录内部执行,不使用 -C 参数指定目录。

6.4 配置阶段 Defconfig 命令

在核心编译之前,make.sh 会先执行配置命令:

make rk3568_defconfig

作用】

加载 U-Boot 默认配置文件 u-boot/configs/rk3568_defconfig,生成 u-boot/.config

6.5 完整 U-Boot 编译命令序列总结

当执行 ./build.sh loader./build.sh uboot 时,按以下顺序依次执行命令:

# Step 0: 进入 u-boot 目录 cd /root/rk356x_dev/u-boot # Step 1: 执行 make.sh(一步完成配置+编译+打包) ./make.sh CROSS_COMPILE=aarch64-none-linux-gnu- rk3568 # === make.sh 内部展开的命令序列 === # Step 1a: 加载 defconfig 配置(make.sh 内部自动执行) make rk3568_defconfig # Step 1b: 核心编译(make.sh 内部自动执行) make PYTHON=python2 CROSS_COMPILE=aarch64-none-linux-gnu- all --jobs=N # Step 1c: 打包镜像(make.sh 内部自动执行,调用 rkbin 工具) # → 生成 u-boot/uboot.img # → 生成 u-boot/*loader_*.bin (MiniLoaderAll) # → 生成 u-boot/trust.img (如启用) # Step 2: 收集产物到 output/firmware/ ln -rsf u-boot/*loader_*.bin output/firmware/MiniLoaderAll.bin ln -rsf u-boot/uboot.img output/firmware/uboot.img ln -rsf u-boot/trust.img output/firmware/trust.img

九、 交叉编译工具链汇总

组件工具链前缀GCC 版本路径
Kernelaarch64-none-linux-gnu-10.3-2021.07prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/
U-Bootaarch64-none-linux-gnu-10.3-2021.07同上(同一套工具链)
Rootfs (Debian)不适用-使用 debootstrap + QEMU user-static chroot 方式构建

get_toolchain() 函数(build.sh: 161-203)的解析策略:

get_toolchain(MODULE, ARCH, VENDOR, OS) │ ├─ 非_x86_64 主机? │ └─ 返回系统原生工具链 (aarch64-linux-gnu- 或 arm-linux-gnueabihf-) │ ├─ RV1126 特殊处理? │ └─ VENDOR = rockchip830 │ ├─ 构建搜索路径: │ TC_DIR = prebuilts/gcc/linux-x86/$ARCH # e.g., .../aarch64 │ ├─ 构建匹配模式: │ 有 VENDOR → "$ARCH-$VENDOR-$OS-[^-]*-gcc" │ 无 VENDOR → "$ARCH-$OS-[^-]*-gcc" │ └─ find 查找第一个匹配的 gcc, 截取目录作为前缀返回

十、 完整构建时序图

1. 从命令行到 .config 生成

时间线 → [用户执行] ./build.sh rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig │ ▼ [main():506] ├─ 拦截 Makefile 选项? → 否 ├─ set -eE + trap ERR ├─ 保存初始环境变量 │ ▼ [setup_environments():379] ← 设置全局路径变量 RK_SDK_DIR=/root/rk356x_dev RK_DEVICE_DIR=device/rockchip RK_OUTDIR=output RK_CONFIG=output/.config ... (共 20+ 个变量) │ ▼ [setup_developer_environments():422] [加载 devenv (如存在)] │ ▼ [check_sdk():429] ├─ 验证脚本路径正确性 └─ 执行 check-sdk.sh (检查依赖工具) │ ▼ [参数预处理:584-592] 输入: "rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig" 检测: "rk3566_rk3568" 存在于 .chips/ 目录 转换: "chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig" │ ▼ [parse_scripts():449] ├─ 生成 output/.make_usage (Makefile 目标列表) └─ 生成 output/.parsed_cmds (各 hook 支持的命令列表) │ ▼ [选项验证:598-640] 遍历 OPTIONS, 通过 option_check() 验证每个选项是否合法 "chip:..." → 匹配 INIT_CMDS 中的 "chip" → 合法 │ ▼ [日志初始化:643-654] 创建 output/sessions/<timestamp>/ 日志目录 │ ▼ [★★★ INIT STAGE ★★ :665] run_build_hooks init "chip:rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig" │ ├─[00-config.sh::init_hook()] ──────────────────────────────┐ │ case "chip" → shift → choose_chip("rk3566_rk3568" "LubanCat...") │ │ │ │ choose_chip(): │ │ ├─ ls .chips/ | grep "rk3566_rk3568" → 唯一匹配 │ │ ├─ CHIP = "rk3566_rk3568" │ │ ├─ ln -rsf .chips/rk3566_rk3568 .chip │ │ └─ choose_defconfig("LubanCat_rk3568_debian_lite_defconfig") │ │ │ │ choose_defconfig(): │ │ ├─ ls .chip/ → 精确匹配 LubanCat_rk3568_debian_lite_defconfig │ │ └─ switch_defconfig(...) │ │ │ │ switch_defconfig(): │ │ ├─ ln -rsf .chip/LubanCat... output/defconfig │ │ ├─ ln -rsf .chip/ .chip (已是正确目录, 幂等) │ │ └─ make LubanCat_rk3568_debian_lite_defconfig │ │ │ │ │ └─ [Makefile KConfig 系统启动] │ │ ├─ 读取 defconfig 最小配置 │ │ ├─ 解析 Config.in 完整配置树 │ │ ├─ 推导所有依赖项的值 │ │ └─ 写入 output/.config (约 200+ 行) │ └─────────────────────────────────────────────────────────────┘ │ ├─[10-kernel.sh::init_hook()] ───────────────────────────────┐ │ case "default" │ │ ├─ 读取 .config → RK_KERNEL_CFG="lubancat_linux_rk356x_defconfig" │ │ ├─ 读取 .config → RK_KERNEL_PREFERRED="6.1" │ │ ├─ 版本优先级判定 → 使用 PREFERRED = "6.1" │ │ ├─ kernel_version() → 检查当前软链接 │ │ └─ ln -rsf kernel-6.1 kernel (若需要切换) │ └─────────────────────────────────────────────────────────────┘ │ ├─[30-rootfs.sh::init_hook()] ──────────────────────────────┐ │ case "default" │ │ ├─ check_config RK_ROOTFS → 尚未配置 → return 0 │ │ └─ (rootfs 信息已在 .config 中由 KConfig 推导完成) │ └─────────────────────────────────────────────────────────────┘ │ ▼ [INIT 完成:666] rm -f output/.tmpconfig* │ ▼ [配置命令检测:669-671] option_check("pre-build build post-build cleanall ...", "chip:...") → 不匹配 → return 0 (纯配置命令到此结束) │ ▼ [完成] output/.config 已就绪 ✓

2. 完整构建流程(./build.sh all)

如果执行完整构建命令(而非仅配置),INIT 阶段之后将继续:

[INIT 完成] output/.config 已生成 │ ▼ [source .config:677] 加载所有 RK_* 变量到环境 │ ▼ [确定内核版本:679] export RK_KERNEL_VERSION="$(kernel_version)" → "6.1" │ ▼ [自定义环境检测:681-717] 检查是否有用户自定义的环境变量覆盖 (RK_KERNEL_VERSION 和 RK_ROOTFS_SYSTEM 不可自定义覆盖) │ ▼ [分区表解析:720-721] source partition-helper rk_partition_init 根据 RK_PARAMETER (parameter-extboot.txt) 解析分区布局 │ ▼ [打印最终配置:772-780] 显示所有关键 RK_* 配置项 │ ══════════════════════════════════════════ ▼ [PRE-BUILD STAGE:783] run_build_hooks pre-build (通常无操作,除非指定 kernel-config 等子命令) │ ▼ [★★★ BUILD STAGE ★★ :786] run_build_hooks build all │ ├─[10-kernel.sh::build_hook("kernel")] ───────────────────┐ │ ├─ source kernel-helper │ │ │ → RK_KERNEL_TOOLCHAIN = aarch64-none-linux-gnu- │ │ │ → KMAKE = make -C kernel/ -jN CROSS_COMPILE=... ARCH=arm64 │ │ │ │ │ ├─ do_build("kernel") │ │ │ ├─ make_kernel_config() │ │ │ │ └─ $KMAKE lubancat_linux_rk356x_defconfig │ │ │ │ [可能附加: rk3568_linux.config fragment] │ │ │ │ │ │ │ ├─ check-kernel.sh │ │ │ │ │ │ │ ├─ [RK_KERNEL_EXTBOOT=y 分支]: │ │ │ │ ├─ do_build_kerneldeb() │ │ │ │ │ └─ $KMAKE bindeb-pkg │ │ │ │ │ → linux-headers-*.deb │ │ │ │ │ → linux-image-*.deb │ │ │ │ │ │ │ │ │ └─ do_build_extboot() ★ │ │ │ │ ├─ $KMAKE rk356x-lubancat-generic.img │ │ │ │ ├─ $KMAKE dtbs │ │ │ │ ├─ 构建 extboot/ 目录结构 │ │ │ │ │ ├── Image-6.1.x (内核镜像) │ │ │ │ │ ├── dtb/*.dtb (设备树) │ │ │ │ │ ├── dtb/overlay/*.dtbo │ │ │ │ │ ├── extlinux/extlinux.conf │ │ │ │ │ ├── uEnv.txt / rk356x/*.txt │ │ │ │ │ ├── initrd-6.1 │ │ │ │ │ ├── kerneldeb/*.deb │ │ │ │ │ └── config/System.map/logo │ │ │ │ └─ mkfs.ext2 → extboot.img (128MB) │ │ │ │ → output/firmware/boot.img │ │ │ │ │ │ │ └─ finish_build build_kernel │ └─┬────────────────────────────────────────────────────────┘ │ ├─[30-rootfs.sh::build_hook("rootfs")] ───────────────────┐ │ │ │ │ ├─ ROOTFS = "debian" (来自 RK_ROOTFS_SYSTEM) │ │ ├─ 创建 output/debian/images/ 工作目录 │ │ │ │ │ └─ build_debian() │ │ │ │ │ ├─ [缓存检查] $RK_ROOTFS_IMAGE 存在? │ │ │ └─ 不存在 ↓ │ │ │ │ │ ├─ [缓存检查] linaro-*-rootfs.img 存在? │ │ │ └─ 不存在 ↓ │ │ │ │ │ ├─ [步骤 1] mk-base-debian.sh │ │ │ cd debian12/ │ │ │ RELEASE=bookworm TARGET=lite ARCH=arm64 \ │ │ │ ./mk-base-debian.sh │ │ │ → debootstrap + live-build │ │ │ → linaro-bookworm-lite-arm64-alip-*.tar.gz │ │ │ │ │ ├─ [步骤 2] mk-rootfs.sh → mk-bookworm-rootfs.sh │ │ │ ├─ 解压 tar.gz 到 binary/ │ │ │ ├─ 复制 overlay/ 系统配置 │ │ │ ├─ 复制 overlay-firmware/ 固件 │ │ │ ├─ 复制 packages/arm64/ deb 包 │ │ │ └─ qemu-aarch64-static chroot: │ │ │ ├─ apt-get install 基础包 │ │ │ ├─ 安装 libmali, mpp, rga, gstreamer 等 │ │ │ └─ 执行定制脚本 │ │ │ │ │ ├─ [步骤 3] 打包镜像 │ │ │ → linaro-rk356x-lite-rootfs.img (ext4) │ │ │ → output/debian/rootfs.ext4 │ │ │ → output/firmware/rootfs.img │ │ │ │ │ └─ finish_build build_rootfs │ └─┬────────────────────────────────────────────────────────┘ │ ├─[70-loader.sh::build_hook("loader")] ────────────────────┐ │ │ │ │ ├─ get_toolchain("U-Boot", "arm64") │ │ │ → aarch64-none-linux-gnu- │ │ │ │ │ ├─ UMAKE = "./make.sh CROSS_COMPILE=aarch64-none-linux-gnu-" │ │ │ │ │ └─ build_uboot() │ │ ├─ check-loader.sh │ │ ├─ cd u-boot && $UMAKE rk3568 │ │ │ ├─ make rk3568_defconfig │ │ │ ├─ make -jN │ │ │ └─ pack_images (使用 rkbin 工具) │ │ │ │ │ ├─ check-security.sh uboot │ │ │ │ │ ├─ 收集产物: │ │ │ ├─ *loader*.bin → firmware/MiniLoaderAll.bin │ │ │ ├─ uboot.img → firmware/uboot.img │ │ │ └─ trust.img → firmware/trust.img │ │ │ │ │ └─ cd .. │ └─┬────────────────────────────────────────────────────────┘ │ ▼ [★★★ POST-BUILD STAGE ★★ :789] run_build_hooks post-build │ ├─ [固件打包] │ 根据 parameter-extboot.txt 分区表和 package-file-extboot 清单, │ 将以下组件打包为 update.img: │ ├── firmware/MiniLoaderAll.bin (IDBlock) │ ├── firmware/uboot.img (U-Boot) │ ├── firmware/trust.img (ATF+OPTEE, 可选) │ ├── firmware/boot.img (extboot: 内核+DTB+initrd) │ └── firmware/rootfs.img (Debian rootfs) │ └─ [linux-headers 打包] (如果指定) └─ 生成 linux-headers-{host,armhf,aarch64}.tar(.gz) └─ 可选: 打包为 .deb ▼ [完成 ✓] 固件位于: output/update.img

十一、 关键文件路径索引

1. 主控脚本

文件说明
build.sh ( 入口)主入口脚本:环境初始化、错误处理、hook 调度、阶段编排
00-config.sh核心: 芯片选择、defconfig 切换、KConfig 触发
10-kernel.sh内核配置选择、编译、extboot 镜像构建
30-rootfs.shRootfs 构建(Debian/Ubuntu/Buildroot/Yocto)
70-loader.shU-Boot 编译构建
build-helperHook 框架辅助(日志、命令执行封装)

2. KConfig 配置文件

文件说明
Config.inKConfig 主入口
Config.in.kernel内核相关选项(架构、defconfig、DTS、extboot)
Config.in.rootfs根文件系统选项(Buildroot/Debian/Ubuntu/Yocto)
Config.in.loaderU-Boot/Loader 选项(defconfig、SPL、trust)
Config.in.debianDebian 发行版选项(版本/架构/镜像源)
Config.in.boot启动镜像选项(压缩格式、FIT image 等)
Config.in.firmware固件打包选项(package-file、partition)

3. 目标 Defconfig

文件说明
LubanCat_rk3568_debian_lite_defconfig本次使用的目标 defconfig(最小配置片段)

4. 辅助脚本

文件说明
kernel-helper内核工具链设置、KMAKE 变量构造
mk-config.shKConfig 辅助(olddefconfig 包装)
check-sdk.shSDK 完整性和依赖检查
check-kernel.sh内核编译环境检查
check-loader.shU-Boot 编译环境检查
check-debian.shDebian 构建环境检查
partition-helper分区表解析
post-helperPost-rootfs 阶段辅助

5. Debian 构建脚本

文件说明
mk-base-debian.sh基于 live-build 构建基础 Debian tarball
mk-rootfs.shRootfs 构建入口,分发到版本特定脚本
mk-bookworm-rootfs.shDebian 12 (bookworm) 专属定制脚本
mk-image.sh将目录打包为 ext4 镜像

6. 输出产物

路径说明
output/.config最终完整配置文件(KConfig 生成)
output/defconfig→ 指向当前使用的 defconfig(软链接)
output/firmware/boot.imgextboot 启动分区镜像(内核 + DTB + initrd)
output/firmware/rootfs.imgDebian 根文件系统镜像
output/firmware/uboot.imgU-Boot 镜像
output/firmware/MiniLoaderAll.binDDR 初始化 + SPL
output/firmware/trust.imgATF + OP-TEE(可选)
output/update.img最终可烧写的完整固件

本文档由 markdowncli 技能辅助生成

About

LubanCat-RK系列板卡SDK配置仓库

Language
Perl46.4%
Shell27%
C19.6%
C++2.9%
Others4.1%