ARTICLE DETAIL

资讯详情

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

RK3568开发板OpenHarmony刷机实战:从SD卡启动到eMMC烧录全流程

RK3568开发板OpenHarmony刷机实战:从SD卡启动到eMMC烧录全流程 刚拿到一块 RK3566/RK3568 的开发板想把 OpenHarmony 跑起来第一道坎往往不是编译而是怎么把系统刷进去。很多教程把刷机写得玄乎其实拆开看就三件事让板子能从 SD 卡启动、把系统烧进 eMMC、处理好分区表让系统能认盘。这篇就围绕“SD-eMMC-单分区”这条完整链路把 OpenHarmony 刷机的全流程走一遍。整个过程我会按实际操作的顺序来讲包括为什么选单分区、SD 卡怎么处理、eMMC 烧录用什么工具、遇到 110 这类报错怎么定位适合刚接触 OpenHarmony 设备开发、准备在 RK 平台板上做系统移植或固件验证的朋友参考。1. 项目整体设计与思路拆解1.1 明确刷机目标SD 启动与 eMMC 烧录分别解决什么问题先说一个容易混淆的点很多人以为刷机就是把固件往 eMMC 里一写就完事。实际上在 OpenHarmony 开发中SD 卡和 eMMC 承担着不同的任务。SD 卡启动的核心价值是“快速迭代”。编译出来的系统镜像动辄几百 MB甚至是多个分区的完整镜像。如果每次都往 eMMC 里烧一次烧录要几分钟而且烧坏了还要想办法恢复。用 SD 卡启动插上去就能跑拔下来就能改极大缩短开发调试的反馈周期。在 OpenHarmony 这类大型系统开发里SD 卡口几乎是开发者的“逃生通道”。eMMC 烧录的核心价值是“产品化落地”。调试结束之后系统最终要跑在板载存储上不能依赖外部 SD 卡。设备的正常启动流程是 BootROM → 引导加载程序 → 内核 → 用户态服务而这个链路在正式产品里必须全部从 eMMC 读取。所以烧录 eMMC 是让板子从“开发态”变成“可交付态”的必经步骤。那“单分区”又是什么意思OpenHarmony 的通用镜像通常涉及多个分区比如 boot、system、vendor、userdata 等。单分区方案在实践中通常指一种简化的镜像布局把内核、ramdisk、根文件系统整合到一个分区中通过 read-only 根文件系统 可写数据分区的方式工作。对于开发板刷机验证场景单分区方案配置简单、维护容易、出问题的排查面小是我在实操中比较推荐的方式。1.2 为什么选 RK3568 平台设备树与刷机关联很紧密OpenHarmony 对 RK3568 系列芯片支持比较完善社区和官方代码仓里有大量可参考的默认配置。但这也带来一个尴尬源码里设备树文件很多到底该选哪个比如rk3568-evb1-ddr4-v10.dtb、rk3568-evb2-lpddr4-v10.dtb、rk3568-evb2-lpddr3-v10.dtb这类命名初看很容易懵。这个选择核心看三样东西板子的 SoC 型号、内存颗粒类型、板厂对 GPIO 和外围接口的复用定义。比如 EVB1 和 EVB2 的硬件接口定义本身就有差异DDR4 和 LPDDR4/LPDDR3 的驱动时序也不同。选错了设备树最典型的现象有两个要么内核启动阶段直接 panic要么启动到一半发现某个外设 probe 失败——因为没有节点描述这个 GPIO 对应的功能。刷机前务必根据板卡型号确认设备树名称不要想当然地拿默认 dtb 一把梭。1.3 “SD-eMMC-单分区”方案的适用场景与局限这套方案最典型的适用场景是你拿到一块 RK 板卡OpenHarmony 源码已经能编译通过当前核心目标是先把固件跑到桌面/系统界面验证基础外设和系统服务。此时 SD 启动 eMMC 烧录 单分区布局能够以最小的配置复杂度完成验证。局限性也要说清楚单分区方案在生产环境并不常见原因在于系统升级牵扯整个分区重写而不是只更新某个子模块而多分区方案下的 A/B 分区、OTA 增量升级、userdata 独立格式化等能力在量产的设备上几乎是必需品。所以如果你是做产品级方案评估还是建议日后切换到标准多分区布局本文这套流程更适合开发调试和教学验证。2. 刷机前置准备与核心原理2.1 硬件准备清单与连接方式实际刷机的硬件准备并不复杂但每一件都有可能让你卡壳我列一个清单供对照一台 Ubuntu 主机建议 18.04 或 20.04Windows 下做 eMMC 烧录工具兼容性麻烦后续尽量用 UbuntuRK3568 开发板根据板卡型号选择对应设备树一张 Micro SD 卡建议 16GB 以上品牌不限但质量要靠谱劣质卡在写 eMMC 时长时段读拷数据容易出错一个读卡器用于在主机上制作 SD 启动卡USB Type-C 数据线用于烧写 eMMC 时让板子进入 MaskROM/Loader 模式连接顺序建议先插 SD 卡、接电源、再连 USB 线到 Ubuntu 主机最后按下板子的 recovery 键并重新上电进入烧录模式。这样能尽量避免 USB 枚举失败。2.2 软件工具链刷机工具、镜像工具和系统工具OpenHarmony 刷机涉及的软件工具主要有这么几类烧录工具RK 平台的工具链核心是RKDevToolWindows 版本和 Linux 下的upgrade_tool有时也叫rkdeveloptool。它们负责和设备端的烧录协议通信将镜像逐 block 写入 eMMC。编译 OpenHarmony 的 RK 平台镜像产物中通常会生成一个config.cfg或分区表描述文件烧录工具按这个配置解析各个分区的偏移地址和大小。SD 卡格式化工具SD Memory Card Formatter 是 SD 协会官方的格式化工具推荐使用。它比操作系统自带的格式化工具更“懂” SD 卡的内部结构和擦除块边界能清除分区残留信息。注意普通格式化不会抹掉 U-Boot 写进 SD 卡特定扇区的引导代码所以如果你要做“干净卡”建议用这个工具选择“Overwrite format”。系统处理工具主要涉及dd、fdisk、parted、gpt这些 Linux 工具。制作 SD 启动卡本质上就是往 SD 卡的特定偏移位置写入引导镜像和分区镜像dd是这里的主力工具。2.3 固件获取和校验从我实际操作的经验来看刷机失败的根源中固件本身损坏或被截断的情况不在少数。如果你是从编译服务器拉取镜像建议固定用一个 SHA-256 校验流程sha256sum 镜像文件把生成的值和编译日志或官方发布说明中的值比对。另外OpenHarmony 编译产物路径通常在out/rk3568/packages/phone/images/下面这里会有boot_linux.img、system.img、vendor.img、uboot.img等。用哪个取决于你的烧录方式如果你走完整 eMMC 烧录则需要把所有分区镜像一次性写入如果从 SD 卡启动往往只需要uboot.img、boot_linux.img和system.img这几个关键部分。提示不要用来源不明的二手镜像。开发中的 OpenHarmony 版本推进很快编译工具链和内核接口不匹配的话镜像本身没问题也会在启动阶段抛出奇怪的错误。3. 分步实操从空白 SD 卡到 eMMC 烧录3.1 制作 SD 启动卡分区表设计与写卡细节这一节是整个流程的基础。先说分区表设计。单分区方案下我的推荐做法是不维护复杂的 GPT 分区表而是直接用dd把引导镜像按偏移写入再用传统 MBR 分区表放一个可写的 userdata 分区。有的朋友会问这样是不是有点“野”其实在开发板上非常常见因为 OpenHarmony 的引导加载程序在 SD 启动模式下不一定按照标准分区表去找内核它有自己固定的扇区偏移。具体怎么做呢在 Ubuntu 主机上先确认 SD 卡设备名。插上读卡器后执行lsblk一般会看到类似/dev/sdb的设备千万确认清楚别把电脑硬盘给 dd 了。确认后开始做卡sudo dd ifuboot.img of/dev/sdb bs512 seek64 sudo dd ifboot_linux.img of/dev/sdb bs512 seek16384这里seek的偏移量是怎么来的RK 平台在 SD 卡启动时BootROM 会从 SD 卡的扇区 64即偏移 32KB 处开始检索 U-Boot 的 idblock。U-Boot 编译产物里包含了 idblock 信息写到 64 扇区是通用约定。boot_linux.img写到 16384 扇区也就是偏移 8MB 处这是 U-Boot 环境变量里配置的默认加载地址对应的偏移。如果你改过 U-Boot 的CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR这个配置需要按实际值调整。写完这两个镜像后再创建 userdata 分区sudo fdisk /dev/sdb交互式操作中建议先p打印当前分区表然后d删除已存在的分区如果之前格过再n新建主分区大小根据卡容量自行分配。创建完成后w写入并退出最后格式化sudo mkfs.ext4 /dev/sdb1至此一张 SD 启动卡就制作完成。插入板子并上电如果看到串口输出 U-Boot 日志并进入内核启动流程说明 SD 启动正常。3.2 烧写 eMMC 的两种方式从 SD 卡烧与从 USB 烧eMMC 的烧录路径有两条我分别讲一下因为不同场景下选择不一样。方式一从 SD 卡系统内部烧写 eMMC这种方式适合你已经从 SD 卡启动到了 OpenHarmony 系统或者进到了 U-Boot 命令行。在 U-Boot 里可以这样写 eMMCmmc dev 1 fatload mmc 0:1 ${loadaddr} update.img mmc write ${loadaddr} 0 0x2000实际上 OpenHarmony 的update.img是一个打包好的完整升级镜像可以用upgrade_tool烧写也可以直接在 U-Boot 下逐块写。这种方式的优点是不需要额外的 USB 线而且能看到每一块的写入进度缺点是如果 eMMC 本身没烧过任何可用引导板子无法启动到 U-Boot那这个方式就无从谈起。方式二从 USB 烧写MaskROM/loader 模式这是最主流、最可靠的完整烧录方式。操作要点如下完全断电拔掉 SD 卡避免干扰 eMMC 枚举按住板子上的 recovery 按键或 MaskROM 按键不同板卡位置不同建议看板卡原理图或丝印通过 USB Type-C 线连接 Ubuntu 主机上电保持按键按住 3~5 秒后松开。此时设备应被识别为处于 Loader 模式。在 Ubuntu 下用rkdeveloptool工具可以查看设备连接状态sudo rkdeveloptool ld如果输出类似DevNo1 Vid0x2207 Pid0x350b之类的信息说明设备已正确枚举。整个 eMMC 烧录的过程核心是先擦除再逐个分区写入sudo rkdeveloptool db rk3568_loader.bin sudo rkdeveloptool ul update.imgdb命令是下载 bootloader 到 SRAM 中运行ul命令是升级固件它会解析update.img里的分区表并自动写入。如果单独刷某个分区或者在调试中想只更新 boot 镜像可以用sudo rkdeveloptool wl 0x4000 boot_linux.img0x4000是boot_linux.img在 eMMC 上的偏移单位为扇区0x4000 16384 扇区 8MB。这组偏移必须与你的分区表配置保持一致。3.3 单分区布局下的参数计算与偏移量讲解这里补一下偏移计算的逻辑。eMMC 的地址通常按照 512 字节扇区为单位。OpenHarmony 默认的 RK3568 分区布局里uboot分区起始于偏移 0x2000 扇区也就是 4MB 处因为它前面需要留出 4MB 给 SPL/Trust 固件。boot分区起始于偏移 0x4000 扇区8MB 处一般大小 64MB。system分区起始于0x20000扇区64MB 处大小依据磁盘总容量动态调整。在单分区方案中我们要做减法把原本分散的 boot、system 逻辑合并成一个启动分区。操作上可以把内核镜像和根文件系统都打包进boot_linux.img或者保持boot分区独立但 rootfs 直接编译进内核镜像的 initramfs 中。前面我推荐保持原有分区表但用 SD 启动做验证就是因为在开发阶段多保留一个分区并不会带来额外负担而真正需要精简时再将 system 分区合并进去。这里给出一张我整理的常用偏移速查表镜像偏移地址扇区偏移大小说明idblock/SPL6432KBBootROM 固定读取位置不可随意更改uboot.img0x20004MBU-Boot 主镜像U-Boot 自己也会根据环境变量重新定位boot_linux.img0x40008MB内核 dtb ramdisksystem.img0x2000064MB系统分区起始位置单分区时 rootfs 挂载于此userdata动态动态用 fdisk 创建存放可写数据这张表在不同 SDK 版本间可能有差异你在拿到具体代码包后一定先看编译生成的parameter.txt或config.cfg那才是这个版本真正的分区布局。3.4 设备树选择的实操考量前文提到了设备树选择问题这里展开讲。在 OpenHarmony 的 RK3568 内核源码路径kernel/linux/arch/arm64/boot/dts/rockchip/下你会看到大量 dts 文件。选择的关键点按优先级排序SoC 型号必须一致RK3568J、RK3568 等注意 J 代表车规级部分外设差异明显内存颗粒类型必须匹配DDR4/LPDDR4/LPDDR3决定 DDR 初始化时序板级外设接口尽量贴近I2C、SPI、UART、GPIO 扩展、LCD 型号等。如果你的板子是第三方的核心板而厂商只提供了 Android 的 dtbOpenHarmony 通常也能沿用因为内核版本大部分是 5.10 或相近分支只要确认 dts 引用的宏和头文件在 OpenHarmony 内核源码树中存在即可。实操中最快的验证方法是先拿默认 EVB 的 dtb 试启动U-Boot 阶段能看到日志说明引导链路通如果卡在内核阶段并反复重启大概率是内存初始化或串口控制台没有对齐这时再针对板卡设备树做裁剪。4. 常见问题与排查技巧实录4.1 eMMC 偶发报错“-110”的定位与解决这个报错在刷机和启动过程中都遇到过表示命令超时-ETIMEDOUT。在 eMMC 读写场景下常见诱因有三种电压不稳。eMMC 在高速模式HS200/HS400下对 VCCQ 电源质量要求较高劣质电源适配器导致电压跌落时控制器命令超时。时序参数不匹配。板级电路走线较长或者 eMMC 颗粒本身对时序要求严格U-Boot 里的mmc驱动需要手动降低速率模式。镜像写入过程中主机断开。USB 供电不稳导致擦写流程中断eMMC 进入异常状态。排查步骤我建议按这个顺序来先换电源适配器高功率、稳压性能好的再在 U-Boot 环境变量中强制降速比如把mmc的speed-mode设为ddr52或者high-speed最后检查 USB 线缆和接口尽量直连主机后置 USB 口不经过 Hub。注意不要把-110当成偶发问题忽略。eMMC 有坏块管理机制但如果同一个位置反复超时可能是该存储区域已接近寿命极限建议用mmc read/mmc write循环测试确认坏块是否持续扩大。4.2 U-Boot 无打印信息的排查很多人刷完 SD 卡后上电发现串口什么输出都没有第一反应是“镜像坏了”。但从我的经验看无打印的根因按出现频率排序是串口线接错或电平不匹配。RK 平台的调试串口一般是 TTL 电平如果你用 USB 转串口模块要确认交叉连接TX-RX、共地以及波特率设置常见 1500000 波特率SD 卡引导写失败了。卡里没有有效的 idblockBootROM 找不到启动代码上电时序问题。部分核心板需要先给 IO 域供电再给核心供电开发底板上电顺序不正确会导致 BootROM 没有完成初始化。如果 U-Boot 一开始就没打印先验证串口通路的畅通用 USB 转串口模块短接 TX 和 RX看是否能回显再用示波器或万用表确认板卡是否有 3.3V 的 UART 信号。这个能排除至少一半问题。4.3 SD 卡启动时挂载不了根文件系统怎么办在内核启动阶段日志停在这里VFS: Cannot open root device mmcblk0p1 or unknown-block(179,1)这是典型的 root 设备参数没对上。单分区方案下根文件系统在 SD 卡的哪个分区、什么文件系统类型都需要在 U-Boot 环境变量中告知内核。检查这几个参数setenv bootargs root/dev/mmcblk0p1 rw rootfstypeext4 consolettyFIQ0,1500000 saveenv如果是 MMC 设备的编号不对需要确认mmcblk0是 SD 卡还是 eMMC。SD 卡在部分内核版本中可能枚举为mmcblk1这取决于控制器注册顺序。在 U-Boot 里执行mmc list可以查询当前的 MMC 设备列表用mmc dev 0或mmc dev 1分别切换后再mmc info确认是哪张卡。4.4 常见问题速查表为方便对照这里整理一个我实际刷机中遇到的高频问题汇总现象可能原因解决方案USB 无法识别设备未进入 Loader/MaskROM 模式按住 recovery 键上电用rkdeveloptool ld检测烧录到一半提示设备断开USB 线材质量差或电源不稳换数据线避免前置 USB 口使用稳压电源内核启动后反复重启设备树选错内存参数不匹配换对应板卡的 dtb检查 DDR 类型系统启动后 SD 卡没有挂载分区表未创建或未格式化用 fdisk 创建分区mkfs.ext4 格式化eMMC 写入速度极慢降速模式过于保守换 HS200/HS400 模式而非 DDR52刷机后无法从 eMMC 启动引导顺序未切换确认 U-Boot 环境变量 boot_device 或启动拨码开关4.5 几个不常被提及但非常实用的避坑技巧第一SD 卡格式化一定要用 SD Memory Card Formatter而不要图省事用mkfs直接覆盖。因为部分 U-Boot 版本会在 SD 卡末尾区域保存环境变量冗余 env 分区如果你用操作系统工具重新分区这块区域可能没被清除下一次启动时旧环境变量会干扰启动参数。第二rkdeveloptool擦除 eMMC 前务必再三确认设备。因为擦除命令是按设备号操作的如果你主机上同时插了多个 RK 设备rkdeveloptool ld会列出多个而默认操作目标是第一个。谨慎的做法是拔掉其他设备只保留目标板。第三烧录 eMMC 之前强烈建议先备份原始固件。特别是核心板自带的 Android 镜像如果后续要回退没有原始备份会非常被动。在 Loader 模式下sudo rkdeveloptool rl 0 0x100000 backup.img可以把 eMMC 前 512MB 内容整个导出。这样即使分区表被破坏也有原始数据可以恢复。第四OpenHarmony 镜像名的后缀与版本强相关。某些版本system.img实际上是稀疏镜像sparse image烧录时工具会做转换而某些工具和驱动版本对稀疏镜像支持不佳导致写入后分区大小异常。遇到这类问题时可以先解包稀疏镜像再烧录simg2img system.img system_raw.img然后用system_raw.img执行烧写往往会顺利很多。5. 串口日志解读与启动链路验证5.1 一份正常启动日志的关键节点刷机完成后怎么判断系统是否正常启动看串口日志是最直接的方式。一份正常的 OpenHarmony 启动日志中有几个关键节点值得关注第一阶段BootROM 打印通常带有DDR初始化相关的微码信息表明 eMMC/SD 控制器已经枚举成功第二阶段U-Boot 的版本横幅包含日期和编译信息说明 idblock 和 U-Boot 主镜像已正确加载第三阶段内核解压以及设备树加载能看到Booting Linux on physical CPU 0x...和Kernel command line:这里的 bootargs 要和你的分区方案匹配第四阶段系统服务启动OpenHarmony 特有的服务管理进程开始工作最终出现OHOS相关字样或产品 logo。如果在第三阶段后长时间没有输出大概率是设备树与硬件不匹配或者根文件系统没挂上。这时不要盲目重新编译先用printenv查看 U-Boot 环境变量里的 bootargs确认 root 指向是否正确。5.2 用串口信息反向确认分区和镜像串口不仅能看状态还能辅助定位镜像烧写的位置。在 U-Boot 下执行mmc part如果 eMMC 是 GPT 分区表这里会列出分区名和起止扇区。将输出和parameter.txt对比可以确认你烧写时用的偏移是否正确。在实际项目中我遇到过烧写时用了 A 版本分区表、而实际镜像包是 B 版本的情况这种错位问题单靠启动日志很难一眼看出但通过mmc part就能提前发现。6. 刷机后的验证与后续扩展思路6.1 从单分区过渡到标准分区布局如果刷机后系统运行稳定你可以开始考虑从单分区方案过渡到标准多分区布局。具体的做法是在parameter.txt中定义好分区表然后重新生成对应的镜像并整体烧录。分区数量变多之后单独更新某个模块比如只更新vendor分区验证驱动会变得非常方便。提示修改分区表之后bootargs中的 root 参数需要同步修改。多分区布局下system分区通常是只读的而userdata分区是唯一可写区域应用数据和配置会集中放到这里这样 OTA 升级时可以只更新系统分区而保留用户数据。6.2 与编译流程的衔接建议刷机不是孤立的动作它和编译流程强相关。我的建议是建立“编译-打包-刷机-验证”的闭环流程编译完成后先检查关键镜像的时间戳和大小然后制作 SD 卡快速验证基础启动确认无误后再烧录 eMMC。这样可以避免每次代码改动都经历一次完整的 eMMC 烧录毕竟 eMMC 的擦写次数是有限资源频繁整盘烧写不是好习惯。另外如果你经常需要刷机可以考虑写一个简单的脚本把上面的rkdeveloptool命令串起来并且加一个-l日志输出选项方便留痕。脚本里强制执行擦除前确认防止误操作。7. 写在最后的实操心得这套 SD-eMMC-单分区刷机流程我前前后后在多种 RK 板卡上跑过最大的体会是刷机这件事七分在准备三分在操作。准备包括固件校验、分区表确认、硬件连接检查操作其实就那么几条命令。很多刷机失败的朋友回头复盘时往往发现是在某个“以为没问题”的环节翻了车比如用错设备树、烧错偏移、卡没格式化干净。个人建议是第一次刷机务必全程开着串口日志每一步都和预期行为对照。出现异常不要慌把日志保存下来回去对照分区表和设备树定义一条一条排查。熟悉了这套流程之后日后不管是做内核调试、驱动移植还是系统裁剪你都会觉得整个 OpenHarmony 开发过程踏实很多。
返回列表