ARTICLE DETAIL

资讯详情

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

启动链路与分区—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

启动链路与分区—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】 串口开着上电后字是一行一行出来的。今天顺着启动链路走卡在哪一行对应哪一张分区不要先改驱动。屏停在 logo 上你改 RenderService、改 launcher、改设备树二十分钟一轮现象不变。串口其实早就把死亡地点写出来了有的停在write training result有的停在Cannot find partition boot_linux有的 16 秒wait for file ... dwmmc有的 22 秒桌面起来了又自己关屏。这些不是同一种「起不来」。启动是一条严格串行的管子每一节读一张不同的分区。管子在哪一节断改后面的分区没有用。产品名rk3568_evb。内核 Linux 5.10 aarch64用户态 32 位 musl。hardware 名rk30board。上电 → MiniLoaderAll.bin DDR 训练、把 U-Boot 搬进内存 → uboot.img 读 GPTparameter.txt 写进的那张表 → resource 分区 logo.bmp rk-kernel.dtb → boot_linux 分区 ext2Image extlinux.conf ramdisk → 内核 ramdisk 一阶段 init读 fstab.required → 挂 /usr /vendor 二阶段 init读 fstab.rk30board → system 一堆 SA foundation、render_service、launcher → 桌面 然后可能被 SuspendController 关屏官方启动流程偏通用启动子系统。下面按这块 RK3568 板上实际读的分区写。1. 用死亡时间认管子断在哪大约时间串口关键字断在哪该动哪张镜像01 s反复训练write training result 之后没 outMiniLoader / DDRMiniLoaderAll.bin整包12 sCannot find partition boot_linuxU-Boot 找分区常去 eMMC先 USB 刷 eMMC 的 GPT p52 s 有 logo无内核FATAL error: cannot load boot_linuxp5 空或不是 ext2boot_linux.img内核起~16 s panicwait for file .../fe2b0000.dwmmc/by-name/systemramdisk 的 fstab.required 和介质错配ramdisk / 整包~16 sFailed to exec /bin/init然后 FreeRootDir没加载 ramdisk或 fstab.required 缺boot_linux 里的 extlinux.conf~58 s/data 挂不上ExecRebootfstab.rk30board 错或 vendor 没在一阶段挂上vendor.img动画播完再过十几秒屏黑KeventFbNotifierFn:blank4SuspendController timeoutsystem 里的 power_suspend.json卡 logo串口能敲命令无 render_service或它退了图形栈 / SystemUIvendor GPU 库、system启动不会「同时」暴露两个错。16 秒那关过了才会让你看见 58 秒那关。所以修启动问题按时间往下走不要看见黑屏就改 dts。2. MiniLoaderDDR 版本比容量口号重要上电之后还没有 U-Boot。芯片 BootROM 从介质开头取出MiniLoaderAll.bin里面嵌着 DDR 训练固件。训练过了才把uboot.img搬进内存。串口这一段大致是DDR V1.16 6f71c736ce 1056MHz 0x0 ... SRX U-Boot 2017.09 ...4 GB 核心板公版 MiniLoader 经常是DDR V1.10 1560 MHz。写训练打完就停write training result没有out没有 U-Boot没有 Linux。看起来像内存坏了。换一块 2 GB 板可能能起于是有人下结论「开源鸿蒙标准系统必须 4 GB / 1 GB 跑不动桌面」。后半句被证伪过2 GB 板 MemAvailable 足够出桌面。真因是 loader 频率和这份颗粒不对付。刷之前看镜像里的二进制strings out/rk3568_evb/packages/phone/images/MiniLoaderAll.bin | grep -E DDR|V1\. | head期望V1.16。合成用 rkbin 的boot_merger不是改内核sdram_rk3568.c——那份是空 stubRK3568 容量由预编译 bin 探测。# 在 rkbin 目录示例。ini 文件名按你的包 cd /path/to/rkbin # RKBOOT/RK3568MINIALL.ini 里两处 FlashData / CODE471 # rk3568_ddr_1560MHz_v1.16.bin → rk3568_ddr_1056MHz_v1.16.bin ./tools/boot_merger RKBOOT/RK3568MINIALL.ini # 产出 MiniLoaderAll.bin strings MiniLoaderAll.bin | grep DDR cp MiniLoaderAll.bin \ /path/to/OpenHarmony/device/board/rk/rk3568_evb/loader/MiniLoaderAll.bin cp MiniLoaderAll.bin \ /path/to/OpenHarmony/out/rk3568_evb/packages/phone/images/MiniLoaderAll.bin还挂再降到 780 MHz 那档固件。SDDiskTool 从磁盘 0 扇区写会覆盖卡上旧 loader。卡以前能起 4 GB刷一份带 V1.10 的包之后就不能起是这个覆盖不是颗粒突然坏了。Maskrom 进不去、完全没字先确认 3.3 V / 5 V 到了 SoC。MiniLoader 是芯片行为没电就不会枚举 ROCKUSB也不会打 DDR 日志。3. U-Boot 和 parameter.txt分区名是契约MiniLoader 把控制权交给uboot.img。U-Boot 读 GPT。GPT 是打包时按parameter.txt写进去的。CMDLINE里那串mtdparts看起来像 NAND在 eMMC/SD 上同样当分区表用。一份能用的骨架扇区数按你板的容量改userdata 起始必须落在真实容量内FIRMWARE_VER: 1.0.0 MACHINE_MODEL: RK3568 MACHINE_ID: 007 MANUFACTURER: RK3568 MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE: 0xffffffff CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 TYPE: GPT CMDLINE: mtdpartsrk29xxnand:0x000020000x00004000(uboot),0x000020000x00006000(misc),0x000030000x00008000(resource),0x000300000x0000B000(boot_linux:bootable),0x000020000x0003B000(backup),0x000020000x0003D000(bootctrl),0x003000000x0003F000(system),0x000800000x0033F000(vendor),0x000200000x003BF000(sys_prod),0x000200000x003DF000(chip_prod),0x000200000x003FF000(updater),0x000020000x0041F000(chip_ckm),0x000200000x00421000(eng_system),0x000020000x00441000(eng_chipset),0x006BE0000x00443000(userdata) uuid:rootfs614e0000-0000-4b53-8000-1d28000054a9数字是示例。你树上那份才是权威。要盯的是名字和几个 flag不是把示例扇区抄进 8 GB 的 eMMC。约束分区名boot_linux不能改。U-Bootbootrkp硬编码找它。改成boot/kernel失败可以很安静。boot_linux:bootable的:bootable要留。它参与distro_bootpart这类逻辑。userdata:grow的:grow要去掉。否则 GPT 分区名变成字面量userdata:grow内核找不到userdata。userdata 偏移不能超出介质。公版0x01308000大约对应 9.77 GB8 GB eMMC 上这个分区不存在报Could not find userdata part。往前收到紧挨上一个分区的位置。package-file第一列必须和括号里的名字一致。一边写rootfs一边写system对应镜像不会被写进整包。U-Boot 停下来可以手探 mmc list mmc dev 0 part list mmc 0 mmc dev 1 part list mmc 1Cannot find partition boot_linux时先part list看当前mmc dev是 0 还是 1。很多底板的 U-Boot 默认去mmc 0eMMC找即便拨码拨在 SD。eMMC 空这里就死。先 USB 整包刷 eMMC再谈 SD 启动。misc分区非零U-Boot 可能进 recovery。打包用全零misc.img。怀疑时 mmc read $loadaddr misc起始扇区 0x80 md.b $loadaddr 0x100全零才正常。单分区日常不要 dd misc除非你知道自己在清它。4. resourcelogo 和真正生效的 dtbU-Boot 从resource 分区p4取出rk-kernel.dtb logo.bmp logo_kernel.bmplogo 是 U-Boot 画的不是内核画的。所以换开机画面刷 p4不必动 Image改 dts真正被内核用的是这份rk-kernel.dtb不是 boot_linux 里那份 toybrick.dtbresource.img 是 RSCE 包用resource_tool打resource_tool --pack --imageresource.img \ rk-kernel.dtb logo.bmp logo_kernel.bmpbuild_kernel.sh/make-ohos.sh会做这一步并把resource.img拷到out/rk3568_evb/packages/phone/images/。换 logo 后若没删旧resource.img脚本可能复用缓存打包目录里 bmp 是新的、产物仍是旧的。强制rm -f out/kernel/src_tmp/linux-5.10/resource.img \ out/rk3568_evb/packages/phone/images/resource.imgU-Boot 常从 eMMC 取 resource。SD 启动改 dtsmmcblk0p4 和 mmcblk1p4 都写。刷机那篇把命令写死了。解包验证mkdir -p /tmp/res cd /tmp/res resource_tool --unpack --image/path/to/resource.img dtc -I dtb -O dts rk-kernel.dtb 2/dev/null | grep -A4 serialfdd50000板上/proc/device-tree对不上这次 dts先问 p4 刷了没有再问 U-Boot 取的是哪块盘的 p4。5. boot_linuxext2 里的 Image 和 ramdiskp5 是一张ext2。U-Bootbootrkp认这个格式。典型布局/Image aarch64 内核 /extlinux/extlinux.conf /extlinux/ramdisk.img 一阶段 initramfs /extlinux/toybrick.dtb 常有开机主 dtb 仍是 resource 那份 /logo.bmp 常有开机不读extlinux.conf必须有 initrdlabel OpenHarmony kernel /Image initrd /extlinux/ramdisk.img append ... consolettyS2,1500000n8 androidboot.hardwarerk30board ...缺initrd这一行U-Boot 不把 ramdisk 交给内核。内核用rootPARTUUID...直接把 system 分区当根。一阶段 init 调SwitchRoot(/usr)system 根上没有/usr这个挂载点目录的预期结构stat(/usr)失败于是FreeRootDir把 system 分区上的文件删光再exec(/bin/init)得到 ENOENTpanic。这是启动链里最贵的错每次开机破坏 system只能重刷。编完先验debugfs -R cat /extlinux/extlinux.conf \ out/rk3568_evb/packages/phone/images/boot_linux.img看不到initrd不要交付。khdf 的 HCS 烤进内核 Image不在这张 ext2 的某个 conf 里。改 khdf 重编 Image 重打 boot_linux。改 dts 仍要同时刷 resource。只改 dts、Image 没变时可以只重编 dtb、重打 ext2最小重建那篇但p4 还是要刷否则 U-Boot 交出去的还是旧 dtb。6. ramdisk 和 fstab.required一阶段内核解开 ramdisk 当根跑里面的/bin/init32 位 musl。它读etc/fstab.required把标了required的分区挂到新根。典型四条/dev/block/platform/fe2b0000.dwmmc/by-name/system /usr ext4 ro wait,required /dev/block/platform/fe2b0000.dwmmc/by-name/vendor /vendor ext4 ro wait,required /dev/block/platform/fe2b0000.dwmmc/by-name/sys_prod /sys_prod ext4 ro wait,required /dev/block/platform/fe2b0000.dwmmc/by-name/chip_prod /chip_prod ext4 ro wait,requiredeMMC 把fe2b0000.dwmmc换成fe310000.sdhci。vendor 必须是required。只有wait一阶段不挂它。SwitchRoot之后二阶段立刻找/vendor/etc/fstab.rk30board找不到/data永不挂后面所有写/data的服务失败。ramdisk 里还要有挂载点目录/usr/vendor/sys_prod/chip_prod否则MountToNewTarget失败。fstab 和介质错配串口大约 16 秒wait for file /dev/block/platform/fe2b0000.dwmmc/by-name/system ... Failed to exec /bin/init, err2 Kernel panic - Attempted to kill init!ueventd 已经按真实控制器建好了fe310000.sdhci/by-name/...fstab 却去 dwmmc 下面等。等 5 秒超时/usr没挂上二阶段的 init 路径不存在。fstab.required来自device/board/rk/rk3568_evb/cfg/install_images [ramdisk]。改它不必重编内核必须重打 ramdisk并且确认 boot_linux 里那份 ramdisk 也更新了——有的打包把 ramdisk 再拷进 ext2。两处都 grepdebugfs -R cat /etc/fstab.required \ out/rk3568_evb/packages/phone/images/ramdisk.img debugfs -R cat /extlinux/ramdisk.img \ out/rk3568_evb/packages/phone/images/boot_linux.img /tmp/rd.img # ramdisk.img 常是 gzip cpio具体格式按 file 输出再解 file out/rk3568_evb/packages/phone/images/ramdisk.img7. vendor 和 fstab.rk30board二阶段SwitchRoot之后init 读import /vendor/etc/init.${ohos.boot.hardware}.cfg mount_fstab /vendor/etc/fstab.${ohos.boot.hardware}ohos.boot.hardwarerk30board所以只认/vendor/etc/init.rk30board.cfg /vendor/etc/fstab.rk30boardfstab.rk3568是死文件。fstab.rk30board负责 userdata →/data、misc 等。控制器名必须和一阶段同一介质。只改 required、忘了 rk30board16 秒那关过了大约 58 秒mount .../fe2b0000.dwmmc/by-name/userdata on /data failed write_updater ... ExecReboot panic/data没有所有依赖 data 的 SA 起不来init 认为关键服务死了重启。userdata 分区在介质上是存在的mmcblk0p15 / mmcblk1p15首挂为空会 fsck/format这是正常的。找不到的是fstab 指错了控制器不是分区没做出来。init.rk30board.cfg里放start console、chmod 节点、自启服务。改它进 vendor.img。vendor 还装着 uhdf 的hdf_default.hcb、GPU 和相机 so。config.json若没把芯片产品配进 VDI/GPU 列表render_service 会退串口正常、屏停 logo。那是图形栈不是启动管子本身但死亡时间会和「卡 logo」混在一起。先确认ps | grep render_service。8. system桌面以及首启那次关屏system 分区挂到/usr再 switch 成/。foundation、窗口、SystemUI、launcher、Settings、powermgr 都在这里。用户态 32 位/system/bin/init的 interpreter 是 musl-arm。正常时间线2/4 GB、屏那路 okay0 s DDR U-Boot 2 s logoresource 8 s 内核 dmesg 15 s bootanimation 25 s 动画退桌面图标 30 s hdc list targets 有设备号有一种「进不去桌面」是假的。动画播完launcher、foundation、render_service 都在wms.fullscreen.ready也打了。再过大约十几秒屏黑。复位又能看到动画然后又黑。电源服务的SuspendController读power_suspend.json里的timeout源这么多秒没人点屏当用户走开关屏。首启要装一堆预装 hapCPU 忙你盯着串口没人摸触摸计时器到点必关。重启后你若碰巧点了一下计时器被清掉又能亮很久——看起来偶发首启无人操作时是必然。日志KeventFbNotifierFn:blank4 receive display off event DevmgrServicePowerStateChange:suspend state 1 HdfTouchDriverDozeSuspend临时摸触摸或按电源键。永久删掉/system那份json 里的 timeout 块。{ power_suspend: { sources: [ { name: lid }, { name: timeout, value: 15 } ] } }把 timeout 那个对象整段删掉。源码在base/powermgr/power_manager/services/native/profile/power_suspend.json装到/system/etc/power_config/power_suspend.json。丢一份到/vendor/etc/power_config/无效。加载函数GetOneCfgFile(etc/power_config/power_suspend.json)只搜/system:/chipset:/sys_prod:/chip_prod命中即返回/vendor不在列表里。改完重打 system.img。displayOff-1也救不了。运行时 DisplayOffTime 取自 settings 数据库不是编译默认。首启数据库里是有限值。这和 16 秒 panic、58 秒 ExecReboot、DDR 训练失败都不是一类。串口能敲命令、ps里有 launcher再考虑关屏。9. 把整条管子画成「谁读哪张盘」BootROM 介质 0 扇区附近的 MiniLoader MiniLoader uboot 分区 U-Boot GPT来自 parameter.txt resource p4 → logo rk-kernel.dtb boot_linux p5 → Image ramdisk 内核 ramdisk 里的 init fstab.required 一阶段 init system p7 → /usr vendor p8 → /vendor 必须 required 二阶段 init /vendor/etc/fstab.rk30board userdata p15 → /data /vendor/etc/init.rk30board.cfg SA / 桌面 system 上的二进制 vendor 上的 HAL/so Suspend /system/etc/power_config/power_suspend.jsonby-name 软链在运行时指向 eMMC 的 pN不管当前根在哪。一阶段 fstab 写的却是platform/控制器/by-name/...走的是控制器下面那份 by-name和/dev/block/by-name不是同一组节点。所以 fstab 必须写对控制器你自己 dd 时不要用/dev/block/by-name。boot_devicesfe2b0000.dwmmc,fe310000.sdhci写在 cmdline 里是候选列表两个都列正常。真正决定挂哪块盘的是两份 fstab。10. 一次对照从串口日志对到分区把一次失败的串口保存下来按出现的第一句致命错误对# 主机上 grep -nE DDR|U-Boot|boot_linux|Starting kernel|wait for file|FreeRootDir|ExecReboot|blank4|render_service uart.log | head -40第一句动作停在 DDR无 U-Boot换 V1.16 MiniLoader整包刷SDDiskTool 也会覆盖 loaderCannot find partition boot_linux刷 eMMC GPT p4 p5kernel panic 16s dwmmc/sdhcigrep 两份 fstab重打 ramdisk 和 vendor出完 eMMC 改回 SDFreeRootDir / exec init ENOENT查 extlinux.conf 的 initrd、ramdisk 是否进了 boot_linux58s ExecRebootfstab.rk30board、vendor 是否 requiredblank4删 system 的 timeout先摸一下屏确认桌面其实在无 render_servicevendor 的 GPU/VDI、SystemUI 签名不是 loader不要在 DDR 失败时改 dts不要在 16 秒 panic 时改 launcher。管子是串行的。主机上可以把这份 grep 做成脚本丢进日志目录随手跑#!/usr/bin/env bash # classify_uart.sh uart.log set -euo pipefail log${1:?usage: $0 uart.log} hit() { grep -E $1 $log /dev/null echo $2; } hit write training result DDR: MiniLoader 频率/版本看 strings MiniLoaderAll.bin hit Cannot find partition .boot_linux U-Boot: eMMC 无 GPT/p5USB 整包刷 eMMC hit wait for file .*dwmmc ramdisk: fstab.required 还是 SD 路径当前介质是 eMMC hit wait for file .*sdhci ramdisk: fstab.required 还是 eMMC 路径当前介质是 SD hit FreeRootDir|Failed to exec .*/bin/init extlinux 缺 initrd或 ramdisk 没有 fstab.required hit ExecReboot|Could not find userdata vendor: fstab.rk30board / userdata 偏移 / vendor 未 required hit blank4|display off event system: SuspendController timeout桌面其实在 hit render_service 查它是否立刻退了vendor GPU 库、SystemUI if ! grep -q Starting kernel $log; then echo 内核没起来问题在 MiniLoader / U-Boot / boot_linux不要改 system fi if grep -q Starting kernel $log ! grep -q wms.fullscreen.ready $log; then echo 内核起来了但没到窗口就绪fstab / init / 图形栈 fi10.1 console 和 hardware 后缀写进生效的那份 cfg二阶段会 import/vendor/etc/init.rk30board.cfg。调试口要能敲命令boot 段里得有start console。骨架# device/board/rk/rk3568_evb/cfg/init.rk30board.cfg on boot start console chmod 0666 /dev/ttyS0 /dev/ttyS3 /dev/ttyS7 /dev/ttyS8 chmod 0666 /dev/i2c-1 /dev/i2c-2 restorecon /dev/ttyS0 /dev/ttyS7 /dev/i2c-1 on property:ohos.boot.completedtrue # 自启服务写这里服务名还要进高权限进程白名单 start your_board_daemon写在init.rk3568.cfg里等于没写。验板上# ls -l /vendor/etc/init.rk30board.cfg /vendor/etc/fstab.rk30board # grep start console /vendor/etc/init.rk30board.cfg # param get ohos.boot.hardware rk30boardhardware 不是rk30board整份 cfg 不会被 importconsole、chmod、自启一起消失。先对 cmdline 里的androidboot.hardware再改 cfg。11. 失败判断4 GB 板刷完没字。loader 版本。strings MiniLoaderAll.bin | grep DDR。同一张 SD 换一块核心板就不能起。新板 eMMC 空U-Boot 去 eMMC 找 boot_linux。先 USB 刷 eMMC。logo 新、设备树旧。刷了带新 logo 的 resourcedtb 仍是旧的——打 resource 时用了旧 dtb。或反过来。解包看rk-kernel.dtb。每次开机 system 里的文件消失。缺 initrd。立刻停修 extlinux.conf重刷 system。继续开机等于反复格式化自己。16s / 58s 切换着出现。两个 fstab 改了一份。一次 grep 全改。首启黑屏重启后正常。timeout 关屏。不是「偶发硬件」。parameter 里 userdata 越界。小容量 eMMC。算扇区不要抄 16 GB 板的表。misc 非零进 recovery。换全零 misc或整包。从 loader 到桌面中间没有魔法。每一段对应一张分区、一份配置、一种串口口吻。认准口吻再决定刷哪一张。系列第 11 篇 · 芯片瑞芯微 RK3568 · OpenHarmony 4.1API 11 · Linux 5.10
返回列表