Linux内核增加HDF驱动子系统

HDF驱动子系统是OpenHarmony重要的特色功能之一,其主要的功能是实现驱动程序在多内核多平台的物联网环境,实现一次驱动开发,多端部署。之前移植OHOS3.0使用了传统的linux驱动,比较遗憾,今天尝试将HDF驱动子系统加入编译框架。开始前先了解几个名词。

HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述源码,JSON存储。

HC-GEN(HDF Configuration Generator)是 HCS 配置转换工具,可以将 HDF 配置文件HCS转换为二进制HCB。

HCB(HDF Configuration Binary)二进制文件,驱动可使用 HDF 框架提供的配置解析接口获取配置。

内核打补丁

如何在内核加入HDF驱动,linux内核下主要实现是下面两个目录:

drivers\adapter\khdf\linux 和 drivers\framework

这两个目录是通过链接的方式加入到内核编译的,流程如下:

kernel\linux\build\kernel.mk:75

$(hide) cd $(KERNEL_SRC_TMP_PATH) && patch -p1 

可以参考3516的HDF补丁:kernel\linux\patches\linux-5.10\hi3516dv300_patch\hdf.patch

patching file drivers/Kconfig
patching file drivers/Makefile
patching file drivers/hdf/Makefile
patching symbolic link drivers/hdf/framework
patching symbolic link drivers/hdf/khdf
patching symbolic link include/hdf

# 添加到linux内核的补丁
drivers/hdf/framework -> /drivers/framework/        # 驱动子系统驱动框架、配置管理、配置解析、驱动通用框架模型、硬件通用平台能力接口等
drivers/hdf/khdf -> /drivers/adapter/khdf/linux/    # 在linux内核中部署OpenHarmony驱动框架
drivers/hdf/Makefile                                # 由hdf.patch提供
include/hdf -> /drivers/framework/include/          # 驱动框架对外提供能力的头文件

内核配置

只是打上补丁还不行,还得在内核的编译配置文件中加入HDF选项。最开始的做法就是参考3516的配置选择,但是发现有些配置会导致编译失败。测试发现下面的配置是可以编译成功的。

[*] Enable HDF manager                      
(2)   Set HDF support platform              
[*]   Enable HDF platform driver            
[*]     Enable HDF platform mipi dsi driver
[*]     Enable HDF platform gpio driver    
[*]     Enable HDF platform i2c driver      
[*]     Enable HDF platform watchdog driver
[*] hi35xx pwm driver                      
[*] Enable HDF platform pwm driver          
[*] Enable HDF platform uart driver        
[ ] Enable HDF platform sdio driver        
[ ] Enable HDF platform emmc driver        
[*] Enable HDF platform mmc driver          
[*] Enable HDF platform spi driver          
[*] Enable HDF platform rtc driver          
[*] Enable HDF linux test                  
[*] Enable HDF Display driver              
[ ]   Enable HDF Lcdkit driver              
[*]   Enable HDF Icn9700 driver            
[ ]   Enable HDF St7789 driver              
[*] Enable HDF input driver                
[*]   Enable HDF tp 5P5 GT911 driver        
[*]   Enable HDF tp 2P35 FT6236 driver      
[ ] Enable HDF wifi                        
[ ] Enable HDF Bluetooth                    
[*] Enable HDF sensor driver                
[ ]   Enable HDF accel sensor driver        
[ ]   Enable HDF gyro sensor driver        
[ ]   Enable HDF barometer sensor driver    
[ ]   Enable HDF hall sensor driver        
[*] Enable HDF storage driver              
[ ] Enable HDF USB PNP Notify driver        
[ ] Enable F_GENERIC driver                
[ ] Enable HDF Audio driver                
[*] Enable HDF vibrator driver              
[*]   Enable HDF linear vibrator driver    
[ ] Enable HDF dsoftbus driver

