RK平台从编译到烧录:构建与烧录排障系统化

电子说

1.4w人已加入

描述

一次完整的开发闭环是「编译 → 烧录 → 升级 → 分区 → 启动」。这套链路每换一段都可能出问题,而每一段都有它自己的「证据」(报错信息、工具输出、日志、分区表)。本文基于触觉智能RK3576 Linux SDK,把这条链路从头到尾过一遍,问题、根因、命令串成一套,遇到卡点按段排查即可。

编译

五个环节里,环境报错看 check-*.sh(01 编译)、烧录失败看工具与 Loader/MaskRom 模式、升级看 misc 引导与升级包、分区看 parameter.txt 与 rootfs:grow、启动卡死看日志阶段标志。下面按这个顺序展开。

一、编译环境都装好了,为什么一编译就报错?

别急着怀疑代码——这套 SDK 在动手编译前会先给环境做一次"体检",绝大多数报错信息里,其实就写着答案。

拿到 RK3576 Linux6.1 SDK 后第一件事不是改代码,而是先把编译环境对齐。这套 SDK(K1 新一代布局)内置了一套自动环境检查:每次 ./build.sh 或 make 启动时都会先跑 check_sdk,再按你选择的组件(内核 / Debian / Buildroot / Yocto…)分别跑对应的 check-*.sh。报错不是"玄学",而是这套检查脚本吐出来的结构化信息。报错信息里一般就带着解法:装哪个包、换哪个版本、改哪个目录权限。

1、这套 SDK 的"先体检,后编译"机制

入口在 device/rockchip/common/scripts/build.sh 的 main():

setup_environments:导出全套 RK_* 环境变量(SDK 目录、output 目录、芯片目录等);

check_sdk:先校验脚本路径没被搬错位置,然后执行 check-sdk.sh,并检测是否用 root 在编译;

各组件脚本(mk-kernel.sh / mk-rootfs.sh 等)内部再调 check-kernel.sh / check-debian.sh / check-buildroot.sh / check-yocto.sh 等。

这些 check-*.sh 全部位于 device/rockchip/common/scripts/ 下。所以排查"编译报错"的第一步,是先读懂报错是哪个检查脚本吐出来的,而不是直接去翻 Makefile。

官方依据:SDK 编译流程见 docs/cn/Rockchip_Developer_Guide_Linux_Software_CN.pdf 与根目录 README.md(Quick Start 五步:make help → make rockchip_defconfig → make menuconfig → make → 烧 output/firmware/update.img);环境检查机制以 device/rockchip/common/scripts/check-*.sh 源码为准。

2、一张表看懂环境报错(错误信息 → 原因 → 解法)

下表所有"报错关键字 / 解法"均直接摘自 SDK 源码(check-sdk.sh、check-kernel.sh、check-debian.sh、check-package.sh、build.sh),不是网上总结的通用经验。

