#夏日挑战赛# OpenHarmony3.2Beta1 移植到RaspberryPi 4B 原创
简介
摸着各路大神过江,初步移植OpenHarmony3.2Beta1成功,第一次做分享,编辑排版什么的都很粗糙,各位看官见谅
B站视频链接
https://www.bilibili.com/video/BV1dB4y1p7sR?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=ec7ef22748a6df239398ec368867dbcc
本次移植的相关代码见码云仓库:
https://gitee.com/diemit/vendor_raspberrypi/tree/OpenHarmony-3.2-Beta1/
https://gitee.com/diemit/device_board_raspberrypi/tree/OpenHarmony-3.2-Beta1/
https://gitee.com/diemit/device_soc_broadcom/tree/OpenHarmony-3.2-Beta1/
下面简单分享下移植思路
1,适配编译框架
适配编译框架可以参考赵老师的文章
https://blog.csdn.net/qq_41795122/article/details/124329510
虽然是3.1-Release的,但是思路差不多,就是不断的试错然后从别的地方复制文件,网上也有很多教程了,
我这里就只列举出我觉得比较关键的地方,下面开始
1.1 在vendor目录下新建++产品厂商++文件夹【raspberrypi】
目录结构如下
从华为海思的开发板hispark_taurus把图示的文件都复制过来
其中需要修改
config.json
"product_name": "hispark_taurus_standard",
"device_company": "hisilicon",
"device_build_path": "device/board/hisilicon/hispark_taurus/linux",
"target_cpu": "arm",
"type": "standard",
"version": "3.0",
"board": "hispark_taurus",
"enable_ramdisk": true,
...
{
"subsystem": "hisilicon_products",
"components": [
{
"component": "hisilicon_products",
"features": []
}
]
},
...
这是我修改后的,没有device_build_path也可以,我没写也能成功编译
"product_name": "rpi4",
"version": "3.0",
"type": "standard",
"target_cpu": "arm",
"ohos_version": "OpenHarmony 3.2Beta1",
"device_company": "raspberrypi",
"board": "rpi4",
"enable_ramdisk": false,
...
{
"subsystem": "raspberrypi_products",
"components": [
{
"component": "raspberrypi_products",
"features": []
}
]
},
...
product.gni
import("//device/board/${device_company}/hispark_taurus/device.gni")
import("//device/board/raspberrypi/${device_name}/device.gni")
1.2 在device/board目录下新建++开发板厂商++文件夹【raspberrypi】
目录结构如下
这里的目录结构我参考的是rk3568的,
其中的camera文件夹参考树莓派3的适配,我按照新的规范重新组织了目录结构而已
https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/hal/adapter/chipset/rpi/rpi3/device/camera/src
cfg是系统的一些配置文件,可以用自己的配置文件覆盖系统默认的配置文件
image打算做合并镜像的,还在参考别的大神(亮子立,xfan1024)的脚本开发中
kernel是我参考官方的kernel_build的自己编译内核的脚本,这里可以展开讲一下
官方编译内核的方式是把
- 【项目根目录】/kernel/linux/linux-5.10下的源码复制到
【项目根目录】/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10 - 然后复制kernel的config,打三方芯片的补丁,打hdf补丁,最后进行编译
我因为用的是第三方内核,所以仿造这个思路,
- 我把树莓派官方的内核源码linux-rpi-5.10复制到【项目根目录】/out/KERNEL_OBJ/kernel/src_tmp/linux-rpi-5.10
- 然后复制kernel的config,然后打hdf补丁,然后编译内核
注意这里的目录结构不能随意改变,这个目录涉及到hdf框架的相对目录层次,我就是手欠改过导致hdf编译出错找了好久才明白,Openharmony这个编译系统很多用的是相对目录,所以目录结构不要自己随意变更
modules,patches,test是我用来存放一些辅助开发的目录,这里不做介绍了
1.3 在device/soc目录下新建++芯片厂商++文件夹【broadcom】
目录结构如下
我这里参考DAYU200开发板的目录,树莓派4用的是博通的bcm2711,所以rockchip对应了broadcom,rk3568对应了bcm2711
hardware里面的display是这次移植的重点
这里参考xfan1024适配树莓派3的代码
https://gitee.com/xfan1024/oh-rpi3b-device/blob/master/hardware/display/BUILD.gn
xfan1024是直接指向了官方默认的display实现,然后用打补丁的方式修改官方默认的实现
我按照了官方解耦的做法,把默认实现的代码都复制到了我适配的文件夹下,然后进行修改,避免修改官方的代码,
复制过来的代码中XX/OpenHarmony/device/soc/broadcom/hardware/display/BUILD.gn里面需要修改一些路径,官方写的是相对于代码的当前路径,我们需要修改成项目的相对路径,名称也把def前缀去掉
display方面的修改我打算放到【3,适配图形显示】进行讲解,这里就不展开了
总之,编译框架的适配就是把自己的适配代码放到vendor,device_board,device_soc这三个文件夹下,然后不断查漏补缺直到编译通过就OK了
2,适配内核
Openharmony官方有一篇第三方移植OpenHarmony Linux内核的方法
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/porting-linux-kernel.md
那时候还是适配3.0的,现在OpenHarmony Linux内核添加了挺多特性,而且很多特性是只能修改内核代码的,不能像hdf那样独立出来然后用软连接的形式链接到内核源码中,这里有一些特性的介绍,但是官方好久没更新了
https://gitee.com/openharmony/docs/tree/master/zh-cn/device-dev/kernel
比如binder驱动新增tokenid的获取和传递等功能,这种是跟我们移植适配有关的,这么久了也没有看到文档。
要适配内核,有两种思路
1.抽出芯片适配代码,做成补丁,编译的时候使用OpenHarmony Linux内核,打上自己的芯片补丁,这个是官方的做法
2.用第三方的内核,抽出OpenHarmony Linux内核的特性补丁,打到自己的三方内核上
抽出芯片适配代码,做成补丁这个需要投入的精力和时间太大,类似于移植芯片到新版linux上,我不会移植芯片到Linux内核所以我选择了第二种方案。
2.1下载三方内核源码
我下载的是树莓派官方内核5.10版本
git clone --depth=1 -b rpi-5.10.y https://github.com/raspberrypi/linux.git linux-rpi-5.10
2.2下载OpenHarmony Linux内核特性补丁
首先找出OpenHarmony Linux内核特性补丁
打开官方的kernel_linux_5.10仓库,打开Pull Requests,点击已合并分类
在标题中找到类似这种描述的标题,然后合并到master分支的pr,这种就是OpenHarmony Linux内核特性补丁,cve bugfix这种我们不用管,这种不是OpenHarmony Linux内核特性补丁。
下载补丁
这里我以pr11为例
点击进入pr详情,然后点击下载diff文件即可,当然,程序员就是要让程序帮我们把做重复的操作
这里我写了一个脚本,根据pr编号下载补丁文件,下载之后会进行补丁的验证,不能直接用,需要修改对应的目录哈,然后下载完之后还有个补丁验证操作,因为只是验证,没有真的打上补丁,所以越后面的补丁基本都会报错,因为后面的补丁是以前面的补丁为基础的,实际使用的时候可以把验证的这部代码注释掉
https://gitee.com/diemit/device_board_raspberrypi/blob/OpenHarmony-3.2-Beta1/rpi4/patches/openharmony_kernel_patch.py
另外,hilog的首支补丁不是以pr的形式提交的,所以在pr里面找不到,我在这里提供一下链接,同样下载diff文件即可,可以命名为1.diff
https://gitee.com/openharmony/kernel_linux_5.10/commit/286181507c841fcc293a0a5761204bf8d8d79cc7
打补丁
cd 到要打补丁的内核目录下,然后一路 git apply就好
git apply /home/diemit/OpenHarmony/device/rpifdn/patches/kernel-5.10/1.diff
有冲突的话加上–reject参数,然后手动解决一下冲突就好,我合并了这么多,也就不到十个有冲突,而已基本上就是一两行有,很好解决,内核新增的选项配置的话有空我整理一下吧,不保证时间
3,适配图形显示
目前显示用的cpu渲染,先点亮再说哈
图形适配首先需要内核支持,参考亮子力的这篇文章,把驱动直接编译进内核
https://ost.51cto.com/posts/9473
我用的屏幕是微雪的4.3寸dsi屏幕,跟树莓派官方驱动直接兼容的,所以少了很多麻烦
接下来就是处理图形适配的这些文件了
官方有个dayu200的适配文档写得很详细,可以适当参考下,我就删掉了海思的私有库实现而已
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/porting/porting-dayu200-on_standard-demo.md#显示适配
display_device,display_gralloc,display_layer_video,utils这些是直接复制官方目录下的
经过各种资料查询,确认树莓派4的bcm2711是没有2d加速功能的,所以display_gfx不用适配了,我这里复制了一份unionpi的代码占个坑,里面也只是直接返回DISPLAY_SUCCESS的,没有什么处理
https://gitee.com/algoideas/device_unionpi/blob/master/hardware/display/src/display_gfx/display_gfx.c
按照我目前的成果,官方的代码只要修改设备的名称为vc4就好,这里也是参考了xfan1024适配树莓派3的代码
https://gitee.com/xfan1024/oh-rpi3b-projectpatch/blob/master/patches/drivers_peripheral/0001-support-rpi3.patch
std::shared_ptr<HdiDeviceInterface> DrmDevice::Create()
{
DISPLAY_LOGD();
if (mDrmFd == nullptr) {
const std::string name("vc4");
然后修改XX/OpenHarmony/foundation/graphic/graphic/rosen/modules/render_service/BUILD.gn
添加上自己的产品名
到这里图形适配就完了,是不是简单到不可思议
4,编译出固件烧写进tf卡
复制出xx/OpenHarmony/out/rpi4/packages/phone/images目录下的system.img和vendor.img到一个临时目录
然后调整一下大小
resize2fs system.img 1024M
resize2fs vendor.img 64M
Linux下用cfdisk分区会比较方便,记得要根据自己写的fstab.required,fstab.rpi4来分区
之后写入到U盘里面
写入SYSTEM分区
sudo dd if=system.img of=/dev/sdb2 bs=4M
写入VENDOR分区
sudo dd if=vendor.img of=/dev/sdb3 bs=4M
data分好区后格式化为ext4即可
boot分区,就是放编译出来的内核和设备树,还有树莓派启动的配置
这是boot分区的一些文件
cmdline.txt
console=tty1 console=serial0,115200 no_console_suspend root=/dev/mmcblk0p2 rw rootfstype=ext4 elevator=deadline rootwait androidboot.selinux=permissive hardware=rpi4
console=tty1可以让log输出到屏幕,开机的时候会一堆信息刷屏,显得比较牛逼一点
console=serial0,115200是输出到urat串口,用来调试
config.txt
hdmi_force_hotplug=1
hdmi_drive=2
hdmi_group=1
hdmi_mode=1
avoid_warnings=2
dtoverlay=vc4-fkms-v3d
enable_uart=1
kernel=zImage
uart_2ndstage=1
弄完之后插卡上电,之后就可以体验一下自己的成果了
之后可能我还会分享一篇用nfs挂载系统根目录,然后远程启动树莓派的帖子,看看什么时候有空吧
太强了,点赞收藏评论3连了
尝鲜固件
你好,请问下,我在移植的时候,modetest已经能正常显示屏幕了,然后在移植openharmony的时候,任何显示画面都没有,使用hilog | grep DISP查看信息一直有报错:
394 I 01400/DISP: [Allocate@drm_allocator.cpp:57] fmt 0xc create dumb width: 1024 height: 600 bpp: 32 pitch 4096 size 2457600
-01 00:11:40.109 303 394 E 01400/DISP: [Allocate@drm_allocator.cpp:59] DRM_IOCTL_MODE_CREATE_DUMB failed errno 12
但是我手动模拟的场景是一直使用ioctl命令DRM_IOCTL_MODE_CREATE_DUMB申请显存的时候才会出错,我想请问下楼主知道这个是需要一直申请的吗,即下面这段代码
dumb.height = ALIGN_UP(height, HEIGHT_ALIGN);
dumb.width = ALIGN_UP(AdjustStrideFromFormat(format, width), WIDTH_ALIGN);
dumb.flags = 0;
dumb.bpp = fmtInfo->bitsPerPixel;
ret = drmIoctl(gbm->fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
DISPLAY_LOGI("fmt 0x%{public}x create dumb width: %{public}d height: %{public}d bpp: %{public}u pitch %{public}d "
"size %{public}llu",
format, dumb.width, dumb.height, dumb.bpp, dumb.pitch, dumb.size);
DISPLAY_CHK_RETURN((ret != 0), NULL, DISPLAY_LOGE("DRM_IOCTL_MODE_CREATE_DUMB failed errno %{public}d", errno));
首先问一下你现在适配的是什么版本,还有你适配的是不是cpu渲染,cpu渲染的我已经适配到3.2beta4点亮了,gpu渲染方面我还在研究mesa3d,目前还没起来,cpu渲染的话可以给你解答一下
你好,适配的是OpenHarmony v3.1.4 Release 标准版本,用cpu渲染的场景下
我修改内核配置之后,不会报上面的错误了,但是还是无法显示开机动画啥的界面,使用 hilog | grep BootAnimation一直刷下面的信息,不知道是哪里没有适配好。
void OHOS::HiviewDFX::ServiceController::CommunicationLoop(const std::atomic<bool> &) Begin
01-01 00:05:16.400 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.401 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.401 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.415 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection name:BootAnimation, ret:8
01-01 00:05:16.569 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.569 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.570 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.582 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection name:BootAnimation, ret:8
01-01 00:05:16.583 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.583 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.584 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.598 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection name:BootAnimation, ret:8
01-01 00:05:16.600 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.600 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.601 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.612 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection name:BootAnimation, ret:8
01-01 00:05:16.614 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.614 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.614 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.628 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection name:BootAnimation, ret:8
01-01 00:05:16.630 239 239 I 00000/BootAnimation: Draw: OnDraw frame is nullptr
01-01 00:05:16.630 239 239 I 00000/BootAnimation: CheckExitAnimation: CheckExitAnimation enter
01-01 00:05:16.634 240 1029 I 00000/VsyncDistributor: RequestNextVSync: conn name:BootAnimation, rate:0
01-01 00:05:16.644 240 578 I 00000/VsyncDistributor: ThreadMain: Distributor name:app, connection n
有群吗,想加个群一起学习下
我自己的群没有,微信上有个ohos第三方板移植,你可以申请加入
那可以创建个啊,一起交流学习
踩个脚印,作为以后学习的阶梯。谢谢楼主共享学习过程!
你好,我现在也有遇到DRM_IOCTL_MODE_CREATE_DUMB failed errno 12的问题,请问你是改内核哪些地方的呢