HDF用户态和内核态之间是怎样调用的? 原创 精华

liangkz_梁开祝
发布于 2022-2-17 21:11
浏览
2收藏

有兄弟在gitee的OpenHarmony/drivers_framework仓库提issue,见“HDF用户态和内核态之间是怎样调用的?

我看到了就做了简单回答如下,对鸿蒙驱动开发感兴趣或者有疑问的朋友,建议去gitee看原问答和其它相关issue的问答。

在标准系统中,HDF分用户态和内核态两部分,如何快速确定某个源文件是工作在用户态还是内核态?
可以搜索文件名,使用BUILD.gn构建成so的,是工作在用户态,使用Makefile构建的,是在内核态。

注意有部分文件是用户态和内核态共用的。

用户态驱动是以so库的形式存在吗?由哪个程序去负责加载这些so库,并将其注册到系统中?

drivers\adapter\uhdf2\host\src\driver_loader_full.c 的 HdfDriverLoaderGetDriverEntry()函数中,会通过两个strcat_s操作,拼接出用户态驱动so库的部署路径和库名,如:/system/lib/libsample_driver.z.so,通过realpath/dlopen/dlsym 来获取用户态驱动的入口 HdfDriverEntry,接下来就按流程执行其中的Bind/Init函数。

这个开发模型是否有详细的文档、框图等资料提供?

我已经完成了几乎整个HDF的详细分析,画出了详细的流程图和各模块之间的关系图,请关注即将出版的南向开发书籍《鸿蒙系统学习笔记》。

用户态驱动是如何注册到系统中的?

通过部署在用户态的hcs文件描述驱动配置信息,见//vendor/hisilicon/Hi3516DV300/hdf_config/uhdf/*.hcs
因为用户态驱动都是以动态库方式部署的,并且只对用户态提供服务,所以它的policy都是2,moduleName就是对应的动态库的全名。
编译和分析hcs/hcb文件,仍是hc-gen/hcs-parser。
解析hcb文件的过程和结果,见//drivers/adapter/uhdf2/manager/src/hdf_get_attribute.c内相关函数。

用户态驱动的so库如何告诉加载器自己是一个用户态驱动呢?

在//vendor/hisilicon/Hi3516DV300/hdf_config/uhdf/*.hcs里配置的驱动,都是用户态驱动,

一个用户态驱动是否能且仅能对外暴露一个driverDesc?

目前看起来是这样的,我有九成把握给肯定答案,但最好是官方确认一下。

用户态驱动的so库代码是运行在哪个进程上下文中?
所有用户态驱动的so库是运行在同一个进程上下文中吗?

hdf_devmgr进程是用户态设备驱动管理者进程,它不直接运行用户态驱动so库,它为每一个host fork一个子进程,每个子进程独立运行对应的host的so库,如sample_host进程运行libsample_driver.z.so

设备对象是由谁提供的?

每个设备驱动在执行自己的Bind/Init相关流程中,会生成DeviceServiceStub对象,里面会包含对应的HdfDeviceObject ,见HdfDriverLoaderLoadNode()内的操作。

调用逻辑大概如下。。。。但是这个逻辑是怎么开始的?后面又是如何通知到内核进行块设备注册的?

调用过程,有若干次hdf_devmgr进程和具体host进程之间的跨进程交互,你的逻辑还不完全准确。
我的书籍里给出了完整的交互过程和流程图,敬请关注。
用户态驱动不需要到内核进行注册,它对应用提供HDI接口,再通过系统调用进入内核态,使用内核态驱动提供的服务。

一个应用调用gralloc函数的流程。。。。。

display驱动模型我没有深入分析,但我深入分析了wlan驱动模型,相关流程估计可做参考,也请关注《鸿蒙系统学习笔记》这本书.

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
9
收藏 2
回复
举报
7条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢,文章解决了很多疑惑

1
回复
2022-2-18 10:29:24
mb628371fac4155
mb628371fac4155

你好,这些问题还是没有解答用户态怎么调用内核态的。

uhdf是用户态的驱动,和内核无关。

khdf是内核态的驱动,请问,内核态的设备管理服务是怎么向外提供服务的、内核态驱动是怎么注册、启动的?用户态怎么调用内核驱动的接口

1
回复
2022-5-17 18:01:07
liangkz_梁开祝
liangkz_梁开祝 回复了 mb628371fac4155
你好,这些问题还是没有解答用户态怎么调用内核态的。 uhdf是用户态的驱动,和内核无关。 khdf是内核态的驱动,请问,内核态的设备管理服务是怎么向外提供服务的、内核态驱动是怎么注册、启动的?用户态怎么调用内核驱动的接口

你这几个问题比较大,三言两语还真说不清楚,不过在我的书里都有了非常详细的说明,并且有对应的数据结构关系图,到时候你对着图一看就明白了。这本书很快就可以和大家见面了。

1
回复
2022-5-17 18:24:38
mb628371fac4155
mb628371fac4155 回复了 liangkz_梁开祝
你这几个问题比较大,三言两语还真说不清楚,不过在我的书里都有了非常详细的说明,并且有对应的数据结构关系图,到时候你对着图一看就明白了。这本书很快就可以和大家见面了。

