ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RK3588 SD卡卡刷完全指南:从固件打包到SDDiskTool量产烧写

RK3588 SD卡卡刷完全指南:从固件打包到SDDiskTool量产烧写 很多搞RK3588开发的朋友应该都有过这种经历板子刷机刷到一半USB驱动死活装不上或者整批设备要出货一台一台用线刷工具连电脑效率低到怀疑人生。这时候SD卡卡刷就是那个能救命的方案。SDDiskTool_v1.78是瑞芯微官方的SD卡烧写工具专门用来把update.img固件写入SD卡做成一张能引导设备进入升级状态的“升级卡”。这篇文章我就以RK3588为例把从固件打包到SD卡烧写的完整流程拆开讲清楚顺便附上一个我自己在用的Linux打包脚本照着抄就行。整个过程覆盖三块内容RK3588卡刷包到底长什么样、怎么用脚本把散装镜像打包成update.img、以及怎么用SDDiskTool_v1.78把update.img烧进SD卡。无论是做嵌入式开发、产线量产还是自己折腾RK3588开发板这篇文章都能帮你省下大量排坑时间。1. 卡刷包、线刷包、SDDiskTool_v1.78先把概念捋清楚1.1 RK3588再强也得靠刷机活起来RK3588是瑞芯微目前的旗舰级SoC8nm工艺4个A76大核加4个A55小核GPU是Mali-G610还带了一个6 TOPS算力的NPU。这颗芯片跑Android、跑Ubuntu、跑Debian都没问题很多边缘计算盒子、NAS、智能大屏、工业HMI都在用它。但芯片再强固件装不进去就是一块砖。RK3588的启动链路支持从eMMC、SD卡、SPI NOR/NAND Flash启动同时也保留了MaskROM模式和Loader模式这两种烧写通道。开发阶段大家习惯用USB线刷也就是通过RKDevTool把固件烧进eMMC这种方式调试方便但有个前提电脑得装对驱动设备得能正常进入Loader模式。一旦设备黑屏、系统崩溃、进不了系统USB线刷可能连驱动都枚举不出来这时候SD卡卡刷的优势就体现出来了。只要设备硬件没坏、SD卡引导链路没被破坏一张做好的升级卡插进去上电就能自动进入升级流程把固件写进eMMC相当于给设备做了一次“体外循环”式的恢复。1.2 卡刷包和线刷包到底哪里不一样很多刚接触RK平台的朋友搞不清“线刷包”和“卡刷包”的区别。说白了这两者本质上装的东西是一样的都是那套固件镜像区别在于“运输方式”和“启动时机”。线刷包走的是USB通道。电脑上的RKDevTool通过USB向设备发送升级指令设备端由Loader或者MaskROM接收数据然后把各个分区镜像写入存储介质。整个过程需要电脑参与设备处于一种被动接收的状态。卡刷包走的是SD卡通道。我们把update.img烧写到SD卡的特定区域然后把SD卡插到设备上。设备上电后BootROM会尝试从SD卡引导发现SD卡里存在升级固件和升级标记就自动进入升级模式由SD卡上的固件把镜像写入eMMC。整个过程不依赖USB也不依赖电脑。这里有个关键点常见的手机卡刷包比如那些zip格式的Recovery卡刷包是进入Recovery模式后用脚本刷入系统RK平台的SD卡卡刷包则是直接利用芯片的SD卡启动链路完成烧录两者机制完全不同不要混为一谈。从实际应用场景来看我列个对比表对比项USB线刷SD卡卡刷硬件依赖USB线、电脑、驱动SD卡、读卡器适用阶段开发调试、参数修改量产、售后、救砖操作速度单台操作慢可批量速度快对设备状态要求需进入Loader/MaskROM只要SD卡引导链路完好工具RKDevToolSDDiskTool_v1.78所以在我自己的项目里调试阶段用线刷一旦固件版本稳定了全部转成SD卡卡刷产线上一张卡能连续刷几十台设备效率完全不是一个量级。1.3 SDDiskTool_v1.78在这条链路里的位置SDDiskTool_v1.78是瑞芯微官方提供的Windows图形化工具它的作用非常专一把update.img固件烧写到SD卡上并对SD卡进行分区和标记使其成为一张可以被RK芯片识别并引导的升级卡。注意SDDiskTool本身不负责生成固件它只负责把固件“灌”进SD卡。所以完整的卡刷包制作链路是在Linux环境下用打包脚本把boot、system、vendor、uboot等散装镜像打包成update.img。把update.img拷贝到Windows电脑。用SDDiskTool_v1.78选择SD卡、选择update.img、点击烧写。把烧好的SD卡插到RK3588设备上上电设备自动完成升级。v1.78这个版本对RK3588的支持已经比较完善。老版本的SDDiskTool可能识别不了RK3588的loader或者烧写时分区表不兼容所以如果你用的是RK3588尽量选新版本工具。2. 制作前的准备RK3588固件拆解与工具链选型2.1 RK3588固件包里到底装了什么东西整个RK平台的update.img本质上是一个“容器”文件里面装了两类东西一类是引导程序一类是系统分区镜像。引导程序就是我们常说的loaderRK3588平台通常是一个叫rk3588_spl_loader_v*.bin的文件也可能叫RK3588MiniLoaderAll.bin。它负责初始化DDR、存储控制器然后把系统分区镜像搬运到对应的存储位置。系统分区镜像就是设备真正运行时要用的那些分区。RK3588的Android固件一般包含这些部分分区镜像作用parameter.txt分区表描述文件定义每个分区的起始位置和大小uboot.imgU-Boot引导程序boot.imgLinux内核与DTB设备树recovery.img恢复模式镜像system.imgAndroid系统核心vendor.img厂商定制库和硬件抽象层odm.img设备制造商定制内容misc.img启动模式标记分区如果做Linux系统则可能是boot.img、rootfs.img、resource.img这类组合。但不管什么系统parameter.txt都是灵魂——它决定了镜像在eMMC上的布局如果parameter和实际镜像不匹配刷完大概率开不了机。现在很多新的RK方案采用GPT分区表但parameter文件依然存在只是格式更复杂了。生产环境中parameter文件通常由SDK编译时根据BoardConfig生成我们打包的时候直接拿编译产物里的就行不用手动写。2.2 从零组包需要的工具afptool和rkImageMaker打包update.img核心工具是两个afptool和rkImageMaker。afptool负责把一堆零散的镜像文件打包成一个firmware.img同时记录分区名和偏移信息。解包的时候反过来把firmware.img里各分区镜像提取出来。rkImageMaker负责把loader和firmware.img合并成最终的update.img。它会在文件头部写入loader并把打包时间、芯片型号、系统类型等信息记录进去。烧写时SDDiskTool就是根据update.img里的loader信息来判断芯片支持情况的。这两个工具在瑞芯微官方SDK的RKTools/linux目录下都能找到Linux版本直接可执行Windows版本也有对应exe。我自己习惯在Linux编译服务器上跑打包脚本生成update.img后再拷贝到Windows机器上操作SDDiskTool。如果你手头只有别人给的一个update.img也可以先解包出来看结构。命令行大概是这样的# 解包update.img得到loader和firmware.img ./rkImageMaker -unpack update_old.img unpack_temp/ # 解包firmware.img得到各个分区镜像 ./afptool -unpack unpack_temp/firmware.img unpack_image/把解出来的文件改一改再用打包脚本重新封装这就是二次定制固件最常用的套路。2.3 环境准备Linux打包机Windows烧写机我建议你按“双机协作”的方式来搭环境。打包脚本跑在Linux上SDDiskTool_v1.78跑在Windows上。原因很简单第一瑞芯微官方提供的afptool和rkImageMakerLinux版本编译好后是纯命令行工具适合写进脚本自动化执行。第二SDDiskTool_v1.78只有Windows版本而且它是图形界面操作批量烧卡时反而直观方便。整个环境就三样东西一台Linux电脑装了bash能运行afptool和rkImageMaker。一台Windows电脑装了SDDiskTool_v1.78插着一张SD卡读卡器。一个用于传递文件的U盘或者局域网共享目录。如果你的Linux机器和Windows机器是同一台电脑那就用WSL或者虚拟机跑脚本再把生成的update.img复制到Windows桌面操作SDDiskTool。实测下来WSL里跑这两个工具没有任何问题。注意SD卡别用太差的Class 10以上的正规品牌卡最稳妥。我见过太多烧写失败案例最后排查下来都是SD卡本身写入不稳定导致的。3. 完整打包脚本一键生成RK3588卡刷包3.1 脚本设计思路为什么要写成脚本之前我有段时间手动打包固件每次都要敲那一长串rkImageMaker命令参数还不能敲错。后来改成脚本一条命令搞定解包和打包而且还能自动检查关键镜像文件是否存在省去了很多低级错误。这个脚本我设计了三个功能解包update.img、打包update.img、检查打包后的文件。核心逻辑并不复杂就是调用官方工具做封装加上一些文件存在性检查和日志输出。用到的shell语法也很基础变量、函数、for循环、if判断没有任何高级技巧但实用性很强。脚本的目录规划是这样rk3588_build/ ├── build_update.sh # 主脚本 ├── tools/ # 放afptool、rkImageMaker、loader │ ├── afptool │ ├── rkImageMaker │ └── rk3588_spl_loader_v1.08.111.bin ├── unpack/ # 解包临时目录 ├── image/ # 存放散装镜像的目录 └── output/ # 输出update.img的目录3.2 完整脚本代码下面就是完整的打包脚本你可以直接保存为build_update.sh使用#!/bin/bash # # RK3588 update.img 解包/打包脚本 # 适用于 SDDiskTool_v1.78 卡刷包制作 # 用法: # ./build_update.sh unpack update.img # ./build_update.sh pack image目录 # set -e # ---------- 工具链路径配置 ---------- TOOL_DIR$(cd $(dirname $0) pwd) TOOLS$TOOL_DIR/tools LOADER$TOOLS/rk3588_spl_loader_v1.08.111.bin RK_IMAGE_MAKER$TOOLS/rkImageMaker AFP_TOOL$TOOLS/afptool UNPACK_DIR$TOOL_DIR/unpack OUTPUT_DIR$TOOL_DIR/output # ---------- 日志颜色 ---------- RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m NC\033[0m log_info() { echo -e ${GREEN}[INFO]${NC} $1 } log_warn() { echo -e ${YELLOW}[WARN]${NC} $1 } log_error() { echo -e ${RED}[ERROR]${NC} $1 exit 1 } # ---------- 检查工具链 ---------- check_tools() { [ -x $RK_IMAGE_MAKER ] || log_error 找不到 rkImageMaker请把它放到 $TOOLS 目录 [ -x $AFP_TOOL ] || log_error 找不到 afptool请把它放到 $TOOLS 目录 [ -f $LOADER ] || log_warn 找不到 RK3588 loader 文件打包时会失败请确认文件名是否正确 log_info 工具链检查完毕 } # ---------- 解包功能 ---------- do_unpack() { local SRC_IMG$1 if [ ! -f $SRC_IMG ]; then log_error 固件文件不存在: $SRC_IMG fi rm -rf $UNPACK_DIR mkdir -p $UNPACK_DIR log_info 第1步: 使用 rkImageMaker 分离 loader 和 firmware $RK_IMAGE_MAKER -unpack $SRC_IMG $UNPACK_DIR || log_error rkImageMaker 解包失败 log_info 第2步: 使用 afptool 解包 firmware 到 $UNPACK_DIR/image mkdir -p $UNPACK_DIR/image $AFP_TOOL -unpack $UNPACK_DIR/firmware.img $UNPACK_DIR/image || log_error afptool 解包失败 log_info 解包完成分区镜像位于: $UNPACK_DIR/image ls -lh $UNPACK_DIR/image } # ---------- 打包功能 ---------- do_pack() { local SRC_DIR$1 if [ ! -d $SRC_DIR ]; then log_error 固件目录不存在: $SRC_DIR fi mkdir -p $OUTPUT_DIR local TMP_FIRMWARE$OUTPUT_DIR/firmware.img.tmp local OUT_IMG$OUTPUT_DIR/update.img log_info 第1步: 检查固件目录中的关键镜像 local REQUIRED_FILES(parameter uboot.img boot.img recovery.img system.img vendor.img) for f in ${REQUIRED_FILES[]}; do if [ -f $SRC_DIR/$f ] || [ -f $SRC_DIR/$f.img ] || [ -f $SRC_DIR/$f.bin ]; then log_info 找到: $f else log_warn 缺少: $f (如果是Linux系统部分镜像没有是正常的) fi done log_info 第2步: 使用 afptool 打包分区镜像 $AFP_TOOL -pack $SRC_DIR $TMP_FIRMWARE || log_error afptool 打包失败 log_info 第3步: 使用 rkImageMaker 生成最终 update.img $RK_IMAGE_MAKER -RK3588 $LOADER $TMP_FIRMWARE $OUT_IMG -os_type:androidos || log_error rkImageMaker 打包失败 rm -f $TMP_FIRMWARE log_info 打包完成: $OUT_IMG ls -lh $OUT_IMG } # ---------- 主函数 ---------- usage() { cat EOF RK3588 update.img 打包/解包脚本 用法: ./build_update.sh unpack update.img 解包固件到 unpack/ 目录 ./build_update.sh pack image目录 从镜像目录打包生成 update.img 示例: ./build_update.sh unpack ./update_android12.img ./build_update.sh pack ./image EOF } main() { local CMD$1 local ARG$2 case $CMD in unpack) [ -z $ARG ] { usage; exit 1; } check_tools do_unpack $ARG ;; pack) [ -z $ARG ] { usage; exit 1; } check_tools do_pack $ARG ;; *) usage exit 1 ;; esac } main $3.3 脚本关键点说明先说set -e。这行代码的意思是脚本中任何一条命令返回非零退出码整个脚本立刻终止。打包流程里afptool或rkImageMaker只要任何一个失败后面步骤就没必要继续了所以这个参数一定要加。再说for循环检查镜像文件。这段代码是给操作者一个预警机制。RK3588的Android固件boot、system、vendor这些分区必须有如果打包目录里缺了system.img这种关键镜像生成出来的卡刷包刷进去肯定开不了机。脚本不会强行阻止打包但会给出警告提醒你确认是不是漏拷贝了文件。然后看rkImageMaker的参数。-RK3588指定芯片型号-os_type:androidos指定系统类型。如果你打包的是Linux系统把这个参数改成-os_type:linux。很多朋友打包Linux固件时忘了改这个参数结果刷进设备后分区识别不对折腾半天。最后说工具路径。脚本里的LOADER变量指向tools目录下的loader文件不同SDK版本loader文件名不一样如果你的文件名是RK3588MiniLoaderAll.bin改一下LOADER变量就行别忘了赋予执行权限chmod x build_update.sh tools/afptool tools/rkImageMaker3.4 脚本使用演示解包一个现成的RK3588固件命令是这样./build_update.sh unpack ./update_android12.img执行后unpack/image目录下就会出现所有分区镜像包括parameter、uboot、boot、system等。如果你只想改其中一个文件比如替换kernel那就在image目录里把boot.img换成新的然后重新打包。打包的命令是这样./build_update.sh pack ./unpack/image如果一切正常output目录下就会生成一个新的update.img。这个文件就是SDDiskTool_v1.78要用的卡刷包。我自己通常在修改完image目录里的文件后直接一条命令打包再复制到Windows机器烧SD卡整个流程不超过两分钟。4. 实操记录SDDiskTool_v1.78烧写SD卡全流程4.1 烧写模式选择升级卡还是启动卡打开SDDiskTool_v1.78你会看到界面上有一个“烧写模式”选项通常有“烧写”和“启动”两种模式。这两个模式很多人会搞混我花点时间讲清楚。“烧写”模式也叫升级卡模式。SDDiskTool会把update.img写入SD卡的特定分区同时写入升级标记。设备从SD卡启动后发现升级标记就自动把固件烧写到设备内部的eMMC里。烧写完成后拔掉SD卡设备从eMMC启动系统。这是标准的卡刷流程用于量产、升级、救砖。“启动”模式也叫SD卡启动盘模式。SD卡的镜像不会写入设备内部存储而是直接从SD卡运行系统。可以理解为把RK3588设备变成一个类似“无盘工作站”的东西拔掉SD卡设备就是空的插上SD卡就能跑系统。这个模式适合做系统评估、硬件测试不适合做量产刷机。我们的目标是卡刷包所以选“烧写”模式。4.2 SDDiskTool_v1.78具体操作步骤第一步把SD卡插入读卡器再把读卡器插到Windows电脑上。注意SDDiskTool会直接操作物理磁盘所以SD卡里的数据会被清空操作前务必确认卡里没有重要文件。第二步打开SDDiskTool_v1.78。工具会自动识别已插入的SD卡在设备列表区域显示磁盘信息比如磁盘编号、容量、厂商型号。如果你的SD卡没有被识别换个读卡器试试这一条我后面在常见问题里详细讲。第三步在“固件”选择区域点击“选择”按钮找到我们刚才生成的update.img文件。选中后工具会解析固件信息显示芯片型号和loader版本。如果提示“不支持的芯片类型”说明update.img不是RK3588平台的文件或者你下载的固件本身有问题。第四步确认烧写模式选的是“烧写”然后点击“烧写”按钮。此时工具开始格式化SD卡、写入IDB引导块、写入各分区镜像界面上的日志窗口会滚动显示进度信息。第五步等待日志窗口出现“烧写完成”或类似提示。整个过程中不要去拔SD卡不要关闭工具不要对电脑做重启操作。烧写时间取决于SD卡速度和固件大小一般2GB左右的固件用Class 10的卡大概需要3到5分钟。烧写完成后安全弹出SD卡插到RK3588设备上开始卡刷。注意有些SD卡烧写完成后Windows会弹窗提示“需要格式化磁盘”。这是正常的因为SDDiskTool已经改变了SD卡的分区结构。千万别点“格式化”否则升级卡就被破坏了。4.3 目标设备端升级操作SD卡做好之后剩下的操作就在设备端了。把升级SD卡插到RK3588设备的卡槽里。如果设备之前有系统且能正常进入通常可以直接在系统里执行adb reboot recovery命令让设备重启并进入恢复流程。如果设备已经黑屏无法进入系统那就在断电状态下插入SD卡然后给设备上电BootROM会自动检测SD卡上的升级固件。设备进入升级流程后屏幕可能持续黑屏也可能显示升级进度画面这取决于固件里有没有配置升级动画。判断升级是否完成最简单的方法是观察设备的电源指示灯或者通过串口查看日志。升级完成后设备会自动重启。我建议在升级完成后先把SD卡取下来再让设备彻底断电重启避免设备再次从SD卡引导反复进入升级流程。5. 常见问题排查与踩坑实录5.1 SD卡容量识别异常工具找不到设备这个问题的出现频率非常高。现象是SD卡明明插上了Windows资源管理器也能看到盘符但SDDiskTool_v1.78识别不到或者识别出来容量显示为0。排查看两个方面。第一读卡器兼容性问题。很多山寨读卡器在传输数据时没有问题但SDDiskTool需要直接对SD卡发送底层控制命令部分读卡器对这类命令支持不完整导致工具无法识别。我实测过换成USB3.0的品牌读卡器后问题基本消失。第二SD卡本身可能是扩容卡或者损坏卡。用ChipGenius或者H2testw这类工具检查一下如果SD卡实际容量远小于标称容量那就直接换卡不值得在这种卡上浪费时间。5.2 烧写进度条长时间卡住不动烧写过程中卡住超过10分钟没有进度变化基本可以判定烧写失败了。常见原因有三个一是SD卡有坏块。这种卡建议直接报废或者用SD卡制造商提供的量产工具做一次全盘擦除再试。二是SD卡读写速度太慢尤其是那些Class 4的老卡写入大镜像时速度跟不上工具容易出现假死。三是镜像文件本身不完整比如update.img在拷贝过程中损坏了。排查顺序建议是先换一张固态U盘级别的SD卡试烧如果问题依旧重新拷贝一份update.img再试如果还不行检查工具的版本是否太老。5.3 设备卡刷后无法正常开机这类问题先别急着怪SD卡。第一步检查串口日志RK3588的调试串口在设备上电后会打印芯片初始化信息能看到它是否成功加载了loader、是否识别了SD卡上的固件。第二步检查parameter分区表。如果刷入的parameter和实际镜像布局不一致比如system分区该在的位置被写成了vendor那启动时挂载system分区就会失败导致卡在开机动画或者反复重启。第三步检查loader版本。个别设备在出厂时锁定了特定的loader版本如果卡刷包里的loader不兼容设备可能根本无法进入升级流程。解决办法是从设备开发商提供的原厂固件中提取loader换到我们的打包目录里重新打包。5.4 同一张SD卡第二次烧写失败这是一个比较隐蔽的坑。同一张升级卡第一次刷机一切正常第二次烧写时要么提示空间不足要么烧写过程中报错。原因在于设备升级完成后SD卡上的升级标记并没有完全清除。SDDiskTool再次烧写时需要先对SD卡做一次完整的“恢复存储卡”操作。你可以在SDDiskTool的界面上找到“清空”或“恢复”功能先把SD卡恢复成普通的可移动磁盘再重新执行烧写步骤。如果工具上没有这个功能就用Windows的磁盘管理工具把SD卡所有分区删掉新建一个FAT32分区然后再回到SDDiskTool烧写。注意删除分区时会弹警告确认选对磁盘再操作。踩过几次坑之后我自己的一些习惯卡刷包这套流程我前后用了快两年折腾过的设备加起来也有上百台了总结几个自己的土办法。第一打包脚本生成的update.img我会习惯性用rkImageMaker解包一次确认loader和分区都能正常解开再拿去烧SD卡。虽然多花几十秒但能提前发现镜像损坏问题不至于到了设备端才发现。第二SD卡我会按批次贴上标签哪个批次烧了什么固件版本都记录在案。因为卡刷做多了不同版本的SD卡混在一起很容易拿错卡刷错固件的后果可比重新烧一张卡麻烦多了。第三每次给SDDiskTool选择固件时我会看一眼工具识别出来的loader版本和芯片型号确认是RK3588再继续操作。这个动作很简单但能避免很多“刷完开不了机”的问题反复出现。
返回列表