报错关键字 含义 解法(摘自脚本给出的提示)
Current user is not the owner of SDK source! 当前用户不是 SDK 源码属主(常见于 sudo 或换用户后) sudo chown -h -R $(id -un):$(id -un) $RK_SDK_DIR/,或 su - $RK_OWNER 切回属主
Please move SDK source code into an ext4 partition. 源码所在分区不是 ext4/f2fs/btrfs(如 NTFS、FAT、挂载盘) 把 SDK 移到 ext4 分区;SDK 只认 ext*|f2fs|btrfs
Your rsync/gcc/g++ is missing 缺基础包(check-package.sh 统一输出) sudo apt-get install rsync gcc g++
Your python3 is too old for kernel: … python3 版本太旧(内核 mkbootimg 跑不动) 升级 python3(脚本会提示跑 install-python3.sh)
Your lz4 is too old for kernel: … lz4 不带 favor-decSpeed(内核压缩 Image 需要) 安装 lz4 v1.9.4(源码 git clone …/lz4 -b v1.9.4,sudo make install)
缺 openssl/ssl.h、gmp.h、mpc.h、ncurses.h 等头文件 编译内核缺少 dev 开发包(check-header.sh 检查) sudo apt-get install libssl-dev libgmp-dev libmpc-dev libncurses-dev flex
Please remount to allow creating devices… 分区以 nodev 挂载(编 Debian 需要 mknod) sudo mount -o remount,dev <挂载点>
Your mke2fs is too old: … e2fsprogs 太旧,没有 -d 选项(打 ext4 根文件系统用) 运行 install-e2fsprogs.sh 升级
Your live-build doesn't support bookworm / Your debootstrap doesn't support bookworm live-build / debootstrap 太旧,不支持 Debian 12(bookworm) 按脚本提示用 salsa 源码分支重装 live-build / debootstrap
Your qemu-aarch64-static(qemu-user-static) is broken chroot 模拟 arm64 环境的 qemu 坏了 sudo apt-get install binfmt-support qemu-user-static --reinstall
Your qemu-aarch64 doesn't work with Debian(bookworm)! qemu 版本与 bookworm 不兼容(需 qemu-8.0) 用 SDK 自带 tools/x86_64/qemu-aarch64-static 替换后 reboot
No prebuilt GCC toolchain for …! SDK 预编译交叉工具链缺失(get_toolchain() 在 prebuilts/gcc/linux-x86/ 找不到 gcc) 检查 prebuilts/gcc/linux-x86/aarch64 目录是否完整,必要时重新 repo sync
Debian 源检查报错(编译 Debian 时) check-network.sh 验证镜像源 RK_DEBIAN_MIRROR 不可达(本 SDK 默认 USTC 源) 确保能访问镜像源,或改 RK_DEBIAN_MIRROR

3、最容易踩的三个坑

坑 1:权限 / 目录不对,脚本直接拒跑

最典型的是用 sudo 或换用户编译。SDK 在 check-sdk.sh 里用 stat --format %U 取 SDK 属主,再和当前用户对比,不一致就报 Current user is not the owner of SDK source!。另外源码分区必须是 ext4/f2fs/btrfs——如果 SDK 解压在移动硬盘(NTFS)上,会直接报"请移到 ext4 分区"。

坑 2:版本"装了"但"太老"

这类报错最容易让人困惑:包明明装了啊。SDK 的检查不是"装了没",而是验证关键能力,例如:

lz4:跑 lz4 -h | grep favor-decSpeed,旧版没有这个特性就报错并建议装 v1.9.4;

python3:直接拿 kernel/scripts/mkbootimg 试跑,跑不动就报"too old";

mke2fs:必须支持 -d 选项;

qemu-user-static:要能配合 bookworm 的 ldconfig 跑起来,否则提示换 qemu-8.0。

坑 3:只编译内核 vs 全量编译,需要的包不一样

只编内核,检查的是 check-kernel.sh(flex、libssl-dev、libgmp-dev、libmpc-dev、libncurses-dev 等);一旦加编 Debian 根文件系统,就触发 check-debian.sh(debootstrap、qemu-user-static、binfmt-support、live-build)。很多人在内核编过后以为环境没问题,结果 buildroot/debian 阶段又报新错——因为那是另一组检查脚本。Buildroot 还要 expect(unbuffer),Yocto 要 zstd。

4、别等报错,先主动自查

 

# 1. 编译前先看帮助,确认选择路径make helpmake rockchip_defconfig   # 或 ./build.sh rk3576:# 2. 关键包快速自查which python3 rsync gcc g++ flex debootstrap fakeroot zstd unbufferlz4 -h | grep favor-decSpeed   # 看 lz4 能力dpkg -l | grep -E "libssl-dev|libgmp-dev|libmpc-dev|libncurses-dev|qemu-user-static|live-build"# 3. 确认 SDK 属主与分区stat -c '%U' . 2>/dev/null        # 应与当前用户一致findmnt -fnu -o FSTYPE -T .        # 应是 ext4/f2fs/btrfs

 

如果环境检查和命令都对,编译仍报错,那才进入"看构建日志"阶段——日志统一在 output/log/ 与 output/sessions/ 下,逐行看最终失败的命令。

5、避坑提醒

官方 推荐 Ubuntu 22.04;在 Ubuntu 24.04 上编译,官方 SDK Note 特别说明 v1.1.0 增强了 Debian 编译环境的检查与提示、v1.0.1 修复了 24.04 的编译异常——升级 SDK 或用 LTS 系统能少踩很多坑(依据:docs/cn/RK3576/RK3576_Linux6.1_SDK_Note.md)。

