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