认识系统 第 3 篇

同一颗芯片,从普通 Linux 换到 OpenHarmony 以后

同一颗 RK3568,从普通 Linux 换成 OpenHarmony 4.1 之后,同一天里会碰到哪些不一样。

同一颗芯片,从普通 Linux 换到 OpenHarmony 以后

分层图上一篇摊开了。今天把同一颗 RK3568 放在两边看:昨天还在普通 Linux 上用的那套,换成开源鸿蒙以后,同一天里会碰到哪些不一样。

同一颗芯片:普通 Linux 和开源鸿蒙

RK3568 我原先是当普通 Linux 板来用的:U-Boot、内核、设备树、rootfs,应用是 Qt 或者直接上的 ELF。换成 OpenHarmony 4.1 标准系统之后,内核那一层几乎没让我重新学,用户态把人拧了一下。

下面按「同一天里会碰到的事」来写,每件事给一条在板上能跑的命令。你要是刚刷完,可以开着 hdc 对着敲。


OpenHarmony 分层

内核还在,配置方式变了

menuconfig 能进,和 Linux 一样:

export KBUILD_OUTPUT=out/kernel/OBJ/linux-5.10
cd out/kernel/src_tmp/linux-5.10
make menuconfig

不要在里面改完就以为永远生效。这套构建每次会从若干份 defconfig 重新合成 .config,你手改的那份会被盖掉。要长期打开某个 CONFIG_,写进板级的 defconfig 片段,或者写进内核构建脚本里那一段强制注入。忘记这一点的结果很经典:本地 .config 里明明是 =y,干净编译之后功能消失。

设备树语法也还是那套 &uart0 { status = "okay"; }。多出来的是:开机真正用的 dtb,往往在 resource 分区的 rk-kernel.dtb,不是你只刷进 boot 分区的那份。所以「我改了 dts、也重编了、刷了内核,屏还是老时序」——先反编译板上的树,别先改驱动。

hdc shell "cat /proc/device-tree/chosen/bootargs"
# 把 dtb 从板子抠出来再反编译,看 status 到底是 okay 还是 disabled

用户态是 32 位 musl

板上没有 aarch64 的用户态 loader。有的是:

hdc shell ls -l /system/lib/ld-musl-arm.so.1

内核模块照旧编 aarch64。你自己写的小工具、应用里的 .so,要 32 位,并且动态链接器指到上面那个路径。用 aarch64-linux-gnu-gcc 随手编一个 hello 丢上去,轻则 exec 失败,重则段错误。这个分裂会贯穿 NAPI、拨号工具、自己写的 canup

命令集也不是完整 busybox。iproutewget 经常没有,ifconfigping 有。看默认路由只能读:

hdc shell cat /proc/net/route

目的地址全 0 的那一行,第一列是接口名。联网那几篇会反复用到这一行。

服务不是 systemd。看 ohos.boot.hardware 决定加载哪份 init 配置,这块板常见是 rk30board,对应 init.rk30board.cfgfstab.rk30board。你改了 init.rk3568.cfg 当正式文件,开机理都不理。cfg 里的命令数组只能放真命令,把注释字符串塞进去,整份服务定义可能解析失败,表现就是「服务写了,ps 里永远没有」。


日志要看两处

内核问题看 dmesg。应用、包管理、相机 HAL、图形合成看 hilog。只盯串口,会漏掉 BMS 为啥拒装、RenderService 为啥合成不出层。

hdc shell dmesg | tail -50
hdc hilog

dmesg 的环形缓冲很小,开机审计一多,早期 probe 就被冲掉。上电后要抓的话,越早越好。


调试口从 ssh/adb 换成 hdc

hdc 分三段:电脑上的 client、电脑上的 server(默认监听 8710)、板上的 hdcd。官方说明在 hdc 使用指导

hdc list targets
hdc shell
hdc file send D:\tmp\boot_linux.img /data/local/tmp/boot_linux.img
hdc install D:\tmp\app-signed.hap

和 adb 像,但包是 hap,日志是 hilog,没有 adb remount 那套肌肉记忆。Windows 和 Linux 同时插同一块板,两个 hdc server 会抢,把其中一边的端口换掉。

串口还在,早期比 hdc 更要紧。UART2,1500000,8N1。115200 是雪花,不是砖。


应用变成 hap

Linux 上 scp myapp /usr/bin 就结束的事,这里要:DevEco 编出 unsigned hap → 用 hap-sign-tool 签名 → hdc install。系统预装还要进镜像里的列表,指纹和权限各算一道门。

错误码值得单独记三个:

  • 未签名,校验直接失败
  • 签名过了,列表里的证书哈希和 hap 对不上
  • 哈希对了,应用申请的权限超出 profile 的级别

后一个错误出现,说明前一个已经过了。不要只盯着最后一次失败改签名,可能该改的是 p7b 的 apl。

NAPI 仍然是 C 读写节点,这一部分和传统嵌入式最像。差别是 so 必须 32 位,节点要给非 root 的应用打开权限。开发期 SELinux 常常是宽松的;一 enforce,原先 chmod 过的路径会集体 403。


刷分区时最容易带着走的习惯

路径必须是 /dev/block/mmcblkXpY。写成 /dev/mmcblkXpY,节点不存在时 dd 会建普通文件,显示成功。

hdc shell cat /proc/partitions
hdc shell "dd if=/data/local/tmp/boot_linux.img of=/dev/block/mmcblk1p5 bs=4M conv=fsync"

/dev/block/by-name/ 在这块板上总是指向 eMMC。从 SD 启动时往 by-name 写,写的是另一块闪存。

resource 是 p4,里面才是开机用的 rk-kernel.dtb。只刷 p5 的 boot_linux,显示和引脚还按旧树走。

mount -o remount,rw /vendor 改脚本能验证思路,重启就没了。要留下去,重打 vendor 分区。


内核熟、用户态生,是总纲。下一篇把底板的口和软件节点对上,后面按接口写芯片时就不必每次从排针猜起。


系列第 2 篇 · 芯片:瑞芯微 RK3568 · OpenHarmony 4.1(API 11) · Linux 5.10

二维码