本 SDK 默认 Debian 12(bookworm)arm64,源码 debian/ubuntu-build-service/bookworm-xfce-arm64/;换其它版本/架构前先看 check-debian.sh 是否支持。

编译并行度由环境变量控制(本机示例 NINJAJOBS=48 / MAKEFLAGS=-j48),内存不够时先降并行度再谈其他。

"一编译就报错"在 RK3576 Linux6.1 SDK 里几乎都是环境检查拦截的结果,不是代码问题。处理顺序:① 看报错来自哪个 check-*.sh;② 按脚本提示装包/换版本/改权限;③ 用上文自查命令提前验证;④ 全量编译前把 kernel + rootfs 需要的包一次装齐。

二、烧录一直失败,是板子坏了还是工具不对?

绝大多数烧录失败,不是板子坏了,而是"设备没进对模式"或"工具没找到设备"。本文给你一张决策流程图。

烧录的本质:板子在 Loader 模式(或 MaskRom 模式)下,通过 USB 的 Rockusb 协议与 PC 端工具通信。工具下载镜像到对应分区。所以判断烧录失败,先回答三个问题:① 工具找到设备了吗?② 设备在哪个模式?③ 烧的是不是和分区匹配的镜像?

工具位置:Linux 用 tools/linux/Linux_Upgrade_Tool/Linux_Upgrade_Tool/upgrade_tool(本 SDK 为 v2.44);Windows 用图形工具 RKDevTool(SDK Note:v3.36)或命令行 tools/windows/upgrade_tool_v2.44.zip。官方文档:docs/cn/Linux/Recovery/Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf。

1、烧录失败决策流程图

下面这张图是本文的核心,按顺序走就能定位绝大多数问题:

编译

2、工具的命令集(实测输出)

直接在 SDK 里跑 upgrade_tool -h 就能看到完整命令。常用这几个:

命令 用途
LD ListDevice 列设备——烧录前第一件事
CD / SD ChooseDevice / SwitchDevice——多设备时选择
UL UpgradeLoader——烧 Loader(MaskRom 恢复的第一步)
UF UpgradeFirmware——一键烧 update.img(推荐,免管分区)
DI -p|-uboot|-trust|-b|-r|-m|-oem|-userdata|-rootfs DownloadImage 按分区烧单镜像
EF EraseFlash 擦除 Flash(换分区/换存储前先擦)
RD ResetDevice 重启设备
PL / RCI / SFI 分区表 / 芯片信息 / 固件信息——确认板型与固件匹配

3、常见失败现象对照表

现象 / 报错 原因 处理
执行 DI/UF/UL 时报 No found any rockusb device,please plug device in!(或 LD 显示 List of rockusb connected(0)) 工具没找到任何 Rockusb 设备 先确认板子是否已进入 Loader/MaskRom 模式(不是普通开机状态);换线换口;Type-C 必须用数据线
上电后是正常开机画面,不是"下载模式" 板子没进 Loader 模式 按住 RECOVERY(下载)键 + RESET 再松开,或用系统内 reboot loader 进下载模式
Linux 下 LD 没权限 / 看不到设备 USB 设备权限(udev 规则)或驱动问题 确认用户有 USB 访问权限;Windows 下安装/重装 Rockchip 驱动(MaskRom 模式需专用驱动)
loader 被刷坏/清空后,识别成 MaskRom 设备 Loader 丢失,芯片回落到 MaskRom MaskRom 模式先 UL MiniLoaderAll.bin 恢复 Loader,再走正常流程
烧 di -p(parameter)失败 parameter 与设备存储/既有分区不匹配 先 EF 擦除再烧;确认烧的是同一板型的 parameter(见 01.04)
烧到一半卡住 / 报错退出 镜像与设备不符、USB 不稳定、存储异常 换稳定 USB 口;用 UF 烧整包 update.img;必要时重进 Loader 再试

注:MaskRom 与 Loader 模式的进入方式、Windows 驱动安装细节以官方 Upgrade_CN.pdf 与 RKDevTool 文档为准(模式机制属 RK 平台通用行为)。

4、SDK 自带的烧录脚本:rkflash.sh

