| name | ohos-dev-distributed-device-image-flashing |
| description | Use when the user wants to download OpenHarmony daily build images or flash them to a real device (DAYU200/RK3568 or others). Triggers on daily build, DAYU200, RK3568, flashing, burning, hdc reboot, upgrading firmware. |
| metadata | {"author":"openharmony","scope":"distributed","stage":"development","domain":"device","capability":"image-flashing","version":"0.2.0","status":"draft"} |
Flash OpenHarmony Device with Daily Build
Download daily build and flash via hdc updater mode. Scripts are generic — not hardcoded to any specific repo or device.
Scripts
| Script | Purpose |
|---|
download_daily.py | Query DCP API, download + extract device image |
flash_device.py | Parse parameter.txt for partitions, flash via hdc updater mode |
Use the actual installed skill directory when running the helper scripts.
Required Workflow
Follow these steps in order. Do not skip connectivity checks.
Step 1: Verify Device Connectivity
Before any download or flash operation, confirm the device is reachable.
Direct USB:
hdc list targets
Via SSH tunnel:
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "echo connected && hdc list targets"
Record the current firmware version for post-flash comparison:
hdc shell param get const.product.software.version
Step 2: Download Image
SKILL_DIR=<installed-skill-dir>
python3 "$SKILL_DIR/download_daily.py" --component dayu200
After download completes, the script verifies archive integrity. Check the output for errors before proceeding.
Step 3: Flash Device
Pre-flash checklist:
- Device is reachable (Step 1 passed)
- Image downloaded and extracted (Step 2 passed,
system.img exists in output dir)
- User has explicitly approved the destructive flash operation
Only pass --yes after the user has explicitly approved destructive device flashing. Otherwise let
flash_device.py prompt for FLASH.
python3 "$SKILL_DIR/flash_device.py" --img-dir daily_build --yes
WARNING: Do not interrupt the flash process. If hdc disconnects or power is lost during dd writes, the device may become unbootable. See Recovery section below.
Step 4: Verify Success
Wait ~60 seconds after reboot, then:
hdc shell param get const.product.software.version
Compare with the version recorded in Step 1. If the version changed to the expected build, flash succeeded.
If the device does not appear in hdc list targets after 120 seconds, see Recovery below.
Step 5: Push Custom Libraries (Optional)
After flashing the base image, push locally-compiled libraries:
hdc shell mount -o rw,remount /
for lib in lib1.z.so lib2.z.so; do
hdc file send $lib /system/lib/$lib
done
hdc shell reboot
For SSH tunnel scenarios, upload via scp first, then send to device:
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "hdc shell mount -o rw,remount /"
for lib in lib1.z.so lib2.z.so; do
scp -P $SSH_PORT $lib $SSH_USER@$SSH_HOST:push_tmp/$lib
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "hdc file send push_tmp/$lib /system/lib/$lib"
done
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "hdc shell reboot"
SSH Tunnel Usage
The scripts run on the target machine that has USB to the board. Upload via SSH then execute remotely.
SKILL_DIR=<installed-skill-dir>
SSH_PORT=<ssh-port>
SSH_USER=<ssh-user>
SSH_HOST=<ssh-host>
scp -P $SSH_PORT "$SKILL_DIR/download_daily.py" $SSH_USER@$SSH_HOST:download_daily.py
scp -P $SSH_PORT "$SKILL_DIR/flash_device.py" $SSH_USER@$SSH_HOST:flash_device.py
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "python download_daily.py --component dayu200"
ssh -p $SSH_PORT $SSH_USER@$SSH_HOST "python flash_device.py --yes"
WARNING: SSH disconnect during flash is dangerous. If the SSH session drops while dd is writing a partition, the device may be left in a partially-written state. Mitigations:
- Use
nohup or tmux/screen on the remote machine to keep the process alive if SSH drops.
- Ensure the remote machine has a stable power supply.
- If SSH drops mid-flash, do NOT power cycle the device. Reconnect SSH and check if the process is still running (
ps aux | grep flash_device).
Device Recovery
If a flash fails (power loss, hdc disconnect, corrupted image), the device may not boot normally.
DAYU200 / RK3568 Recovery
-
Try updater mode: Hold the device's Vol+/recovery button while powering on. The device should enter updater/recovery mode. Then retry flashing.
-
If hdc is unreachable in updater mode: Use the RKDevTool (Windows) or upgrade_tool (Linux) from Rockchip to flash via USB in maskrom/loader mode:
- Power off the device
- Hold the maskrom button while connecting USB
- Use RKDevTool to write the full image
-
If maskrom is not accessible: The hardware recovery button location varies by board revision. Consult the DAYU200 hardware documentation.
General Checklist
| Symptom | Recovery |
|---|
| Device reboots to updater loop | Re-flash all partitions from updater mode |
| hdc list targets shows nothing | Try maskrom mode or check USB cable |
| Boot hangs on logo | system.img may be corrupt — re-download and flash |
| Services crash after custom .so push | IDL interface mismatch — do a full flash instead of partial push |
Key Design Decisions
Partition table from parameter.txt: flash_device.py parses CMDLINE:mtdparts=... from the image's parameter.txt to discover partitions. The built-in RK3568 fallback partition list is used only when --allow-fallback-partitions is explicitly passed after verifying the image layout.
SSH port fallback: Scripts default to port 2222. If connection fails, prompt the user for the correct port rather than failing silently.
DCP API: Response path is data.builds.dataList[].component. Auto-searches last 7 days if today's build is missing.
Archive safety: download_daily.py rejects archive entries that would extract outside the output directory. After download, the archive is verified by opening it before extraction.
Destructive action confirmation: flash_device.py requires interactive FLASH confirmation unless --yes is passed by an already-approved workflow.
Command failure handling: flash_device.py stops immediately when an hdc command exits non-zero.
Userdata write path: userdata.img is flashed last. The helper unmounts /data, uploads the
image to updater ramdisk temporary storage, writes it with dd, runs sync on the userdata block
device, and removes the temporary file. Do not write userdata.img with a direct hdc file send
to /dev/block/by-name/userdata.
Why Updater Mode
Normal mode mounts system/vendor read-only — dd silently fails. Updater mode keeps partitions unmounted. Userdata is flashed last because it's used as temp storage during the process.
Common Mistakes
| Mistake | Fix |
|---|
| DCP 返回空 | 日期格式 YYYYMMDDHHMMSS;脚本自动搜索 7 天 |
| dd 无输出 | 必须 updater 模式 |
| userdata 失败 | 先 umount /data |
| 推包后 mmi_service 不启动 | IDL 接口变了需全量刷机,不能只推部分 .so |
| SSH 连不上 | 先启动目标机器的 SSH 或端口转发服务,确认端口 |
| SSH 断开导致烧录中断 | 用 nohup/tmux 运行脚本;不要立即断电 |
| 下载的镜像包损坏 | 删除 tar.gz 重新下载;检查网络连通性 |