执行命令:
./build.sh rk3566_rk3568:LubanCat_rk3568_debian_lite_defconfig
该命令完成两件事:
rk3566_rk3568LubanCat_rk3568_debian_lite_defconfig最终产物为 RK3568 芯片 LubanCat 开发板的 Debian 12 (bookworm) lite 版本完整固件(update.img)。
build.sh 是一个软链接,指向:
build.sh -> device/rockchip/common/scripts/build.sh
主入口脚本为 build.sh,核心函数为 main() (build.sh: 506)。
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)。
在 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
setup_environments() (build.sh: 379-420)定义了构建系统所需的所有关键路径变量:
| 变量 | 值 | 说明 |
|---|---|---|
RK_SDK_DIR | /root/rk356x_dev | SDK 根目录 |
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.in | KConfig 主文件 |
RK_CONFIG | output/.config | 最终输出配置 |
RK_OUTDIR | output/ | 输出根目录 |
RK_FIRMWARE_DIR | output/firmware/ | 固件输出目录 |
RK_BUILD_HOOK_DIR | build-hooks | 构建钩子目录 |
RK_DEFCONFIG_LINK | output/defconfig | defconfig 软链接 |
我们直接函数里加打印:
# ----- 打印所有变量 -----
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 调度模式,核心调度链为:
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
每次调用 run_hooks() 时,按以下优先级遍历两个目录(build.sh: 336-339):
优先级高: ./.chip/scripts/ # 芯片专用钩子 优先级低: ./common/build-hooks/ # 公共钩子
对于
usage阶段则相反:公共目录优先,芯片目录在后(build.sh: 332-333)。
每个 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"
| 脚本 | INIT 阶段 | PRE-BUILD 阶段 | BUILD 阶段 | POST-BUILD 阶段 |
|---|---|---|---|---|
| 00-config.sh | 芯片选择、defconfig 切换、KConfig 触发 | - | - | - |
| 10-kernel.sh | 内核版本选择、创建 kernel 软链接 | 内核 menuconfig/make | 内核编译 + extboot | linux-headers 打包 |
| 30-rootfs.sh | rootfs 类型确认 | Buildroot 配置/编译 | Debian/Ubuntu/Buildroot/Yocto 构建 | Buildroot SDK 打包 |
| 70-loader.sh | - | - | U-Boot 编译和镜像打包 | - |
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 已生成 ✓
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")
}
当 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 定义了 %_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 配置文件)
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" ← 打包清单名称
KConfig 系统根据上述最小配置 + Config.in 中的依赖关系,自动推导出完整配置。关键推导链如下:
# 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
# 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" # 变量展开结果
# 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"
# 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
| 配置项 | 值 | 来源 |
|---|---|---|
RK_DEFCONFIG | LubanCat_rk3568_debian_lite_defconfig | defconfig 文件名 |
RK_CHIP_FAMILY | rk3566_rk3568 | Makefile 自动推导 |
RK_CHIP | rk3568 | Makefile 从文件名提取 |
RK_ROOTFS_SYSTEM | debian | 隐含推导(非 buildroot/yocto) |
RK_ROOTFS_TARGET | lite | defconfig 中指定 |
RK_DEBIAN_VERSION | bookworm | Config.in.debian 默认值 |
RK_DEBIAN_NUMBER | debian12 | KConfig 推导 |
RK_KERNEL_PREFERRED | 6.1 | defconfig 中指定 |
RK_KERNEL_CFG | lubancat_linux_rk356x_defconfig | defconfig 中指定 |
RK_KERNEL_DTS_NAME | rk356x-lubancat-generic | defconfig 中指定 |
RK_KERNEL_EXTBOOT | y | defconfig 中指定 |
RK_UBOOT_CFG | rk3568 | Config.in.loader 推导 |
RK_PARAMETER | parameter-extboot.txt | defconfig 中指定 |
RK_USE_FIT_IMG | y | defconfig 中指定 |
| 项目 | 值 |
|---|---|
| 内核版本 | 6.1 |
| 源码目录 | kernel-6.1/ |
| 软链接 | kernel → kernel-6.1 |
| 架构 | arm64 (aarch64) |
| 内核 defconfig | lubancat_linux_rk356x_defconfig |
| 设备树 | rk356x-lubancat-generic.dts |
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 # 创建/更新软链接
通过 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 |
当执行 ./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
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 |
| USB | DWC3, DWC2, gadget, Type-C |
| 文件系统 | ext4, XFS, BTRFS, UBIFS, SquashFS, NFS, NTFS3, FUSE |
本节汇总在 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
调用位置: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 核心数 + 1CROSS_COMPILE=aarch64-none-linux-gnu-:交叉编译工具链前缀ARCH=arm64:目标架构为 ARM64lubancat_linux_rk356x_defconfig:内核默认配置文件(来自 RK_KERNEL_CFG)<config_fragments>:芯片相关的配置片段(自动检测),可能包括:
rk3566_rk3568.configrk3566_rk3568_linux.configrk3568.configrk3568_linux.config【作用】
该命令将 defconfig 和 config fragments 合并,生成内核最终的 .config 配置文件(位于 kernel/.config)。
调用位置: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)【**作用】】
该命令触发内核构建系统完成以下工作:
vmlinux 和 Image(内核镜像).dts → .dtb)mkimage 工具将 Image + .dtb 打包为 FIT 格式镜像(.img)调用位置: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/ 目录。产物包括:
rk356x-lubancat-generic.dtb)overlay/*.dtbo)调用位置: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 分区镜像中。
| 目标 | 完整命令示例 | 说明 |
|---|---|---|
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 | 完全清除(包括配置) |
当执行 ./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
| 项目 | 值 |
|---|---|
| 类型 | Debian 12 (bookworm) lite |
| 构建目录 | debian12/ |
| 目标架构 | arm64 (RK_DEBIAN_ARCH) |
| 镜像格式 | ext4 |
| 镜像名称 | linaro-rk356x-lite-rootfs.img |
| 输出路径 | output/debian/rootfs.ext4 |
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 环境中操作。
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
| 脚本 | 位置 | 用途 |
|---|---|---|
check-debian.sh | common/scripts/check-debian.sh | 验证主机环境(QEMU、debootstrap 等) |
mk-base-debian.sh | debian12/mk-base-debian.sh | 创建 Debian 基础系统 tar.gz |
mk-rootfs.sh | debian12/mk-rootfs.sh | 分发到版本特定的构建脚本 |
mk-bookworm-rootfs.sh | debian12/mk-bookworm-rootfs.sh | Debian 12 (bookworm) 专属构建脚本 |
mk-image.sh | debian12/mk-image.sh | 生成 ext4 镜像文件 |
| 项目 | 值 |
|---|---|
| U-Boot defconfig | rk3568 |
| 对应文件 | 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。
根据 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"
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"
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 ..
| 镜像文件 | 大小 | 来源 | 说明 |
|---|---|---|---|
MiniLoaderAll.bin | ~KB | DDR bin + SPL bin | 一级引导:DDR 初始化 + SPL 程序 |
uboot.img | ~MB | U-Boot 二进制 + DTB | 二级引导:FIT 格式 U-Boot 镜像 |
trust.img | ~KB | ATF BL31 + OP-TEE BL32 | 安全引导:ARM Trusted Firmware |
这些闭源二进制组件来自 rkbin/ 目录:
| 组件 | 文件 | 说明 |
|---|---|---|
| DDR 初始化 | rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.23.bin | DDR4/LPDDR4X 1560MHz |
| SPL | rkbin/bin/rk35/rk356x_spl_v1.14.bin | rk356x 共享 SPL |
| ATF BL31 | rkbin/bin/rk35/rk3568_bl31_v1.44.elf | ARM Trusted Firmware |
| OP-TEE BL32 | rkbin/bin/rk35/rk3568_bl32_v2.15.bin | OP-TEE 安全 OS |
| USB Plug | rkbin/bin/rk35/rk356x_usbplug_v1.17.bin | USB 烧写模式 |
本节汇总在 u-boot/ 目录中最终执行的完整编译命令。与 Kernel 不同,U-Boot 使用自有的 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-"
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 # 完成提示
调用位置:u-boot/make.sh 主函数中
在 u-boot/ 目录内实际执行的 make 命令:
make \
PYTHON=python2 \
CROSS_COMPILE=aarch64-none-linux-gnu- \
all \
--jobs=<N>
【参数含义】
| 参数 | 值示例 | 说明 |
|---|---|---|
PYTHON=python2 | python2 | 指定 Python 2 解释器路径(U-Boot 构建工具需要) |
CROSS_COMPILE | aarch64-none-linux-gnu- | 交叉编译工具链前缀 |
all | - | 编译所有目标(U-Boot binary + SPL 等) |
--jobs=<N> | CPU 核心数 | 并行编译线程数 |
【作用】
该命令使用 U-Boot 自身的 kbuild 构建系统(u-boot/Makefile),完成:
u-boot-nodtb.bin)u-boot.bin)注意:此命令在
u-boot/目录内部执行,不使用-C参数指定目录。
在核心编译之前,make.sh 会先执行配置命令:
make rk3568_defconfig
【作用】
加载 U-Boot 默认配置文件 u-boot/configs/rk3568_defconfig,生成 u-boot/.config。
当执行 ./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 版本 | 路径 |
|---|---|---|---|
| Kernel | aarch64-none-linux-gnu- | 10.3-2021.07 | prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/ |
| U-Boot | aarch64-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, 截取目录作为前缀返回
时间线 → [用户执行] ./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 已就绪 ✓
如果执行完整构建命令(而非仅配置),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
| 文件 | 说明 |
|---|---|
| build.sh (→ 入口) | 主入口脚本:环境初始化、错误处理、hook 调度、阶段编排 |
| 00-config.sh | 核心: 芯片选择、defconfig 切换、KConfig 触发 |
| 10-kernel.sh | 内核配置选择、编译、extboot 镜像构建 |
| 30-rootfs.sh | Rootfs 构建(Debian/Ubuntu/Buildroot/Yocto) |
| 70-loader.sh | U-Boot 编译构建 |
| build-helper | Hook 框架辅助(日志、命令执行封装) |
| 文件 | 说明 |
|---|---|
| Config.in | KConfig 主入口 |
| Config.in.kernel | 内核相关选项(架构、defconfig、DTS、extboot) |
| Config.in.rootfs | 根文件系统选项(Buildroot/Debian/Ubuntu/Yocto) |
| Config.in.loader | U-Boot/Loader 选项(defconfig、SPL、trust) |
| Config.in.debian | Debian 发行版选项(版本/架构/镜像源) |
| Config.in.boot | 启动镜像选项(压缩格式、FIT image 等) |
| Config.in.firmware | 固件打包选项(package-file、partition) |
| 文件 | 说明 |
|---|---|
| LubanCat_rk3568_debian_lite_defconfig | 本次使用的目标 defconfig(最小配置片段) |
| 文件 | 说明 |
|---|---|
| kernel-helper | 内核工具链设置、KMAKE 变量构造 |
| mk-config.sh | KConfig 辅助(olddefconfig 包装) |
| check-sdk.sh | SDK 完整性和依赖检查 |
| check-kernel.sh | 内核编译环境检查 |
| check-loader.sh | U-Boot 编译环境检查 |
| check-debian.sh | Debian 构建环境检查 |
| partition-helper | 分区表解析 |
| post-helper | Post-rootfs 阶段辅助 |
| 文件 | 说明 |
|---|---|
| mk-base-debian.sh | 基于 live-build 构建基础 Debian tarball |
| mk-rootfs.sh | Rootfs 构建入口,分发到版本特定脚本 |
| mk-bookworm-rootfs.sh | Debian 12 (bookworm) 专属定制脚本 |
| mk-image.sh | 将目录打包为 ext4 镜像 |
| 路径 | 说明 |
|---|---|
output/.config | 最终完整配置文件(KConfig 生成) |
output/defconfig | → 指向当前使用的 defconfig(软链接) |
output/firmware/boot.img | extboot 启动分区镜像(内核 + DTB + initrd) |
output/firmware/rootfs.img | Debian 根文件系统镜像 |
output/firmware/uboot.img | U-Boot 镜像 |
output/firmware/MiniLoaderAll.bin | DDR 初始化 + SPL |
output/firmware/trust.img | ATF + OP-TEE(可选) |
output/update.img | 最终可烧写的完整固件 |
本文档由 markdowncli 技能辅助生成