SDK 已经把整包烧录流程写成了脚本 device/rockchip/common/scripts/rkflash.sh,它直接调用上面的 upgrade_tool。全量烧录(rkflash.sh 不带参数 = all)的执行顺序是:

 

upgrade_tool ul -noreset $LOADER      # MiniLoaderAll.binupgrade_tool di -p $PARAMETER         # parameter.txt(分区表)upgrade_tool di -uboot $UBOOT         # uboot.imgupgrade_tool di -trust $TRUST         # trust.imgupgrade_tool di -b $BOOT              # boot.imgupgrade_tool di -r $RECOVERY          # recovery.imgupgrade_tool di -m $MISC              # misc.imgupgrade_tool di -oem $OEM             # oem.imgupgrade_tool di -userdata $USERDATA   # userdata.imgupgrade_tool di -rootfs $ROOTFS       # rootfs.imgupgrade_tool rd                       # 重启

 

支持只烧某一个:./rkflash.sh boot、./rkflash.sh rootfs、./rkflash.sh loader、./rkflash.sh update(一键烧 update.img)、./rkflash.sh erase(擦除)。

镜像在哪:固件输出目录 output/firmware/(即 rockdev)。本 SDK 的 Loader 是 rk3576_spl_loader_v1.09.107.bin(软链到 u-boot/),boot.img 来自内核构建。

5、实操排查步骤

 

# 0. 工具与设备cd tools/linux/Linux_Upgrade_Tool/Linux_Upgrade_Tool./upgrade_tool LD          # 看到 Rockusb 设备 = 连接成功# 1. 看不到设备 → 强制进 Loader#    按住 RECOVERY 键 + 复位/上电,然后再次 LD# 2. 进 MaskRom 后先恢复 Loader./upgrade_tool UL /rockdev/MiniLoaderAll.bin# 3. 正常烧录(二选一)./upgrade_tool UF /rockdev/update.img     # 整包,最省事# 或单分区./upgrade_tool DI -p /rockdev/parameter.txt./upgrade_tool DI -b /rockdev/boot.img# 4. 烧完重启./upgrade_tool RD

 

烧录失败先别怀疑板子: 用 upgrade_tool LD 看工具是否找到设备; 找不到就强制进 Loader(RECOVERY 键),再不行考虑 MaskRom + UL 恢复 Loader; 走 rkflash.sh all 或 UF update.img 整包烧录最稳; 仍未解决才考虑硬件(换线/换口/换板)。

三、Recovery 进不去、OTA 刷不上,升级链路哪一环断了?

"进不去 recovery"和"OTA 刷不上"不是同一件事:前者是引导问题,后者是升级包/板端代码问题。本文把升级链路拆成四个环节逐一排查。

一次完整的 OTA/Recovery 升级,由四个环节组成:① recovery 镜像(迷你系统)→ ② misc 分区的引导指令(决定重启后进不进 recovery)→ ③ 板端升级代码(rkupdate,实现 Rockusb)→ ④ 升级包 update.img(打包了哪些分区)。逐环节确认,失败就能定位到具体一环。

1、升级链路全景

编译

2、环节 ①:recovery 镜像从哪来

recovery 不是内核的一部分,而是 SDK 单独构建的一个极简 Buildroot 系统 + recovery 专用内核,最终打包成一个 FIT 镜像。构建入口是 device/rockchip/common/scripts/mk-recovery.sh:

用 RK_RECOVERY_CFG(本 SDK = rockchip_rk3576_recovery,对应 buildroot/configs/rockchip_rk3576_recovery_defconfig)编一个迷你 rootfs(initrd 为 cpio.gz);

编 recovery 专用内核(mk-kernel.sh recovery-kernel);

用 FIT 模板 device/rockchip/.chips/rk3576/boot4recovery.its 把 fdt + kernel + ramdisk + resource 打成一个 recovery.img。

排障点:烧录前先确认 output/firmware/recovery.img 存在且是最近一次 ./build.sh recovery 的产物。recovery 分区在 parameter 里固定为 128MB(见下),镜像别超。

3、环节 ②:怎么进 recovery——misc 分区的秘密

重启后会不会进 recovery,由 misc 分区的内容决定。device/rockchip/common/scripts/mk-misc.sh 生成 misc.img:

misc.img 只有 48KB(truncate -s 48k),分区本身是 4MB

