当前位置: 首页 > 科技观察

OpenHarmony富设备迁移指南(四)第三方内核适配定制

时间:2023-03-17 17:13:10 科技观察

了解更多开源请访问:开源基础软件社区https://ost.51cto。COM1。为什么OpenHarmony移植如此困难?为什么OpenHarmony移植花了这么长时间才出来?Android手机厂商开源内核代码后,LineageOS可以快速跟进。这应该是很多网友不解的事情。暂时,这与内核和驱动程序直接相关。下面是我总结的简单解释:Linux设备:标准Linux内核+硬件驱动Android设备:Android内核(标准内核+Android定制)+硬件驱动(调用部分自定义接口)OH设备:OH内核(标准内核+Android定制)OHcustomization)+hardwaredriver(调用一些自定义接口)如果Android设备驱动调用了Androidkernel-specific接口,则Androiddriver不能在标准内核上使用,也不能在OHkernel上使用。如果Android驱动调用了标准Linux内核的接口,是可以在OH设备上使用的,但这种情况很少见,这也是为什么在pMOS中可以看到部分设备的支持状态。很多网友在将OpenHarmony移植到自己的手机上后,期望OpenHarmony能够打电话,认为只要开发者坚持,就一定能成功。有了OH内核的驱动,厂家不可能花心思帮你适配基于OH内核的驱动,所以我在移植适配评测的时候,参考的是pMOS,因为pMOS使用的是标准的Linux内核,为什么不能使用UbuntuTouch内核??了解过的同学应该知道,UbuntuTouch使用的是Android内核,可以使用Android驱动,所以小米6支持UbuntuTouch打电话,而pMOS不支持。另外,每次Linux内核版本变化,代码都会频繁改动,导致同样的代码有可能编译不出来。这也是SOC厂商和驱动厂商不积极升级内核版本的原因。长期以来,移植OpenHarmony一直是吃力不讨好的事,而且只能开着开着,没有驱动,卡在上限,所以移植也不是费力就能搞定的。希望大家能够理解。2、OH内核特性移植到OH官方文档仓库。标准内核介绍中有一些对OH内核特性的解释(如下图所示)。遗憾的是,这只是一部分,一些更基础的驱动没有列出来。接下来,我们先移植基础。对于部分,保证开机亮屏,更高级的功能不会移植。zh-cn/device-dev/kernelOpenHarmony/docs-码云-开源中国(gitee.com)1.在之前的文章【OH编译框架适配与定制】中添加设备内核编译配置文件我们有下载源码到kernel/linux/linux-sagit目录,然后我们在【从postmarketOS获取移植资源】一文中找到解压出来的config配置,把config放在device/board/xiaomi/sagit/kernel/configs并重命名为sagit_oh_defconfig,因为我自定义了Linux编译过程,我的编译脚本会将sagit_oh_defconfig复制到linux-sagit/arch/arm64/configs。熟悉Linux内核编译的同学也可以按照自己的想法去做。这部分只是添加移植设备的编译配置。2、移植OH在staging下添加的hilog、hievent、hisysevent、zerohung、hungtask、blackbox驱动(1)移植驱动前更新最新内核代码,我们先将官方内核更新到最新版本,尽量保证驱动程序没有bugcd~/ohos_beta3/kernel/linux/linux-5.10/gitfetchoriginitcheckoutorigin/master1.2.3。(2)复制代码,修改linux-5.10/driver/staging/下的Kconfig、Makefile复制hilog、hievent、hisysyvent、zerohung、hungtask、blackbox源码到linux-sagit/driver/staging/目录下。修改linux-sagit/driver/staging/下的Kconfig文件,在最后添加如下信息。修改linux-sagit/driver/staging/下的Makefile文件,在最后添加如下信息。仅仅复制staging下的文件是不行的,编译的时候会报错,缺少一些头文件。将linux-5.10/include下的dfx文件夹复制到linux-sagit/include下。同时,linux-5.10/include/linux/下的三个头文件。blackbox.h、blackbox_storage.h、blackbox_common.h。还需要复制到对应的linux-sagit/include/linux/下完成头文件。(3)修复get_fs()、set_fs()函数缺失问题头文件编译完成后仍然会报错。我发现这是因为mm_segment_t、get_fs()、set_fs()等结构体和函数在新版内核中被移动了。除了,它被标记为在5.10内核中删除。我不知道为什么OH内核维护者没有删除它。这个操作会带来安全问题,现代的CPU已经不支持了,所以我们可以大胆去掉这部分。代码,我其实验证过不影响内核的运行,所以搜索我们移植的文件,全部删除。这是我改的,注释掉的部分是没用的代码。(4)修复inode_permission()、vfs_mkdir()、vfs_unlink()函数参数。由于API变更,增加了以上三个函数参数。我参考了其他内核代码的调用,确认加入[&init_user_ns]参数可以解决问题。修改如下图所示:在内核编译sagit_oh_defconfig末尾添加如下配置,编译内核一次看是否成功。3、移植accesstokenid驱动(1)复制驱动代码,修改Kconfig,Makefile将linux-5.10/drivers下的accesstokenid文件夹复制到linux-sagit/drivers文件夹下。同理,对accesstokenid驱动添加Kconfig和Makefile修正。(2)修改accesstokenid驱动关联文件通过[CONFIG_ACCESS_TOKENID]查找,发现红框中的文件有accesstokenid相关的变化,需要手动处理。linux-5.10官方内核的变化是在[FORBIDDEN_MMAP_FLAGS]后面增加了代码。我们还将[CONFIG_ACCESS_TOKENID]中包含的代码复制到linux-sagit内核中,[ACCESS_TOKENID_FEATURE_VALUE]和[BINDER_CURRENT_FEATURE_SET]依赖[ENABLE_ACCESS_TOKENID],一起复制。接下来就是捉迷藏的游戏,找出这些变化,然后根据插入位置的上一行代码或者下一行代码进行查找,转移到相应的位置,手动合并变化。对于一些找不到对应位置的,有可能声明已经移到.h头文件中了。比如binder_thread结构体在5.10版本被放在binder.c文件中,6.0版本被提取到binder_internal.h中。还有一些改动是添加到switch上的,直接放在default前面就行了。linux-5.10:linux-sagit:这里需要注意[BINDER_FEATURE_SET]一起复制过来,因为都是OH添加的。一开始我没有复制,所以启动的时候日志一直报binder错误,然后通过gitee函数逐行查看,查看了binder.c的代码后,确认这段代码也是自己添加的OH组,属于ACCESS_TOKENID的相关函数。还有一些upstream的代码优化了写法,只有看懂了代码才能改,比如下面这段binder_init.在kernel-5.10的binder_init中,OH在[debugfs_create_file("failed_transaction_log")之后添加了一段代码。在我们的linux-sagit中,是linux6.0的代码,优化过,找不到插入位置和之前一样直接,新版本直接使用for循环简化了一大段代码,为了保证移植的正确性,这时候我们需要对代码运行进行分析。旧版本:1.debugfs_create_dir("binder",NULL);2.debugfs_create_dir("proc",binder_debugfs_dir_entry_root);3.debugfs_create_file("state"/"transactions"...4.(OH)proc_create_data("transaction_proc"...Newversion:1.debugfs_create_dir("binder",NULL);2.debugfs_create_file("state"/"transactions"..3.debugfs_create_dir("proc",binder_debugfs_dir_entry_root);根据函数名可以知道OHRelated(proc)新增的时间进程,在2.debugfs_create_dir("proc",binder_debugfs_dir_entry_root)后面;,所以我们参考这个逻辑,新版本的变化可以对应新版本:1.debugfs_create_dir("binder",NULL);2.debugfs_create_file("state"/"transactions"..3.debugfs_create_dir("proc",binder_debugfs_dir_entry_root);4.(OH)proc_create_data("transaction_proc"...至此我把我移植时遇到的问题和解决方法说完了,大家可以按照上面的方法找到需要移植的代码,并将其添加到相应的位置。4、反向移植ashmem驱动后,发现桌面图标点亮后无法显示。hilog疯狂提示dberror。定位发现需要ashmem驱动,但是这个驱动在linux5.18被去掉了。我们需要把它重新移植回来,我参考了网上SoulInfernoDE公布的恢复ashmem驱动的方法wget-Oremove_ashmem.patchhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=721412ed3d819e767cac2b06646bf03aa158aaecinterdiff-qremove_ashmem.patch/dev/null>enable_ashmem.patchpatch-p1-ienable_ashmem.patch1.2.3。同时[CONFIG_ANDROID]这个flag已经去掉了,我们还需要做一些修改才能正常编译ashmem驱动。在Makefile下暂存。obj-$(CONFIG_ANDROID)更改为obj-y。在staging/android下的Kconfig中。去掉ifANDROID的判断。至此,内核代码的变化解释完毕。三、修改内核编译配置1、为设备添加必要的内核驱动。在我们之前解压出来的文件中,有一个deviceinfo文件,可以看到。启动时,内核需要加载以下模块:panel-jdi-fhd-r63452msmi2c-quprmi_i2cqcom_spmi_fgqcom_spmi_haptics。我们直接将它们编译进内核,这样就不需要修改gn来处理ko模块文件,也不需要写init配置文件来添加启动时加载模块的语句。运行命令进入内核配置菜单make-C/home/diemit/OpenHarmony/out/KERNEL_OBJ/kernel/src_tmp/linux-sagitARCH=arm64CC="/home/diemit/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang"HOSTCC="/home/diemit/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang"PERL=/usr/bin/perlCROSS_COMPILE="/home/diemit/OpenHarmony/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-"menuconfig1.按键盘[/]键搜索,输入[r63452]获取驱动状态和菜单位置,我以前做过,所以现在是y(编译进内核),默认是m(编译成模块)。2、添加相关的相关驱动将上面列出的所有需要??的驱动编译进内核,同时将相关的驱动编译进内核,例如:触摸屏会和Inputdevicesupport中的事件接口相关,不一起触摸屏驱动编译进内核后不能正常工作。添加ashmem驱动程序。3、添加OH自定义驱动添加accestoken驱动,hdf不能选。添加关联的binderipc驱动程序。添加hilog、hievent等驱动。4、添加调试所需的驱动程序。根据pMOS的指导,添加usb串口驱动??Serialdebugging/SerialGadget-postmarketOSCONFIG_USB_G_SERIAL=yCONFIG_U_SERIAL_CONSOLE=yCONFIG_USB_U_SERIAL=y1.2.3。根据pMOS给出的配置,在menuconfig界面搜索对应的驱动选择,或者直接编辑defconfig文件添加。至此内核相关定制适配讲解完毕,下篇将讲解打包刷机调试,敬请期待。了解更多开源请访问:开源基础软件社区https://ost.51cto.com