CONFIG_DRIVERS_HDF=y
CONFIG_HDF_SUPPORT_LEVEL=2
CONFIG_DRIVERS_HDF_PLATFORM=y
CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y
CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y
CONFIG_DRIVERS_HDF_PLATFORM_I2C=y
CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG=y
CONFIG_PWM_HI35XX=y
CONFIG_DRIVERS_HDF_PLATFORM_PWM=y
CONFIG_DRIVERS_HDF_PLATFORM_UART=y
# CONFIG_DRIVERS_HDF_PLATFORM_SDIO is not set
# CONFIG_DRIVERS_HDF_PLATFORM_EMMC is not set
CONFIG_DRIVERS_HDF_PLATFORM_MMC=y
CONFIG_DRIVERS_HDF_PLATFORM_SPI=y
CONFIG_DRIVERS_HDF_PLATFORM_RTC=y
CONFIG_DRIVERS_HDF_TEST=y
CONFIG_DRIVERS_HDF_DISP=y
# CONFIG_DRIVERS_HDF_LCDKIT is not set
CONFIG_DRIVERS_HDF_LCD_ICN9700=y
# CONFIG_DRIVERS_HDF_LCD_ST7789 is not set
CONFIG_DRIVERS_HDF_INPUT=y
CONFIG_DRIVERS_HDF_TP_5P5_GT911=y
CONFIG_DRIVERS_HDF_TP_2P35_FT6236=y
# CONFIG_DRIVERS_HDF_WIFI is not set
# CONFIG_DRIVERS_HDF_BT is not set
CONFIG_DRIVERS_HDF_SENSOR=y
# CONFIG_DRIVERS_HDF_SENSOR_ACCEL is not set
# CONFIG_DRIVERS_HDF_SENSOR_GYRO is not set
# CONFIG_DRIVERS_HDF_SENSOR_BAROMETER is not set
# CONFIG_DRIVERS_HDF_SENSOR_HALL is not set
CONFIG_DRIVERS_HDF_STORAGE=y
# CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY is not set
# CONFIG_DRIVERS_HDF_USB_F_GENERIC is not set
# CONFIG_DRIVERS_HDF_AUDIO is not set
CONFIG_DRIVERS_HDF_VIBRATOR=y
CONFIG_DRIVERS_HDF_VIBRATOR_LINEAR=y
# CONFIG_DRIVERS_HDF_DSOFTBUS is not set
# end of Device Drivers

[*] Enable HDF linux test 是需要设置的,如果没有设置CONFIG_DRIVERS_HDF_TEST,目录结构就出问题了,会报这样的错误。

drivers/hdf/khdf/Makefile:22: PRODUCT_PATH=vendor/raspberrypi/RPI4B
scripts/Makefile.build:44: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile: No such file or directory
make[5]: *** No rule to make target 'drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile'.  Stop.
CC [M]  drivers/net/wireless/mac80211_hwsim.o
make[4]: *** [scripts/Makefile.build:497: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config] Error 2
make[3]: *** [scripts/Makefile.build:497: drivers/hdf/khdf] Error 2
make[2]: *** [scripts/Makefile.build:497: drivers/hdf] Error 2
make[2]: *** Waiting for unfinished jobs....

下面3个选项要关闭,不然会报下面的错误。

[ ] Enable HDF platform sdio driver

[ ] Enable HDF platform emmc driver

[ ] Enable HDF wifi

drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioRescan': sdio_adapter.c:(.text+0x20): undefined reference to `hisi_sdio_rescan'
sdio_adapter.c:(.text+0x34): undefined reference to `himci_get_mmc_host' drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioFindFunc':
sdio_adapter.c:(.text+0xc84): undefined reference to `himci_get_mmc_host' sdio_adapter.c:(.text+0xc9c): undefined reference to `himci_get_mmc_host'
sdio_adapter.c:(.text+0xcb4): undefined reference to `himci_get_mmc_host' drivers/../../../../../../drivers/adapter/khdf/linux/platform/emmc/emmc_adapter.o: In function `Hi35xxLinuxEmmcBind':
emmc_adapter.c:(.text+0x214): undefined reference to `himci_get_mmc_host' drivers/../../../../../../device/hisilicon/drivers/wifi/driver/hi3881/oal/oal_sdio_host.o: In function `sdio_card_detect_change':
oal_sdio_host.c:(.text+0x2ce8): undefined reference to `hisi_sdio_rescan' make[1]: *** [Makefile:1179: vmlinux] Error 1 make[1]: Leaving directory '/home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10' make: *** [kernel.mk:80: /home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10/arch/arm/boot/zImage] Error 2 ninja: build stopped: subcommand failed. 

编译过程

为了方便测试可以单独进行内核编译,比如我的编译命令是这样的。

./build.sh --product-name RPI4B --ccache --build-target raspberrypi_products

可以分析下HDF这部分的编译过程。

linux-5.10\drivers\hdf\Makefile,hdf.patch会添加这个Makefile,将khdf文件夹加入编译。

obj-$(CONFIG_DRIVERS_HDF) += khdf/

linux-5.10\drivers\hdf\khdf\Makefile

export HDF_ROOT := drivers/hdf
obj-$(CONFIG_DRIVERS_HDF)  += osal/
obj-$(CONFIG_DRIVERS_HDF)  += network/
obj-$(CONFIG_DRIVERS_HDF)  += config/

SUPPORT_LEVEL_STD_H := $(shell [ "$(CONFIG_HDF_SUPPORT_LEVEL)" -ge 2 ] && echo true)

$(warning PRODUCT_PATH=$(PRODUCT_PATH))     # 会检查PRODUCT_PATH变量
ifeq ($(PRODUCT_PATH),)
$(error PRODUCT_PATH not)
endif

# 这里有条注释指明了*.hcs配置文件的存放路径
# for L2+, hcs config should in vendor/product_company/product_name/config/khdf
ifeq ($(SUPPORT_LEVEL_STD_H), true)
SUB_DIR:=khdf/
endif

# HDF test的配置会使hcs目录结构不一样,我当时没有设置CONFIG_DRIVERS_HDF_TEST就掉这个坑里了。
ifeq ($(CONFIG_DRIVERS_HDF), y)
ifeq ($(CONFIG_DRIVERS_HDF_TEST), y)
obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR)/hdf_test/
obj-$(CONFIG_DRIVERS_HDF) += test/
else
obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR)
endif
endif
# ... 后面按照配置添加一些编译目录 ...

drivers\adapter\khdf\linux\Makefile:会调用 obj-(CONFIG_DRIVERS_HDF) += ../../../../(CONFIGDRIVERSHDF)+=../../../../(PRODUCT_PATH)/hdf_config/$(SUB_DIR)/hdf_test/ 这是OHOS3.0默认的HCS文件存放路径。官方的注释也说明了,所以将设备对应的*.hcs存放到 vendor\raspberrypi\RPI4B\hdf_config\khdf 文件夹,参考 3516 的 vendor\hisilicon\Hi3516DV300\hdf_config\khdf\hdf.hcs 就可了。

#include "device_info/device_info.hcs"
#include "platform/i2c_config.hcs"
#include "platform/hi35xx_watchdog_config.hcs"
#include "platform/hi35xx_pwm_config.hcs"
#include "platform/hi35xx_uart_config.hcs"
#include "platform/sdio_config.hcs"
#include "platform/emmc_config.hcs"
#include "platform/hi35xx_spi_config.hcs"
#include "input/input_config.hcs"
#include "wifi/wlan_platform.hcs"
#include "wifi/wlan_chip_hi3881.hcs"
#include "sensor/sensor_config.hcs"
#include "audio/audio_config.hcs"
#include "audio/codec_config.hcs"
#include "audio/dai_config.hcs"
#include "audio/dma_config.hcs"
#include "audio/dsp_config.hcs"
#include "vibrator/vibrator_config.hcs"
#include "vibrator/linear_vibrator_config.hcs"
#include "lcd/lcd_config.hcs"

root {
  module = "hisilicon,hi35xx_chip";
}

参考 3516 的 vendor\hisilicon\Hi3516DV300\hdf_config\khdf\Makefile

其中:PRODUCT_PATH环境变量的来源:kernel/linux/build/kernel_module_build.sh:42:export PRODUCT_PATH=$4

ifeq ($(LOCAL_HCS_ROOT),)
LOCAL_HCS_ROOT := $(PRODUCT_PATH)
endif

SOURCE_ROOT:=$(abspath ../../../../../)

HC_GEN_DIR := $(abspath $(SOURCE_ROOT)/drivers/framework/tools/hc-gen)
HC_GEN := $(HC_GEN_DIR)/build/hc-gen
LOCAL_HCS_ROOT := $(abspath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))

HCS_DIR := $(LOCAL_HCS_ROOT)

ifneq ($(TARGET_BOARD_PLATFORM),)
HCS_DIR := $(LOCAL_HCS_ROOT)/$(TARGET_BOARD_PLATFORM)
else
ifneq ($(CONFIG_ARCH_HI3516DV300),)
  HCS_DIR := $(LOCAL_HCS_ROOT)
endif
ifneq ($(CONFIG_ARCH_HI3518EV300),)
  HCS_DIR := $(LOCAL_HCS_ROOT)
endif
endif
$(info HCS_DIR = $(HCS_DIR))
HCB_FLAGS := -b -i -a

HCS_OBJ := hdf_hcs_hex.o
HCS_OBJ_SRC := $(subst .o,.c,$(notdir $(HCS_OBJ)))

CONFIG_GEN_HEX_SRC := $(addprefix $(LOCAL_HCS_ROOT)/, $(HCS_OBJ_SRC))
CONFIG_HCS_SRC := $(subst _hcs_hex.o,.hcs,$(addprefix $(HCS_DIR)/, $(HCS_OBJ)))

$(obj)/$(HCS_OBJ): $(CONFIG_GEN_HEX_SRC)
  $(Q)$(CC) $(c_flags) -c -o $@ $echo gen hdf built-in config
  $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi
  $(Q)$(HC_GEN) $(HCB_FLAGS) -o $(subst _hex.c,,$(@)) $echo gen hdf driver config
  $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi
  $(Q)$(HC_GEN) -t -o $@ $

查看结果

编译完成后,可以上传内核镜像到开发板,来查看HDF驱动框架是否启动成功。

加入HDF前:

# ls dev/
__parameters__  hwrng         tty1   tty28  tty46  tty7
__trigger__     input         tty10  tty29  tty47  tty8
autofs          kmsg          tty11  tty3   tty48  tty9
binder          linux,cma     tty12  tty30  tty49  ttyAMA0
block           loop-control  tty13  tty31  tty5   ttyS0
bus             mem           tty14  tty32  tty50  ttyprintk
cachefiles      memcg         tty15  tty33  tty51  unix
char            null          tty16  tty34  tty52  urandom
console         port          tty17  tty35  tty53  vchiq
cpuctl          ptmx          tty18  tty36  tty54  vcs
cpuset          pts           tty19  tty37  tty55  vcs1
dri             random        tty2   tty38  tty56  vcsa
fd              rawctl        tty20  tty39  tty57  vcsa1
freezer         snd           tty21  tty4   tty58  vcsu
fscklogs        stderr        tty22  tty40  tty59  vcsu1
full            stdin         tty23  tty41  tty6   vga_arbiter
gpiochip0       stdout        tty24  tty42  tty60  vndbinder
gpiochip1       system        tty25  tty43  tty61  watchdog
graphics        tty           tty26  tty44  tty62  watchdog0
hwbinder        tty0          tty27  tty45  tty63  zero

加入HDF后:

# ls dev/
HDF_PLATFORM_I2C_MANAGER  loop-control    tty24  tty54
HDF_PLATFORM_UART_1       mem             tty25  tty55
HDF_TEST                  memcg           tty26  tty56
I2C_TEST                  null            tty27  tty57
__parameters__            port            tty28  tty58
__trigger__               ptmx            tty29  tty59
autofs                    pts             tty3   tty6
binder                    random          tty30  tty60
block                     rawctl          tty31  tty61
bus                       sample_service  tty32  tty62
cachefiles                snd             tty33  tty63
char                      stderr          tty34  tty7
console                   stdin           tty35  tty8
cpuctl                    stdout          tty36  tty9
cpuset                    system          tty37  ttyAMA0
dev_mgr                   tty             tty38  ttyS0
dri                       tty0            tty39  ttyprintk
fd                        tty1            tty4   unix
freezer                   tty10           tty40  urandom
fscklogs                  tty11           tty41  vchiq
full                      tty12           tty42  vcs
gpiochip0                 tty13           tty43  vcs1
gpiochip1                 tty14           tty44  vcsa
graphics                  tty15           tty45  vcsa1
hdf_bl                    tty16           tty46  vcsu
hdf_input_host            tty17           tty47  vcsu1
hdf_misc_vibrator         tty18           tty48  vga_arbiter
hdf_sensor_manager_ap     tty19           tty49  vndbinder
hwbinder                  tty2            tty5   watchdog
hwrng                     tty20           tty50  watchdog0
input                     tty21           tty51  zero
kmsg                      tty22           tty52
linux,cma                 tty23           tty53

基本算是启动成功了,接下来考虑打算用HDF的方式添加一下设备。来验证HDF驱动框架是否运转正常。

原创文章,作者:晴川运维,如若转载,请注明出处:https://baike.qcidc.com/4371.html

(0)
晴川运维晴川运维
上一篇 2025年6月8日
下一篇 2025年6月8日

相关推荐

  • Linux fg命令:把后台命令恢复在前台执行

    前面所讲,都是将工作丢到后台去运行,那么,有没有可以将后台工作拿到前台来执行的办法呢?答案是肯定的,使用  fg 命令即可。 fg 命令用于把后台工作恢复到前台执行,该命…

    Linux系统 2025年6月8日
  • Fedora 25 Workstation安装指南

    Fedora 25 Workstation是一款优秀的linux发行版本,由Red Hat倾情赞助,为我们带来了许多新功能和更新,理所当然,Fedora 25成为一个相当重要的版本…

    Linux系统 2025年6月8日
  • Linux中配置HAProxy实现Web负载均衡

    HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。 一、测试环境 HAPr…

    Linux系统 2025年6月19日
  • 浅谈Base64编码原理

    Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于 2的6次方是64,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64…

    Linux系统 2025年6月17日
  • Linux常用命令mzip命令具体使用方法

    Linux mzip命令是Zip/Jaz磁盘驱动器控制指令。 mzip为mtools工具指令,可设置Zip或Jaz磁盘驱动区的保护模式以及执行退出磁盘的动作。 语法 mzip&nb…

    Linux系统 2025年6月8日
  • Linux Mint 安装 Linux Kernel 4.12

    Linus Torvalds 发布了 Linux 内核 4.12。你可以从这里直接下载相关的 deb 包来安装。或者,继续阅读本文,按下面的步骤安装新内核。 警告:Linux 内核…

    Linux系统 2025年6月17日
  • Linux中进程通信方法

    每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进…

    Linux系统 2025年6月11日
  • Linux绝对路径和相对路径详解

    在 linux 中,简单的理解一个文件的路径,指的就是该文件存放的位置,例如,在《Linux文件系统的层次结构》中提到的 /home/cat 就表示的是 cat 文件所存放的位置。…

    Linux系统 2025年7月11日
  • Linux中常用的监控工具

    本篇文章重点为大家讲解一下Linux中常用的监控工具,有需要的小伙伴可以参考一下。 1. iotop 如果你想知道某些进程使用了多少你宝贵的 I/O 资源,那么就使用 iotop …

    Linux系统 2025年6月11日
  • Vim常用的三种模式

    Vim是从vi发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。和Emacs并列成为类Unix系统用户最喜欢的编辑器。 安装VIM …

    Linux系统 2025年6月8日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注