【问题标题】:What is the meaning of "driver core" in the context of Linux kernel device drivers?Linux内核设备驱动程序上下文中的“驱动程序核心”是什么意思?
【发布时间】:2018-06-15 14:48:30
【问题描述】:
我正在阅读 Linux 设备驱动程序,第三版一书,在第 14 章的“将它放在一起”部分中,他们提到了“PCI 核心、驱动程序核心和各个 PCI 驱动程序”之间的交互。他们多次使用“驱动核心”这个词。是个
“驱动核心”不同于“字符设备驱动”?
我的问题源于理解 InfiniBand 堆栈的意图。 IB 堆栈跨越用户空间和内核空间。因此,如果我正在编写一个简单的乒乓 InfiniBand 程序以在 Mellanox ConnectX-4 NIC 上运行,我的二进制文件将依赖于 2 个用户空间库:libibverbs 和 libmlx5,以及 3 个内核模块:ib_uverbs、mlx5_ib 和 mlx5_core。我知道 ib_uverbs 是一个字符设备驱动程序。但是我们可以将 mlx5_ib 和 mlx5_core 内核模块视为某种类型的驱动程序吗?还是它们的功能只是全局导出以便与它们交互?
【问题讨论】:
标签:
linux-device-driver
infiniband
【解决方案1】:
驱动程序核心是管理驱动程序、设备、总线、类等的通用代码。它不依赖于特定的总线或设备。我相信你所参考的章节提供了几个例子来说明PCI总线驱动和驱动核心之间的分工,例如,见图14-3(设备创建过程)。
在您提到的三个内核模块中,两个参与设备核心:ib_uverbs 注册其字符设备以将 RDMA 功能导出到用户空间; mlx5_core 注册一个 PCI 驱动程序来处理 ConnectX NIC; mlx5_ib 也可以视为驱动程序,但 RDMA 子系统不使用设备内核来注册驱动程序(它有自己的 API - ib_register_device)。
【解决方案2】:
什么是驱动核心??
在 Linux 源代码中观察以下调用流程。
tps65086_regulator_probe---> devm_regulator_register-->ulator_register-->device_register(/drivers/regulator/tps65086-regulator.c--->/drivers/regulator/core.c--->drivers/base/core.c)。
tps65086 驱动程序调用稳压器内核,稳压器内核又调用驱动程序内核。
该驱动程序遵循标准驱动程序模型。
include/linux/device.h ----> 驱动模型对象在这里定义。
drivers/base/ --> 对驱动模型对象进行操作的所有函数都在这里定义。
我们可以将其称为驱动程序核心,是任何驱动程序框架工作的基础。
所有的注册都来自更高层。
任何驱动子系统..weather PCI/USB/Platform都是基于此。
drivers/base/core.c -- 标准驱动模型的核心文件。
命名略有混淆 - 但是我们可以将 drivers/base/ 称为驱动程序核心。
字符驱动程序与其他驱动程序有什么区别??
/drivers/char/tlclk.c
tlclk_init-->register_chrdev -->register_chrdev --> cdev_add --> kobj_map (fs/char_dev.c ---> /drivers/base/map.c )。
字符设备注册是使用 char_dev 完成的,它是一个文件系统驱动程序,它再次使用驱动程序模型库的基础设施。
whare 作为 tps65086-regulator.c 等非字符驱动程序,可以注册到驱动程序核心,如下所示。
tps65086_regulator_probe---> devm_regulator_register-->ulator_register-->device_register-->device_add-->kobject_add
(/drivers/regulator/tps65086-regulator.c--->/drivers/regulator/core.c--->drivers/base/core.c)
此外,它不仅取决于驱动程序的类型,还取决于它是什么类型的设备以及需要如何处理设备。
这是一个注册字符设备的 pci 驱动程序。
tw_probe-->register_chrdev --> cdev_add --> kobj_map ( /drivers/scsi/3w-xxxx.c -->fs/char_dev.c ---> /drivers/base/map.c )
驱动程序是否应该调用驱动程序核心没有标准规则。
任何堆栈/框架都可以有自己的核心来管理设备,驱动程序 mlx5_ib (drivers/infiniband/core/) 就是这种情况。
但最后,它大多会使用 Kobject 基础设施和驱动模型对象,如 struct device。
引入驱动模型基础设施以消除冗余内核代码和数据结构。
所以大部分驱动都是以此为基础的,这是编写linux驱动的有效途径。