若配置 RK_MISC_RECOVERY,会在 偏移 16KB 写入 "boot-recovery",偏移 16KB+64 写入 recoveryn<参数>——bootloader 读 misc 看到这些指令就会进 recovery;

若配置 RK_MISC_BLANK,生成的是空白 misc——重启直接进正常系统。

排障点:本 SDK 默认 RK_MISC_BLANK=y(见 output/final.env)。所以"重启直接进 recovery"对烧入的固件不生效是正常的——要么用系统里的 reboot recovery 指令(由升级脚本写 misc),要么在 recovery 模式下按组合键/用升级工具。

4、环节 ③:板端升级代码 rkupdate

进入 recovery 后,真正"刷分区"的是 external/rkupdate ——一套在板端实现 Rockusb 协议的 C++ 代码(RKComm.cpp 管 USB 通信、Upgrade.cpp 管升级流程、RKDevice.cpp 管设备枚举)。它的 main.cpp 会把进度通过管道回传给 recovery 界面:ui_print <文本>、set_progress / progress。

排障点:U 盘升级/ADB 侧载失败时,看板端日志里 rkupdate 是否启动、Rockusb 枚举是否成功、进度回调是否在走;卡住往往是 USB 枚举或镜像读取问题。

5、环节 ④:升级包 update.img

device/rockchip/common/scripts/mk-updateimg.sh 用 tools/linux/Linux_Pack_Firmware/rockdev 打包 update.img。它先读 parameter.txt 生成 package-file(每行一个"分区 → 镜像"),然后按分区逐个打进去:parameter / bootloader / uboot / trust / boot / recovery / misc / oem / userdata / rootfs。

A/B 分区 :对 system_a/system_b 这类分区,打包 ab-ota 类型时跳过 _b 分区(backup 分区标记为 RESERVED 不打)。

OTA 开关 :SDK 配置 RK_UPDATE=y、RK_OTA_PACKAGE_FILE_DEFAULT=y。

排障点:"OTA 刷不上"先查升级包本身:用 upgrade_tool SFI update.img 看固件信息、分区是否与目标 parameter 一致;A/B 升级看槽位切换(misc/bootloader_message)是否正确。

6、排障对照表

现象 故障环节 处理
重启后直接进正常系统,不进 recovery ② misc 本 SDK 默认 misc 为空(RK_MISC_BLANK=y);用 reboot recovery 或强制键进入,而非烧入固件自带
recovery 卡黑屏 / 起不来 ① recovery.img 重新 ./build.sh recovery 并确认 recovery.img 已烧录;检查 recovery 分区容量是否够(128MB)
OTA 刷到一半失败 / 进度不动 ③ rkupdate / ④ 升级包 看板端 rkupdate 日志;用 SFI 检查升级包、对比分区表
提示分区不匹配 / 空间不足 ④ 升级包 vs parameter 用同一 parameter 重新打 update.img;A/B 场景检查 _a/_b 槽位

升级失败按链路定位:进不去 recovery → 查 recovery.img 是否构建/烧录、misc 引导指令(boot-recovery)是否写入、是否用 reboot recovery;OTA 刷不上 → 查板端 rkupdate 是否跑通 Rockusb、升级包分区与目标 parameter 是否匹配。两个问题,四个环节,逐个排除即可。

四、分区改了不生效、系统空间不够用?

parameter.txt 是分区布局的唯一真相。改了"没反应"、想扩容"加不进"——基本都是没理解它怎么被消费,以及 rootfs:grow 是怎么吃掉剩余空间的。

parameter.txt 是构建/烧录/打包三处的共同输入:修改后要同时让三处生效——① 重新构建镜像 → ② 重新烧录 parameter 分区 → ③ 重新打包 update.img。只改文件不重烧,当然"不生效"。另外,rootfs 是 grow 分区(吃掉所有剩余空间),想给某个分区扩容,必须同时缩小别的分区,否则空间"加不进去"。

1、parameter.txt 逐字段拆解

本 SDK 的默认分区表在 device/rockchip/.chips/rk3576/parameter.txt,实际内容如下:

 

