#星光计划2.0# OpenHarmony3.0的树莓派4B移植-学习记录 原创 精华
【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】
目录
前言
以下是学习 OpenHarmony3.0 树莓派4B移植的详细流程记录,主要参考:官方移植指南,官方树莓派3B移植,社区大佬树莓派4B移植,LineageOS 树莓派移植项目:lineage-rpi,Android 树莓派移植项目:android-rpi。
实现了触摸与显示,并添加了物理按键关机的功能。希望能给像我一样第一次接触移植的嵌入式小白以帮助。
以下步骤操作于 Ubuntu 20.04 LTS 。OHOS 3.0 LTS 源码解压自官方镜像(使用 repo下载得到的最新源码有较多变化,以下步骤不再适用)。设项目根目录名为 OpenHarmony,且控制台默认处于该目录。移植系统为OHOS标准版 (standard),内核为 Linux-5.10。
定义开发板
根据官方移植手册,对源码目录以及代码中常出现的几个概念进行解释,并在本流程背景下进行赋值:
product | device | vendor | socvendor | |
---|---|---|---|---|
含义 | 嵌入式产品名 | SOC名 | 产品制造商 | SOC制造商 |
实例 | rpi4 | bcm2711 | raspberry | brcm |
因此,我们首先定义 SOC。建立文件 OpenHarmony/productdefine/common/device/bcm2711.json
:
目前 OHOS 只支持 arm。
接着定义产品。建立文件 OpenHarmony/productdefine/common/products/rpi4.json
:
其中,…
部分照搬同目录下的 Hi3516DV300.json
,并将其中的 "hisilicon_products:hisilicon_products":{},
改为 "brcm_products:brcm_products":{},
。
brcm_products
代表内核构建的子系统。我们需要在 OpenHarmony/build/subsystem_config.json
中定义它,加入键值对:
建立编译配置组件
接着在 OpenHarmony/device
下仿照 ./hisilicon/hi3516dv300
建立编译配置组件。目录结构:
OpenHarmony/device/brcm/bcm2711/build/rootfs/BUILD.gn
OpenHarmony/device/brcm/bcm2711/build/rootfs/init.rpi4.cfg
OpenHarmony/device/hisilicon/hi3516dv300/build/rootfs/init.Hi3516DV300.cfg
OpenHarmony/device/brcm/bcm2711/BUILD.gn
OpenHarmony/device/brcm/build/BUILD.gn
OpenHarmony/device/brcm/build/ohos.build
内核移植
内核编译流程
首先阅读 OpenHarmony/kernel/linux/build/kernel.mk
了解到内核编译的流程:
- 删除 out(编译输出目录)下之前编译过的内核源码,重新复制一份 Linux 内核源码
OpenHarmony/kernel/linux/linux-5.10
到OpenHarmony/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10
下。 - 对内核源码打补丁,包括内核源码补丁与 HDF 补丁。补丁需要预先准备。
- 复制 defconfig,需要预先准备。
- make distclean, xxx_defconfig, modules_prepare, uImage.
生成 patch
因此首先准备树莓派4B需要的内核补丁:
选择树莓派官方内核 rpi-5.10.y 来生成内核源码补丁。设控制台处在项目根目录 OpenHarmony
下,依次执行:
注意 diff
命令:
- 由于
kernel.mk
中用的是patch -p1
,即忽略掉路径的第一部分,因此diff
需作用在 OHOS 自带的源码目录外。 - 树莓派官方内核源码需要用绝对路径,因人而异。
实际编译时很可能会因为 patch
过程中出现冲突而中断,解决方法:
- 在
diff
时忽略源码目录下的.git
,.gitgitignore
, 以及某设备树文件,保证打补丁时无冲突。 - 手动执行
kernel.mk
中的流程。
生成 defconfig
在树莓派官方 bcm2711_defconfig
基础上进行增改(当前位于 OpenHarmony
目录):
增改主要有:
- OHOS上层系统所需:开启 SELinux, Binder, ALSA。
- 显示:开启 DRM, VC4。
- 触屏:开启 INPUT_TOUCHSCREEN, HID_MULTITOUCH, ADS7846, USB_COMPOSITE。因为我使用的微雪触屏控制器为 ADS7846,且是 USB 连线。
- 按键关机:开启 CONFIG_KEYBOARD_GPIO,以将 gpio-key 驱动编译进内核。
生成方法:
-
先进行一次内核编译:
再进入
out
下的内核源码根目录,利用menuconfig
配置.config
,最后用savedefconfig
保存: -
或者直接对
bcm2711_standard_defconfig
增改以下内容:由于本流程没有移植 HDF,因此不开启 HDF 驱动。
编译脚本修正
源码编译脚本默认生成 uImage,这要求树莓派4B用 u-boot 引导,比较费事。因此将 kernel/linux/build/
目录下的kernel.mk
, build_kernel.sh
, BUILD.gn
,kernel_module_build.sh
中的 uImage 都改为 zImage。
事实上不修改也没有关系。在最终生成 uImage 之前,内核编译时会在 boot
下首先生成 zImage,手动将其复制到镜像输出目录即可:
显示与触摸配置
显示
最后添加:
不设置一般也没有关系,默认通过card0节点显示。如果输出节点为 HDMI-A-1 并需要旋转,则添加:
触摸
修改为:
其中 WaveShare WS170120
为微雪触摸屏插入 usb 后,在 /sys/dev/char/xx\:xx/device/uevent
查询得到的设备名。支持 hid-multitouch
。
其它修正
init.cfg
初始化配置文件,类似于 Android 里的 init.rc
进行修改:
vendor
虽然没有移植 HDF 驱动,但是相关文件对内核编译流程是必要的。在 OpenHarmony/vendor
下新建文件,目录结构如下所示:
其中 hdf.hcs
均为:
Makefile
均拷贝自 OpenHarmony/vendor/hisilicon/Hi3516DV300/hdf_config/khdf/Makefile
camera.rpi4.gni
虽然没有移植 camera 驱动,但也对编译是必要的,否则报错:
镜像大小
镜像大小可以在 OpenHarmony/build/ohos/images/mkimage/
下的 xxx_image_conf.txt
里修改。
编译
在根目录 OpenHarmony
下执行:
下载的第三方开源软件压缩包存放于 OpenHarmony
同目录下的 OpenHarmony_2.0_canary_prebuilts
。其中脚本在用 wget
下载 mingw-w64 时,由于后者过大可能触发 Segmentation fault (core dumped)
。目前还没有找到比较好的解决方法,只有用其它下载工具手动从华为镜像下载 clang-mingw.tar.gz 后再放进去。
编译:
编译内核前脚本会在控制台打印编译命令,这方便我们在出错后或是修改config后,到内核源码根目录手动编译。手动编译时可能会出现找不到环境变量 PRODUCT_PATH
的错误,手动设置:
制作SD卡并启动
分区与格式化
利用 fdisk
设置 sd 卡分区:
步骤:
- 删除既有分区。(d 命令)
- 新建四个主分区,分别对应 boot, system, vendor 与 userdata。大小由对应镜像决定。(n 命令)
- 设置 p1 分区文件类型为 W95 FAT32 (LBA)。(t 命令后选择 c)
- 为 p1 分区添加可启动标志。(a 命令)
可能的最终效果(p 命令):
对应的 fdisk
内命令执行序列:
格式化:
制备boot
基于树莓派官方 firmware。设 boot 分区 /dev/mmcblk0p1
已经挂载到 /media/username/boot
下:
修改 config.txt
:
修改 cmdline.txt
:
我的 config.txt
与 cmdline.txt
可以在文章底部资源处下载,供大家参考。
刷写镜像
启动
为使微雪触摸屏成功显示,须满足以下三个条件:
-
config.txt
: 手动设置 HDMI 输出配置(来自官网要求:5inch_HDMI_LCD) -
config.txt
:dtoverlay=vc4-fkms-v3d
启用 fake KMS -
至少要在显示器启动前插入树莓派,且是远离 Type-C 的 Micro HDMI 口。保证树莓派能识别到屏幕。
按键关机
在配置内核编译 defconfig 时,我们开启了 CONFIG_KEYBOARD_GPIO
以将 gpio-key 编译进内核——这是一个与体系结构无关的 GPIO 按键驱动。只需要在设备树 gpio-key 节点添加需要的按键子节点后即可将 GPIO 状态变化转换为按键事件。
而树莓派官方已经有相应实现(详见 rpi-kernel/linux/arch/arm/boot/dts/overlays/README),只需要在 config.txt
开启即可:
这样,GPIO3 会被默认拉高,当它被接地时 gpio-key 就会将其转化为键码值 116 的按键事件输出到 /dev/input/event0
。
在主流的 Linux 发行版上(如基于 Debian 的 Raspbian OS),systemd 自带按键事件监听进程,只需在 /etc/systemd/logind.conf
中取消注释 HandlePowerKey = ignore
即可实现物理按键(或按 F5)关机。
Android 与 OpenHarmony 虽然不用 systemd,但可以运行服务。因此我们自己写一个简单的守护程序:
其中 /bin/reboot
是 OHOS 自带的重启/关机程序,源码位于 OpenHarmony/base/startup/init_lite/services/cmds/reboot/init_cmd_reboot.c
。
使用静态链接库编译以保证程序成功运行。设 system 分区 /dev/mmcblk0p2
已经挂载到 /media/username/_
下:
在 OHOS 初始化时,内核会遍历 /system/etc/init/
下的所有初始化配置。我们在该目录下写一个对应的 myservice.cfg
:
当我们在内核启动时观察到如下信息:
则意味着 myservice 成功启动了,可以利用物理按键关机。接线示意图:
很详细的讲解,感谢楼主分享。
非常棒的讲解,感谢分享
请问1直接照搬2吗? 用不用做什么修改?
对,就目前实现的触摸、显示、按键关机功能而言还不需要做什么修改,但如果后期移植了更多东西后肯定要做对应修改
您好,我在编译过程中遇到这个错误,看起来链接hdf的时候遇到问题,你有遇到过吗?
我的编译环境用的是3.0配套发布的swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker-standard:0.0.4

请问可以接摄像头吗
已解决,把config中对应的几个配置关掉即可
我下载的firmware为什么没有config.txt和cmdline.txt?
抱歉我的失误,我把我自己的上传到文章底部资源了
抱歉目前还没有实现摄像头的移植
你好,我现在用diff生成patch,然后把patch打进去报错很多。
然后用只打了HDF的rpi-5.10 kernel去编译,启动后卡在“binder: send failed reply for transaction 11426 to 1749:1774”。屏幕也没有显示。
能把你的patch发一下吗?感谢!
不好意思最近电脑不在身边……请问是什么样的报错?是执行的我给出的命令吗?
要记得把/home/username/Project/RPI/rpi-kernel/linux/改成自己的树莓派内核源码的绝对路径。如果打patch时出现了有关.git, .gitgitignore 以及某设备树文件的冲突,可以在diff之前把这些文件(夹)先从树莓派内核源码中移走
现在是跑起来了,只是会一直报错“binder: send failed reply for transaction 11426 to 1749:1774”卡住,串口没法输入,明天再看看啦。
显示已经有了,能进入系统,感谢!
楼主 小白一个 能不能告诉我具体要用到什么软件啊?而且他们的功能求求了