不用很详细,提供一些关键的函数也可以,我至少可以自己跟代码。

 

我大概理了一下,khdf的devmgr通过late_initcall初始化,初始化过程会通过注册设备块向用户态开放一些能力(包括devmgr和dev_svc_mgr的能力)。

我有两个疑惑:

 

1. 但是hkdf里面的驱动,我看也是调的HDF_INIT来初始化的,这个不是用户态用的么,它的功能是把驱动entry地址写到.hdf.driver段,用户态devmgr启动的时候就会初始化并注册这个驱动。难道内核的驱动也是通过用户态的devgmr注册?

 

2. 用户态进程我只知道可以通过上面说的devmgr设备块和内核交互。但是开放的接口好像没有看到获取内核驱动服务的。我想知道内核驱动服务是自己注册新的设备块来向用户态开放,还是通过内核的devmgr或者dev_svc_mgr

回复
2022-5-18 09:42:04
liangkz_梁开祝
liangkz_梁开祝 回复了 mb628371fac4155
不用很详细,提供一些关键的函数也可以,我至少可以自己跟代码。 我大概理了一下,khdf的devmgr通过late_initcall初始化,初始化过程会通过注册设备块向用户态开放一些能力(包括devmgr和dev_svc_mgr的能力)。 我有两个疑惑: 1. 但是hkdf里面的驱动,我看也是调的HDF_INIT来初始化的,这个不是用户态用的么,它的功能是把驱动entry地址写到.hdf.driver段,用户态devmgr启动的时候就会初始化并注册这个驱动。难道...

1. “hkdf里面的驱动,我看也是调的HDF_INIT来初始化的,这个不是用户态用的么”

//drivers/adapter/khdf/目录下,全部是编译到内核中的驱动,

//drivers/adapter/uhdf/目录下,是小型系统的用户态驱动框架

//drivers/adapter/uhdf2/目录下,是标准系统的用户态驱动框架

 

内核态的各驱动,HDF_INIT->HDF_DRIVER_INIT->//drivers/framework/core/common/include/host/hdf_device_section.h

是会编译到内核的.hdf.driver段,然后大概如你所理解的方式启动。

 

用户态的各驱动,HDF_INIT->HDF_DRIVER_INIT->//drivers/adapter/uhdf2/include/host/hdf_device_section.h

会在用户空间以另外一种截然不同的方式启动。

 

不管是内核态驱动,还是用户态驱动,DeviceManager 和 DeviceServiceManager 都会以非常重要的、但又不同的形式出现并起关键作用。这中间涉及到了内核态驱动和用户态驱动的代码共用、函数指针分别指向不同的函数、各自结构体(类)的重新定义等等非常容易引起混淆的东西,所以驱动框架的架构还是挺难以让人理解的。

 

2. 用户态进程我只知道可以通过上面说的devmgr设备块和内核交互。

用户态与内核态的交互,简单来说就是消息机制,更进一步就是系统调用,就是linux的open/ioctl这一套。

具体入口可以认为只有两个:

struct HdfIoService *serv = HdfIoServiceBind(SERVICE_NAME);

serv->dispatcher->Dispatch(struct HdfObject *service, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply);

你可参考《RK3568三色灯点灯流程》中给的示例程序:led_rgb 的调用流程跑一下看看。

如果涉及到用户态进程与用户态进程之间的IPC,那就是另外的故事了。

回复
2022-5-18 11:16:33
mb628371fac4155
mb628371fac4155 回复了 liangkz_梁开祝
1. “hkdf里面的驱动,我看也是调的HDF_INIT来初始化的,这个不是用户态用的么” //drivers/adapter/khdf/目录下,全部是编译到内核中的驱动, //drivers/adapter/uhdf/目录下,是小型系统的用户态驱动框架 //drivers/adapter/uhdf2/目录下,是标准系统的用户态驱动框架 内核态的各驱动,HDF_INIT->HDF_DRIVER_INIT->//drivers/framework/core/common/include/host/hdf_device_section.h 是会编译到内核的.hdf.driver...

感谢感谢,我大致明白了!

回复
2022-5-18 11:30:48
Open鸿码
Open鸿码 回复了 mb628371fac4155
你好,这些问题还是没有解答用户态怎么调用内核态的。 uhdf是用户态的驱动,和内核无关。 khdf是内核态的驱动,请问,内核态的设备管理服务是怎么向外提供服务的、内核态驱动是怎么注册、启动的?用户态怎么调用内核驱动的接口

这个在 代码目录下, ls -la 就会发现,代码是 软链接到 kernel目录下,编译到内核中,

至于对外的使用,跟 其他的 device设备没有本质区别, 还是 文件节点。

不过,我也没太看明白,他搞一个什么 section 段的,就是为存放 鸿蒙搞的一堆hdf 变量,

不知道是 为了解决什么问题

回复
2022-6-28 20:52:04
回复
    相关推荐