FIRMWARE_VER: 1.0MACHINE_MODEL: RK3576MACHINE_ID: 007MANUFACTURER: RK3576MAGIC: 0x5041524BATAG: 0x00200800MACHINE: 0xffffffffCHECK_MASK: 0x80PWR_HLD: 0,0,A,0,1TYPE: GPTGROW_ALIGN: 0CMDLINE: mtdparts=:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00010000@0x00068000(backup),0x01400000@0x00078000(userdata),0x00040000@0x01478000(oem),-@0x014B8000(rootfs:grow)uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9uuid:boot=7A3F0000-0000-446A-8000-702F00006273

 

关键点:

分区布局写在 CMDLINE: mtdparts= 这一行 。构建脚本 partition-helper 就是 grep "^CMDLINE:" 后解析这一行来生成分区表的。

分区格式 0x大小@0x偏移(名字)(@ 前是大小、@ 后是偏移),单位是扇区(512B)

最后一个分区写 -  表示"无限/grow",占满剩余空间——这就是 rootfs。

uuid:boot / uuid:rootfs 给 boot/rootfs 固定 UUID(fstab、内核挂载依赖它)。

2、默认分区换算表(扇区 → 实际大小)

分区 大小(扇区) 实际大小
uboot / misc 0x2000 4MB
boot 0x20000 64MB
recovery 0x40000 128MB
backup 0x10000 32MB
userdata 0x1400000 约 10GB
oem 0x40000 128MB
rootfs -(grow) 剩余全部空间

换算:扇区数 × 512 = 字节。SDK 自带换算函数 rk_partition_size_readable_to_sector()(支持 K/M/G/0x 与 grow)在 partition-helper 里。

3、改分区的三种姿势

方式 说明
手改 parameter.txt 最直接,但改 CMDLINE: 行时容易把 offset 改乱,建议只在调整已有分区大小时用
./build.sh mod-parts 交互式编辑器(mk-partitions.sh):支持 print-parts / edit-parts / new-parts / insert-part / del-part / move-part / rename-part / resize-part,自动重排 offset 并写回 parameter.txt,推荐
Windows ParameterTool 图形工具 tools/windows/ParameterTool_v1.2/,可视化编辑,适合量产前统一配置

4、"改了不生效"的根因对照表

现象 根因 处理
改了参数文件,烧进去没变化 只改了源文件,没重新构建/没烧 parameter 分区 重新 ./build.sh 后烧 rkflash.sh all(含 di -p parameter.txt),或 rkflash.sh parameter
分区错乱 / 引导起不来 手改 CMDLINE 时 offset 没跟着推,分区重叠或断档 用 mod-parts 自动重排;改前先 print-parts 看当前布局
想扩容 rootfs 却加不进去 rootfs 是 -@...(...grow),只占"剩余空间";其它分区固定后剩余就那么多 先缩小固定分区(如 userdata 10GB、oem 128MB),rootfs 自动变大
新增分区后挂载不上 / 镜像打不进去 update.img 打包按"分区名找同名镜像"(mk-updateimg.sh);挂载按 PARTLABEL 新增分区要同名镜像 + 挂载配置(RK_EXTRA_PARTITION_* / fstab)
rootfs 挂载失败 / 找不到 动了 uuid:rootfs / uuid:boot 保留/同步 UUID;内核与 fstab 按 UUID 挂载

5、实操:给 rootfs 扩容(示例思路)

 

# 1. 看当前布局./build.sh print-parts# 2. 进入交互式修改:把 userdata 从 0x1400000 调小(如 8GB)./build.sh mod-parts> resize-part userdata 8G> print-parts   # 确认 rootfs 变大> done# 3. 重新构建并烧录 parameter 分区./build.sh./rkflash.sh parameter     # 或全量 rkflash.sh all# 4. 验证df -h /                    # 看 rootfs 实际大小lsblk                      # 看分区表

 

分区不生效 = 没让"重新构建 + 重烧 parameter + 重打镜像"三件事同步生效空间加不进去 = 忘了 rootfs 是 grow 分区,先要给固定分区让路。改分区用 mod-parts 自动维护 offset,最稳。

五、板子卡在开机画面,怎么用串口日志确定卡在哪?

卡在开机画面 ≠ 卡在内核。把启动拆成"内核 → rootfs → init"三段,看最后一条日志停在哪个阶段的哪个标志位,就能精确定位。

