拓冰建站拓冰建站
首页 / 资讯中心 / 正文

刷机全流程SD-eMMC-单分区—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

镜像在手里了。今天专门写怎么刷SD 卡、eMMC 线刷、只更新某一个分区。路径写错时工具会显示成功分区却纹丝不动。dd打印了10 records inmd5sum跟镜像一致复位之后/proc/version还是三天前。下一次更干净dd报01 records in看起来也成功resource 分区里的 dtb 纹丝不动。这两次都不是板子坏了。第一次of写到了/dev/block/by-name/boot_linux符号链接永远指向 eMMC当时系统却跑在 SD 上。第二次of/dev/mmcblk1p4这个节点在开源鸿蒙的/dev里经常不存在dd不会报「没有这个设备」它在 tmpfs 上建一个普通文件把镜像写进文件md5 当然和源文件一样。整包刷 SD、整包刷 eMMC、单分区用 hdc 丢进去再 dd三条路都能把系统写上板。三条路共用同一张分区表共用同一个「假成功」陷阱。刷之前只做一件事cat /proc/partitions看清楚当前内核看见的盘字母。不要用X当盘符不要用 by-name 当捷径。Windows 整包工具的用法进桌面那篇写过。这篇把介质、分区号、dd 的完整命令写成能直接跑的两套一套 eMMCmmcblk0一套 SDmmcblk1。1. 先看盘再说话OTG 已经能hdc list targets或者串口已经有#。先跑# cat /proc/partitions major minor #blocks name 179 0 15267840 mmcblk0 179 1 16384 mmcblk0p1 179 2 4096 mmcblk0p2 ... 179 4 6144 mmcblk0p4 179 5 98304 mmcblk0p5 179 7 1572864 mmcblk0p7 179 8 307200 mmcblk0p8 179 15 4194304 mmcblk0p15 179 32 31166976 mmcblk1 179 36 6144 mmcblk1p4 179 37 98304 mmcblk1p5 179 39 1572864 mmcblk1p7 179 40 307200 mmcblk1p8 179 47 4194304 mmcblk1p15读法你看见含义只有 mmcblk0内核只枚举到 eMMC。没插 SD或 SD 没认出还有 mmcblk1SD 卡在位。**在位不等于从 SD 启动**没有 mmcblk1p7卡在但没按这张 GPT 分区。可能是一张普通数据卡这块板的约定mmcblk0 eMMC焊在核心板上 mmcblk1 Micro SD槽里那张再看根挂在哪# mount | grep on / # df -h / /system /vendor # param get ohos.boot.hardwarevendor若在mmcblk1p8当前从 SD 跑在mmcblk0p8从 eMMC 跑。ohos.boot.hardware必须是rk30board否则你刷的可能是另一份产品。不要用/dev/block/by-name判断介质。它永远指向 eMMC# ls -l /dev/block/by-name | head boot_linux - /dev/block/mmcblk0p5 resource - /dev/block/mmcblk0p4 system - /dev/block/mmcblk0p7 vendor - /dev/block/mmcblk0p8 userdata - /dev/block/mmcblk0p15从 SD 启动时这些箭头看起来一切正常。dd of/dev/block/by-name/system写的是 eMMC 的 p7SD 上正在跑的 system 一字节都没动。下次复位还是老桌面。dd成功md5 对的是 eMMC 那份。所以规则就三条刷前cat /proc/partitions和df /vendorof写/dev/block/mmcblk0pN或/dev/block/mmcblk1pN按当前要写的那块盘选禁止/dev/mmcblk0pN这种不带block的路径禁止 by-name禁止命令里出现盘符占位符2. 分区号两块盘的布局一样parameter.txt 决定 GPT。SD 和 eMMC 用同一张表所以p 后面的数字相同。常用的就这几个分区号镜像改什么时必刷resourcep4resource.imgDTS、logo、显示口切换。里面是 rk-kernel.dtbboot_linuxp5boot_linux.img内核、khdf、内置驱动、extlinuxramdisk有的产品打进 boot_linux有的单独一分区ramdisk.imgfstab.requiredsystemp7system.img系统应用、foundation、powermgrvendorp8vendor.imguhdf、init.rk30board、fstab.rk30board、芯片 souserdatap15userdata.img应用数据、BMS 数据库。整包刷会清空p1 附近是 ubootp2 常是 misc。misc 必须全零否则 U-Boot 可能进 recovery。日常单分区不要碰 uboot 和 misc除非你知道自己在换 loader。resource 大约 6 MB。开机第一张 logo、U-Boot 交给内核的 dtb都从这里取。boot_linux 是 3264 MB 的 ext2。system 1 GB 以上。vendor 几百 MB。userdata 看容量parameter 里的偏移必须落在真实介质内部8 GB eMMC 不要用按 16 GB 算的 userdata 起始扇区否则Could not find userdata part。cat /proc/partitions的#blocks是 1K 块。p4 若是 6144就是 6 MB装得下 34 MB 的 resource.img。不要看见镜像 3.6 MB、自己心算「分区只有 4K」——那是把 6144 看成了扇区数。3. 假成功/dev/mmcblk1p4是一个普通文件开源鸿蒙的/dev是 tmpfs节点由 ueventd 按规则建。块设备的正统路径在/dev/block/下。/dev/mmcblk1p4经常不存在。# ls -l /dev/block/mmcblk1p4 brw------- 1 root root 179, 36 ... /dev/block/mmcblk1p4 # ls -l /dev/mmcblk1p4 ls: /dev/mmcblk1p4: No such file or directory此时你跑# dd if/data/local/tmp/resource.img of/dev/mmcblk1p4 bs4M convfsync 01 records in 01 records out成功。再 md5# md5sum /data/local/tmp/resource.img /dev/mmcblk1p4两行一样。因为/dev/mmcblk1p4现在是dd刚建的普通文件内容就是镜像本身。真正的分区/dev/block/mmcblk1p4没被打开过。辨认# ls -l /dev/mmcblk1p4 /dev/block/mmcblk1p4 -rw-r--r-- 1 root root 3670016 ... /dev/mmcblk1p4 ← 普通文件假的 brw------- 1 root root 179, 36 ... /dev/block/mmcblk1p4 ← 块设备真的第一列是-不是b就是假的。删掉假文件以免下次ls /dev/mmcblk*再骗你# rm -f /dev/mmcblk1p4 /dev/mmcblk0p4 /dev/mmcblk1p5 /dev/mmcblk0p5echo foo /dev/ttyS0在 uart0 还没 probe 时会建同样的假节点ls看得到 ttyS0tcgetattr报Not a tty。同一类坑。还有一种假文件名字更阴。有人写命令时用mmcblkXp4表示「0 或 1 你自己选」。接收的人逐字照抄# 错误示范不要跑。X 不是通配符 dd if/data/local/tmp/resource.img of/dev/block/mmcblkXp4 bs4M convfsync 01 records in 01 records out/dev/block/可写。dd创建名为mmcblkXp4的普通文件。打印成功。md5sum /dev/block/mmcblkXp4和镜像一样。/proc/partitions里没有这个设备。resource 分区一个字节没动。现场靠「这次该消失的旧字符串还在」才识破不是靠 dd 的退出码。# ls -l /dev/block/mmcblkXp4 -rw-r--r-- 1 root root 3670016 ... /dev/block/mmcblkXp4 # find /dev /dev/block -type f -name *mmcblk* /dev/block/mmcblkXp4 # rm -f /dev/block/mmcblkXp4发给别人的命令里不要出现这个字母。两套完整路径都写出来让对方按df | grep vendor选一套跑。正确路径永远带/dev/block/。写完读回校验读的也是 block 路径# dd if/data/local/tmp/resource.img of/dev/block/mmcblk1p4 bs4M convfsync # dd if/dev/block/mmcblk1p4 of/data/local/tmp/resource.read bs4M count2 # md5sum /data/local/tmp/resource.img /data/local/tmp/resource.read镜像比分区短读回会多出分区里原来的尾巴md5 可能不同。比前 N 字节# LEN$(wc -c /data/local/tmp/resource.img) # dd if/dev/block/mmcblk1p4 bs1 count$LEN of/data/local/tmp/resource.head # md5sum /data/local/tmp/resource.img /data/local/tmp/resource.head两行相同才算写进去。bs4M convfsync。bs1M在个别镜像末尾碎块上会报No space left on device分区明明够大那是 dd 和分区大小对齐的假报错换 4M 就消失。convfsync让内核把缓存落到闪存再返回否则dd结束了数据还在 page cache立刻复位可能写残。4. 改 DTS 必刷 resourceU-Boot 还可能去 eMMC 取开机画面和生效 dtb 在 p4。内核 Image 在 p5。只刷 p5logo 不变/proc/device-tree也可以不变。U-Boot 找resource、boot_linux时经常去eMMC上找哪怕你拨码拨在 SD、内核根文件系统已经在 mmcblk1 上。新核心板 eMMC 空白串口会打Cannot find partition boot_linux FATAL error: cannot load boot_linux image to ram同一张刚刷好的 SD 卡换到一块 eMMC 里曾经有过系统的核心板上立刻能起。所以新板先 USB 整包刷一次 eMMC再谈 SD 启动改内核 / DTSp4 和 p5mmcblk0 和 mmcblk1 都写卡在位的话两盘都写的成本是多两次 dd收益是不再出现「我明明刷了 SDU-Boot 还在用 eMMC 里那份 LVDS dtb」。5. 主机到板hdc file send再在板上 dd镜像在 Linux 编译机或 Windows 共享盘。板上没有 sshd、没有 wget。通道是 USB OTG 上的 hdcd。先确认设备hdc kill hdc start hdc list targets应打出一串十六进制。没有就换 OTG 口、确认不是 Host、板上ps | grep hdcd。系统没进用户态时没有 hdcd只能整包刷不能走这条单分区路。Windows 上 hdc 常见位置C:\Users\you\AppData\Local\OpenHarmony\Sdk\11\toolchains\hdc.exe把 hdc 所在目录加进 PATH下面的 bat 才能直接跑。hdc file send的远端路径用/data/local/tmp/这个目录可写、重启可清。不要 send 到/system、/vendor只读挂载send 报成功也不一定落盘。大文件 send 可能中途断开。system.img 1.5 GBUSB2 要十几分钟。断了看板上文件大小不够就重发。6. 完整命令Windows bat先在板上查介质。下面这个 bat 只负责「问板上现在 vendor 在哪」echo off hdc shell param get ohos.boot.hardware hdc shell cat /proc/partitions hdc shell df /vendor /system hdc shell ls -l /dev/block/mmcblk0p4 /dev/block/mmcblk0p5 /dev/block/mmcblk0p7 /dev/block/mmcblk0p8 hdc shell ls -l /dev/block/mmcblk1p4 /dev/block/mmcblk1p5 /dev/block/mmcblk1p7 /dev/block/mmcblk1p8看输出决定走下面哪一套。镜像放D:\ohos\按你的实际路径改第一行。不要把 mmcblk0 改成 mmcblkX。6.1 当前要从 eMMC 更新vendor 在 mmcblk0p8echo off set IMGD:\ohos set HDChdc %HDC% file send %IMG%\resource.img /data/local/tmp/resource.img %HDC% file send %IMG%\boot_linux.img /data/local/tmp/boot_linux.img %HDC% shell dd if/data/local/tmp/resource.img of/dev/block/mmcblk0p4 bs4M convfsync %HDC% shell dd if/data/local/tmp/boot_linux.img of/dev/block/mmcblk0p5 bs4M convfsync REM SD 卡在位时U-Boot 仍可能读 eMMC若你其实想让 SD 也带上这份再写 mmcblk1 %HDC% shell if [ -b /dev/block/mmcblk1p4 ]; then dd if/data/local/tmp/resource.img of/dev/block/mmcblk1p4 bs4M convfsync; fi %HDC% shell if [ -b /dev/block/mmcblk1p5 ]; then dd if/data/local/tmp/boot_linux.img of/dev/block/mmcblk1p5 bs4M convfsync; fi %HDC% shell sync; reboot6.2 当前要从 SD 更新vendor 在 mmcblk1p8echo off set IMGD:\ohos set HDChdc %HDC% file send %IMG%\resource.img /data/local/tmp/resource.img %HDC% file send %IMG%\boot_linux.img /data/local/tmp/boot_linux.img %HDC% shell dd if/data/local/tmp/resource.img of/dev/block/mmcblk1p4 bs4M convfsync %HDC% shell dd if/data/local/tmp/boot_linux.img of/dev/block/mmcblk1p5 bs4M convfsync REM U-Boot 常从 eMMC 取 p4/p5eMMC 也写上 %HDC% shell dd if/data/local/tmp/resource.img of/dev/block/mmcblk0p4 bs4M convfsync %HDC% shell dd if/data/local/tmp/boot_linux.img of/dev/block/mmcblk0p5 bs4M convfsync %HDC% shell sync; reboot6.3 只刷 vendoruhdf、init、fstab.rk30boardeMMChdc file send D:\ohos\vendor.img /data/local/tmp/vendor.img hdc shell dd if/data/local/tmp/vendor.img of/dev/block/mmcblk0p8 bs4M convfsync hdc shell sync; rebootSDhdc file send D:\ohos\vendor.img /data/local/tmp/vendor.img hdc shell dd if/data/local/tmp/vendor.img of/dev/block/mmcblk1p8 bs4M convfsync hdc shell sync; reboot6.4 只刷 system系统应用、power_suspend.jsoneMMChdc file send D:\ohos\system.img /data/local/tmp/system.img hdc shell dd if/data/local/tmp/system.img of/dev/block/mmcblk0p7 bs4M convfsync hdc shell sync; rebootSDhdc file send D:\ohos\system.img /data/local/tmp/system.img hdc shell dd if/data/local/tmp/system.img of/dev/block/mmcblk1p7 bs4M convfsync hdc shell sync; rebootsystem.img 很大。send 失败先看hdc shell ls -l /data/local/tmp/system.img大小和主机dir D:\ohos\system.img一致再 dd。不够就重 send。单刷 system不会清 userdata。BMS 数据库还在预装应用的签名校验在「整包首启」和「单刷保留 data」上行为不同。应用装不上那条线另说。这里只保证分区字节换了。7. 完整命令Linux bash编译机若直接插着板的 OTGhdc 在 Linux 上也能用。更多时候 Linux 只出镜像Windows 跑 hdc。下面假设当前 shell 能hdc list targets。先定介质hdc shell param get ohos.boot.hardware; echo ---; cat /proc/partitions; echo ---; df /vendor按 vendor 所在盘选函数。改 DTS 时两盘 p4/p5 都写。#!/usr/bin/env bash set -euo pipefail IMGDIR/mnt/hgfs/share # 改成你的镜像目录 hdc_ok() { hdc list targets | grep -v ^$ | grep -v Empty; } flash_res_boot() { local dev$1 # mmcblk0 或 mmcblk1 hdc file send $IMGDIR/resource.img /data/local/tmp/resource.img hdc file send $IMGDIR/boot_linux.img /data/local/tmp/boot_linux.img hdc shell dd if/data/local/tmp/resource.img of/dev/block/${dev}p4 bs4M convfsync hdc shell dd if/data/local/tmp/boot_linux.img of/dev/block/${dev}p5 bs4M convfsync } # 用法确认 partitions 里两块盘都在再 hdc_ok flash_res_boot mmcblk0 flash_res_boot mmcblk1 hdc shell sync; reboot只刷 vendoreMMChdc file send /mnt/hgfs/share/vendor.img /data/local/tmp/vendor.img hdc shell dd if/data/local/tmp/vendor.img of/dev/block/mmcblk0p8 bs4M convfsync hdc shell sync; reboot只刷 vendorSDhdc file send /mnt/hgfs/share/vendor.img /data/local/tmp/vendor.img hdc shell dd if/data/local/tmp/vendor.img of/dev/block/mmcblk1p8 bs4M convfsync hdc shell sync; reboot只刷 systemeMMChdc file send /mnt/hgfs/share/system.img /data/local/tmp/system.img hdc shell dd if/data/local/tmp/system.img of/dev/block/mmcblk0p7 bs4M convfsync hdc shell sync; reboot只刷 systemSDhdc file send /mnt/hgfs/share/system.img /data/local/tmp/system.img hdc shell dd if/data/local/tmp/system.img of/dev/block/mmcblk1p7 bs4M convfsync hdc shell sync; reboot读回校验 resourceeMMChdc shell dd if/dev/block/mmcblk0p4 of/data/local/tmp/p4.read bs4M count2 hdc file recv /data/local/tmp/p4.read /tmp/p4.read # 主机上比前 N 字节 python3 - PY from pathlib import Path src Path(/mnt/hgfs/share/resource.img).read_bytes() rd Path(/tmp/p4.read).read_bytes()[:len(src)] print(match if src rd else DIFF, len(src), len(rd)) PY8. 整包SDDiskTool 和 RKDevTool 各管一块介质单分区走不通时hdcd 没起、分区表乱、新板 eMMC 空回整包。SD 卡SDDiskTool管理员勾 SD 启动固件头必须是 RKFW文件名不含 emmc。下拉框认容量认不准就拔读卡器看哪一项消失。写的是读卡器里那张卡不会隔空写 eMMC。刷完弹出再拔。拨码拨到 SD。eMMCRKDevTool「升级固件」Maskrom 或 Loader固件头 RKFW文件名含 emmc。点升级前清空日志成功判据是本次打出的「下载固件成功」。上次那行还躺在窗口里不算。SD 包刷进 eMMC、eMMC 包刷进 SD工具都可以显示成功。内核起来之后 init 按 fstab 去等另一条控制器16 秒或 58 秒 panic。串口关键字wait for file /dev/block/platform/fe2b0000.dwmmc/by-name/system wait for file /dev/block/platform/fe310000.sdhci/by-name/system等的那条和当前介质不一致就是包拿错了。不要在这一步开始改内核。整包会写 loader 区。4 GB 板必须用带 DDR V1.16 的 MiniLoader。SDDiskTool 从 0 扇区写卡上旧的 V1.16 会被包里的 V1.10 覆盖。新核心板顺序先 USB 整包刷 eMMC让 GPT 和 boot_linux 存在再刷 SD、再拨 SD 启动。只刷 SD、eMMC 全空U-Boot 可能找不到分区。RKFW 头 4 字节只告诉工具「我是瑞芯微整包」分不出该进 SD 还是 eMMC。两份包的差别在镜像里面的 fstabSD 写fe2b0000.dwmmceMMC 写fe310000.sdhci。介质约定写在文件名上。文件名介质唤起含 emmc例如 emmc-hdmi.imgeMMCRKDevTool「升级固件」含 update- 或头是 RKAF方向像 eMMC本机不要当主交付改用含 emmc 的 RKFWsd_image*.img或其它不含 emmc 的 RKFWMicro SDSDDiskTool勾选 SD 启动有人做了一个刷机选择小工具扫一个目录按文件名含不含emmc判断该唤起哪个软件。没有这个小工具也没关系你自己按上表选。小工具能防的是手滑——把emmc-xxx.img丢进 SDDiskTool或把sd_image.img当 eMMC 包升级。旧 exe 若「凡 RKFW 一律当 SD」emmc-xxx.img会被送进 SDDiskTool。规则改了必须重新编出 exe 再发Windows 上还在跑昨天那份选择器就会用旧规则把 eMMC 包当 SD 刷。fstab 和介质一旦错配串口看起来像系统坏了其实是挂载路径指错盘。小工具不能替你做的事认C:和 SD 卡的容量、判断 Maskrom 进没进、清空 RKDevTool 日志、在单分区dd时选mmcblk0还是mmcblk1。成功判据仍然是本次「下载固件成功」单分区仍然先df | grep vendor。9. 刷完怎么证明写进去的是这份内核# cat /proc/version Linux version 5.10.xxx (builderhost) (clang ...) #1 SMP PREEMPT 2026-08-21 ...日期应是你这次编 Image 的日期。还是上周p5 没写上或写到另一块盘了。设备树# cat /proc/device-tree/model # find /proc/device-tree -name status | xargs grep -n okay | grep -i uart | head和这次 dts 对。不对p4 没写上或 U-Boot 取了另一块盘的 resource。vendor 里的 fstab# grep -E dwmmc|sdhci /vendor/etc/fstab.rk30board系统应用# md5sum /system/app/com.ohos.settings/Settings.hap和镜像里 debugfs dump 出来的比。假文件排查# ls -l /dev/mmcblk* /dev/block/mmcblk0p4 /dev/block/mmcblk1p4 2/dev/null看见/dev/mmcblk1p4类型是-rw删掉它不要再 dd 给它。10. 失败判断dd: /dev/block/mmcblk1p4: No such file or directory。没插卡或卡没分区。先cat /proc/partitions。不要改成/dev/mmcblk1p4碰运气。01 records且 md5 与镜像完全相同、复位后内容旧。假文件。ls -l看类型。路径若是/dev/block/mmcblkXp4那是占位符被当成文件名find /dev -type f -name *mmcblk*能挖出来。records in/out正常/proc/version不变。写错盘。by-name 指向 eMMC你从 SD 启动。或写了 mmcblk0U-Boot 从 mmcblk1 起。两盘 p5 都写。改了 dts内核新、屏还是旧时序。只刷了 p5。刷 p4。两盘都刷。logo 不变。同上logo 在 p4。boot_linux 里即使有/logo.bmp开机不读。No space left on device分区比镜像大。bs1M换bs4M。或假文件建在了空间很小的 tmpfs 根上——那正好说明 of 路径不在 block 下。hdc file send 成功板上ls没有文件。远端路径写到了只读层或 send 到了另一台设备两个 hdc server 抢。hdc list targets只留一个。调试那篇写HDC_SERVER_PORT。send 到一半断开dd 仍在跑。先ls -l /data/local/tmp/*.img看大小。不够就不要 dd。dd 一个截断的 system.img 进 p7下次可能进不了桌面。整包成功单分区失败。整包走 ROCKUSB不靠 hdcd单分区靠用户态。系统没起来时不要坚持 hdc。刷了 p7桌面图标还是旧的。字节可能已经换了BMS 数据库在 p15。整包或清 userdata。先 md5 hap确认 p7 真换了再查 BMS。刷机命令写完自己读一遍有没有mmcblkX、有没有by-name、有没有丢掉/block/。有就不要发给任何人包括自己。系列第 9 篇 · 芯片瑞芯微 RK3568 · OpenHarmony 4.1API 11 · Linux 5.10
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门