前言
以下是学习 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:
{
"device_name": "bcm2711",
"device_company": "brcm",
"target_os": "ohos",
"target_cpu": "arm",
"kernel_version": "",
"device_build_path": "device/brcm/build"
}
目前 OHOS 只支持 arm。
接着定义产品。建立文件 OpenHarmony/productdefine/common/products/rpi4.json:
{
"product_name": "rpi4",
"product_company": "raspberry",
"product_device": "bcm2711",
"version": "2.0",
"type": "standard",
"product_build_path": "device/brcm/build",
"parts": {
...
"brcm_products:brcm_products":{},
...
}
}
其中,… 部分照搬同目录下的 Hi3516DV300.json,并将其中的 "hisilicon_products:hisilicon_products":{},改为 "brcm_products:brcm_products":{},。
brcm_products 代表内核构建的子系统。我们需要在 OpenHarmony/build/subsystem_config.json 中定义它,加入键值对:
"brcm_products":{
"project": "hmf/brcm_products",
"path": "device/brcm/bcm2711/build",
"name": "brcm_products",
"dir": "device/brcm"
},
建立编译配置组件
接着在 OpenHarmony/device 下仿照 ./hisilicon/hi3516dv300 建立编译配置组件。目录结构:
device
└── brcm
├── bcm2711
│ ├── build
│ │ └── rootfs
│ │ ├── BUILD.gn
│ │ └── init.rpi4.cfg
│ └── BUILD.gn
└── build
├── BUILD.gn
└── ohos.build
OpenHarmony/device/brcm/bcm2711/build/rootfs/BUILD.gn
import("//build/ohos.gni")
ohos_prebuilt_etc("init.rpi4.cfg") {
source = "init.rpi4.cfg"
install_images = [ "system" ]
part_name = "brcm_products"
}
group("init_configs") {
deps = [
":init.rpi4.cfg"
]
}
OpenHarmony/device/brcm/bcm2711/build/rootfs/init.rpi4.cfg复制自OpenHarmony/device/hisilicon/hi3516dv300/build/rootfs/init.Hi3516DV300.cfg
OpenHarmony/device/brcm/bcm2711/BUILD.gn
import("//build/ohos.gni")
print("bcm2711_group in")
group("bcm2711_group") {
deps = [
"build/rootfs:init_configs",
"//kernel/linux/build:linux_kernel"
]
}
OpenHarmony/device/brcm/build/BUILD.gn
import("//build/ohos.gni")
group("products_group") {
deps = [
"//device/brcm/bcm2711:bcm2711_group"
]
}
OpenHarmony/device/brcm/build/ohos.build
{
"subsystem": "brcm_products",
"parts": {
"brcm_products": {
"module_list": [
"//device/brcm/build:products_group"
]
}
}
}
内核移植
内核编译流程
首先阅读 OpenHarmony/kernel/linux/build/kernel.mk
$(KERNEL_IMAGE_FILE):
$(hide) echo "build kernel..."
$(hide) rm -rf $(KERNEL_SRC_TMP_PATH);mkdir -p $(KERNEL_SRC_TMP_PATH);cp -arfL $(KERNEL_SRC_PATH)/* $(KERNEL_SRC_TMP_PATH)/
$(hide) cd $(KERNEL_SRC_TMP_PATH) && patch -p1 < $(HDF_PATCH_FILE) && patch -p1 -s -N < $(DEVICE_PATCH_FILE)
ifneq ($(findstring $(BUILD_TYPE), small),)
$(hide) cd $(KERNEL_SRC_TMP_PATH) && patch -p1 < $(SMALL_PATCH_FILE)
endif
$(hide) cp -rf $(KERNEL_CONFIG_PATH)/. $(KERNEL_SRC_TMP_PATH)/
$(hide) $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) distclean
$(hide) $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(DEFCONFIG_FILE)
ifeq ($(KERNEL_VERSION), linux-5.10)
$(hide) $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) modules_prepare
endif
$(hide) $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) -j64 uImage
endif
了解到内核编译的流程:
生成 patch
因此首先准备树莓派4B需要的内核补丁:
选择树莓派官方内核 rpi-5.10.y 来生成内核源码补丁。设控制台处在项目根目录 OpenHarmony 下,依次执行:
mkdir ../rpi-kernel && cd $_
git clone git://github.com/raspberrypi/linux -b rpi-5.10.y --depth=1
cd ../OpenHarmony/kernel/linux
diff -uNr linux-5.10/ /home/username/Project/RPI/rpi-kernel/linux/ > bcm2711.patch
mkdir patches/linux-5.10/bcm2711_patch && cp bcm2711.patch $_ && cd $_
cp ../hi3516dv300_patch/hdf.patch ./
注意 diff 命令:
实际编译时很可能会因为 patch 过程中出现冲突而中断,解决方法:
生成 defconfig
在树莓派官方 bcm2711_defconfig 基础上进行增改(当前位于 OpenHarmony 目录):
cp ../rpi-kernel/linux/arch/arm/configs/bcm2711_defconfig kernel/linux/config/linux-5.10/arch/arm/configs/bcm2711_standard_defconfig
增改主要有:
生成方法:
编译脚本修正
源码编译脚本默认生成 uImage,这要求树莓派4B用 u-boot 引导,比较费事。因此将 kernel/linux/build/ 目录下的kernel.mk, build_kernel.sh, BUILD.gn ,kernel_module_build.sh 中的 uImage 都改为 zImage。
事实上不修改也没有关系。在最终生成 uImage 之前,内核编译时会在 boot 下首先生成 zImage,手动将其复制到镜像输出目录即可:
cp out/KERNEL_OBJ/kernel/src_tmp/linux-5.10/arch/arm/boot/zImage out/ohos-arm-release/packages/phone/images
显示与触摸配置
显示
vi third_party/weston/weston.ini
最后添加:
[output]
name=card0
不设置一般也没有关系,默认通过card0节点显示。如果输出节点为 HDMI-A-1 并需要旋转,则添加:
[output]
name=HDMI-A-1
transform=rotate-90
触摸
vi third_party/eudev/rules.d/touchscreen.rules
修改为:
ATTRS{name}=="WaveShare WS170120", ENV{ID_INPUT}="1", ENV{ID_INPUT_TOUCHSCREEN}="1"
ATTRS{name}=="VSoC keyboard", ENV{ID_INPUT}="1", ENV{ID_INPUT_KEYBOARD}="1"
DRIVERS=="hid-multitouch", ENV{ID_INPUT}="1", ENV{ID_INPUT_TOUCHSCREEN}="1"
其中 WaveShare WS170120 为微雪触摸屏插入 usb 后,在 /sys/dev/char/xx\:xx/device/uevent 查询得到的设备名。支持 hid-multitouch 。
其它修正
init.cfg
初始化配置文件,类似于 Android 里的 init.rc
vi /base/startup/init_lite/services/etc/init.cfg
进行修改:
- "/etc/init.Hi3516DV300.cfg"
+ "/etc/init.rpi4.cfg"
- "mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor wait rdonly barrier=1",
- "mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data wait nosuid nodev noatime barrier=1,data=ordered,noauto_da_alloc"
+ "mount ext4 /dev/block/mmcblk0p3 /vendor wait rdonly barrier=1",
+ "mount ext4 /dev/block/mmcblk0p4 /data wait nosuid nodev noatime barrier=1,data=ordered,noauto_da_alloc"
vendor
虽然没有移植 HDF 驱动,但是相关文件对内核编译流程是必要的。在 OpenHarmony/vendor 下新建文件,目录结构如下所示:
vendor
└── raspberry
└── rpi4
└── hdf_config
├── hdf.hcs
├── hdf_test
│ ├── hdf.hcs
│ └── Makefile
├── khdf
│ ├── hdf.hcs
│ └── Makefile
├── Makefile
└── uhdf
└── hdf.hcs
其中 hdf.hcs 均为:
root {
module = "default";
}
Makefile 均拷贝自 OpenHarmony/vendor/hisilicon/Hi3516DV300/hdf_config/khdf/Makefile
camera.rpi4.gni
虽然没有移植 camera 驱动,但也对编译是必要的,否则报错:
cp drivers/peripheral/camera/hal/adapter/chipset/gni/camera.rpi3.gni drivers/peripheral/camera/hal/adapter/chipset/gni/camera.rpi4.gni
镜像大小