串口日志是启动过程的"进度条"。判断卡点就一句话:日志最后停在哪个"阶段标志"附近,问题就在那一段。本文给你三段的标志性日志与常见卡点对照表。

边界说明:U-Boot 到 "Starting kernel ..." 之前的启动段属引导加载器问题,本系列不讲(见 uboot-series 06)。本文从内核早期日志开始。

1、先确认串口能看到内核日志

RK3576 的调试串口与内核 console 由设备树 chosen 节点决定。本 SDK 的板级 bootargs(kernel-6.1/arch/arm64/boot/dts/rockchip/rk3576-linux.dtsi):

 

chosen: chosen {    bootargs = "earlycon=uart8250,mmio32,0x2ad40000 console=ttyFIQ0                root=PARTUUID=614e0000-0000 rw rootwait                rcupdate.rcu_expedited=1 rcu_nocbs=all";};

 

earlycon=uart8250,mmio32,0x2ad40000:内核早期日志输出口;

console=ttyFIQ0:正式 console(FIQ 调试口);

root=PARTUUID=614e0000-0000:rootfs 按 PARTUUID 挂载——正是 parameter.txt 里 uuid:rootfs=614e0000-0000-...(见 01.04)。

串口要能看到完整日志,需要 CONFIG_SERIAL_8250_CONSOLE=y(defconfig 已开)并且波特率与 U-Boot 串口一致。

2、三段切分法:找"阶段标志日志"

阶段 标志性日志(正常顺序) 含义
内核早期 Booting Linux on physical CPU 0x0000000000 [0x412fd050]、Kernel command line: ... 内核已接管,开始打印启动参数(能确认 bootargs 是否生效)
内核驱动 一串 [ 秒.微秒 ] ... 带时间戳的 probe 日志(本内核开了 CONFIG_PRINTK_TIME=y,时间戳来自 ARM 架构定时器) 驱动初始化;日志停在哪条附近=那个驱动/子系统卡住
rootfs VFS: Mounted root (ext4 filesystem) ...、Run /sbin/init as init process 根文件系统挂载成功、即将启动 init——rootfs 没问题的最强信号
init/系统 systemd 相关:[ OK ] Started ...、Reached target Multi-User System(Debian/Bookworm 用 systemd) 用户态系统起来了;卡在这里=应用/服务/桌面问题

3、常见卡点对照表

日志尾部特征 卡点 处理方向
没有日志 / 只有 U-Boot 后无输出 内核早期 确认 earlycon 参数与串口波特率;确认 dtb 是否真的加载到该板型
停在某个驱动 probe 后(时间戳不再前进) 内核驱动 看最后打印的驱动名,检查其 dts 节点/时钟/IO 域(见 02.04/02.05)
Kernel panic - not syncing: VFS: Unable to mount root fs rootfs root=PARTUUID 与 parameter 的 uuid:rootfs 是否一致;rootfs 镜像是否完整(见 01.04)
出现 Run /sbin/init 后无后续 init/系统 systemd 卡住:进 recovery 模式 / 单用户模式看 journal(systemctl status、journalctl -b)
画面有 logo 但无任何日志 非串口路径 可能串口没接对/波特率错,或日志级别过低——先解决"看得到日志"再谈定位

4、实操:抓一份能定位的日志

 

# 1. 串口工具(minicom/picocom)连调试串口,把完整启动日志存到文件#    波特率要与 U-Boot/内核一致(RK3576 默认调试串口,通常 1500000)# 2. 复现一次开机,保存日志# 3. 本地确认三段标志是否出现grep -E "Booting Linux|Kernel command line" boot.log          # 内核接管grep -E "VFS: Mounted root|Run /sbin/init" boot.log            # rootfs 就绪tail -50 boot.log                                               # 看卡死前最后 50 行# 4. 能进系统但慢/卡:用 dmesg 看本次启动dmesg | grep -iE "error|fail|panic" | head

 

卡在开机画面时:

 保证能看到内核日志(earlycon/console、波特率);

 看日志尾部的阶段标志——Run /sbin/init 之前卡住是内核/rootfs 问题,之后卡住是 init/系统问题;

 rootfs 卡死先核对 root=PARTUUID 与 parameter 的 uuid:rootfs 是否一致。

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分