OpenHarmony开发者论坛
标题:
第三方内核khdf移植分析报告
[打印本页]
作者:
Laval社区小助手
时间:
2024-3-7 10:34
标题:
第三方内核khdf移植分析报告
[md]## 1 关键字
khdf移植
## 2 问题描述
### 2.1 运行环境
* 软件环境:
* OH版本:3.1-Release
* 内核版本:firefly rk3568 4.19
* 硬件环境:
* firefly rk3568-pc
* 编译环境:
* firefly 提供的编译脚本。./build.sh kernel
### 2.2 问题现象:
咨询描述:使用第三方开发板内核sdk(linux-4.9)快速移植内核后,hdf相关设备节点缺失。
咨询场景描述:使用第三方开发板内核sdk(linux-4.9)快速移植内核后,/dev/hdf\_kevent这个备没有,导致hdf\_devmgr启动失败,进而导致无法解析deviceinfo.hcs中的host node无法解析加载。如果使用hdf\_devhost强制加载也会提示/dev/hdf\_kevent找不到。
### 2.3 测试步骤
执行命令查看/dev/\*hdf\*相关设备节点情况。
```
# ls /dev/*hdf*
ls: /dev/*hdf*: No such file or directory
#
```
## 3 问题原因
### 3.1 正常机制
* 在正常情况下,在第三方内核打入khdf patch后,会在kernel源码工程中会生成如下目录:
![img](
https://devpress.csdnimg.cn/489a999a5f2348cb93a4b64f334a637a.png
)
绿色代表新增加khdf需要增加的目录结构,黄色代表原有目录结构。
同时正常编译下载后,/dev/ 下也会增加相关hdf的文件描述符:
```
# ls /dev/*hdf*
/dev/hdf_kevent
```
### 3.2 异常机制
* 在dev下找不到与HDF相关的设备描述文件,khdf没有安装。
## 4 解决方案
当前解决方案以firefly rk3568-pc提供的kernel-4.19为例。
### 4.1、拷贝firefly kernel代码
```
# 1.1 创建firefly-rk3568目录
root@ubuntu:~/ohos/openharmony/3.2-release# pwd
/root/ohos/openharmony/3.2-release
root@ubuntu:~/ohos/openharmony/3.2-release# mkdir out/kernel/src_tmp/firefly-rk3568
# 1.2 拷贝以下文件到目录
root@ubuntu:~/ohos/openharmony/3.2-release/out/kernel/src_tmp/firefly-rk3568# ls
device kernel prebuilts rkbin tools
# 1.3 创建编译脚本
ln -s device/rockchip/common/build.sh build.sh
# 1.4 初始化配置
./build.sh roc-rk3568-pc-buildroot.mk
```
### 4.2、通过pathc\_hdf.sh打补丁
```
./patch_hdf.sh [工程根目录路径] [内核目录路径] [hdf补丁文件]
```
```
# 2.1 设置PROJ_ROOT、PRODUCT_PATH路径
export PROJ_ROOT=/root/ohos/openharmony/3.2-release
export PRODUCT_PATH=vendor/hihope/rk3568
# 2.2 执行patch_hdf.sh脚本
$PROJ_ROOT/drivers/adapter/khdf/linux/patch_hdf.sh $PROJ_ROOT $PROJ_ROOT/out/kernel/src_tmp/firefly-rk3568/kernel $PROJ_ROOT/kernel/linux/patches/linux-4.19/hispark_taurus_patch/hdf.patch
```
### 4.3、拷贝内核基础代码
目前OpenHarmony内核态的基础代码,主要包含以下两个模块:
drivers/staging/hilog drivers/staging/hievent
```
cd $PROJ_ROOT/out/kernel/src_tmp/firefly-rk3568/kernel
# 3.1拷贝到内核
cp -r $PROJ_ROOT/kernel/linux/linux-4.19/drivers/staging/hilog drivers/staging/
cp -r $PROJ_ROOT/kernel/linux/linux-4.19/drivers/staging/hievent drivers/staging/
# 3.2 添加到drivers/staging/Kconfig
source "drivers/staging/hilog/Kconfig"
source "drivers/staging/hievent/Kconfig"
# 3.3 添加到内核配置项
CONFIG_HILOG=y
CONFIG_HIEVENT=y
```
### 4.4、修改编译参数
```
# 4.1 添加到内核配置项
CONFIG_DRIVERS_HDF=y
CONFIG_HDF_SUPPORT_LEVEL=2
CONFIG_DRIVERS_HDF_PLATFORM=y
CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y
CONFIG_DRIVERS_HDF_PLATFORM_I2C=y
CONFIG_DRIVERS_HDF_PLATFORM_UART=y
# 4.2 修改编译选项
cd $PROJ_ROOT/out/kernel/src_tmp/firefly-rk3568
# 4.2.1 去掉-mgeneral-regs-only (kernel/arch/arm64/Makefile)
# 4.2.2 去掉以下编译参数 (kernel/MakeFile)
# -Wstrict-prototypes
# -Wundef
# KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes)
# KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
# 4.2.3 添加-Wno-unused-variable -Wno-unused-function(kernel/MakeFile)
# 4.2.4 kernel/drivers/hdf/framework/support/platform/src/uart/uart_service.c
UartIoWrite() size_t size; 改成 int size;
# 4.2.5 屏蔽memmove_s memcpy_s memset_s memset_s重定义
./kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmstdlib_s.c
屏蔽对memmove_s memcpy_s memset_s memset_s的实现
```
### 4.5、编译
```
./build.sh kernel
```
如果需要与OpenHarmony 一起编译。需要把kernel/bounds\_checking\_function/bundle.json删掉。
### 4.6、hdf测试
#### 4.6.1、添加khdf测试配置依赖
```
CONFIG_DRIVERS_HDF_TEST=y
```
使用编译成功后的boot.img下载到设备
#### 4.6.2、编译uhdf 测试程序
```
./build.sh --product-name rk3568 --build-target hdf_test_uhdf
```
#### 4.6.3、发送到设备并执行
使用hdc发送hdf\_adapter\_uhdf\_test\_manager到设备
```
hdc_std file send \\192.168.134.153\share\openharmony\3.1-release\out\rk3568\tests\unittest\hdf\manager\hdf_adapter_uhdf_test_manager /data
FileTransfer finish, Size:146520 time:21ms rate:6977.14kB/s
```
添加可执行权限并执行
```
cd /data
chmod a+x hdf_adapter_uhdf_test_manager
./hdf_adapter_uhdf_test_manager
```
#### 4.6.4、测试结果
```
:s0 clasee 252 device list:
tclaclasee 253 device list:
ss=diclasee 254 device list:
r peclasee 255 device list:
rmis[ OK ] HdfManagerTest.HdfGetServiceNameBysDeviceClass001 (58 ms)
[----------] 4 tests from HdfManagerTest (64 ms totali)
[----------] mGlobal test environment teare-down
=1
[ 375.519349] [I/osal_cdev] add cdev sample_service1 success
[ 375.519349]
[ Gtest xml output finished
3[==========] 4 tes7ts from 1 test case ran. (675 ms total)
[ PASSED. ] 4 tests.
```
可以看到PASSED代表测试成功
## 5 定位过程
没有找到/dev/kevent设备描述符,是因为khdf没有适配好,通过标准化添加khdf解决。
## 6 知识分享
khdf在OpenHarmony中是非常重要的框架,与uhdf共同组成hdf框架。旨在为开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。 基于HDF(驱动框架)开发驱动,开发者只需注册所需接口和配置,驱动框架就会解析配置内容,完成驱动加载和初始化动作。
khdf对vmlinux.lds.S 中的依赖:
```
+#ifdef CONFIG_DRIVERS_HDF
+ .init.hdf_table : {
+ _hdf_drivers_start = .;
+ *(.hdf.driver)
+ _hdf_drivers_end = .;
+ }
+#endif
```
这个是驱动程序的加载入口。
```
static struct HdfDriverEntry g_hdfKeventDriverEntry = {
.moduleVersion = 1,
.moduleName = "HDF_KEVENT",
.Bind = HdfKeventDriverBind,
.Init = HdfKeventDriverInit,
.Release = HdfKeventDriverRelease,
};
HDF_INIT(g_hdfKeventDriverEntry);
```
其中HDF\_INIT(g\_hdfKeventDriverEntry) 就是把符号表g\_hdfKeventDriverEntry注册到.init.hdf\_table段中,然后由KHDF框架统一加载启动HDF\_INIT()注册的驱动。
在vendor/hihope/rk3568/hdf\_config/khdf/light/light\_config.hcs中有对硬件信息的描述,类似dts。
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5