LWN: 利用auxiliary bus管理具有多种功能的硬件设备!

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

关注了就能看到更多这么棒的文章哦~

Managing multifunction devices with the auxiliary bus

December 17, 2020

This article was contributed by Marta Rybczyńska
DeepL assisted translation
https://lwn.net/Articles/840416/

设备驱动程序通常都是属于某一个内核子系统中的,一般不会属于两个子系统。然而,有时开发人员需要处理意外情况。例如,我们有一个网络接口卡(NIC),它就同时具有以太网和 RDMA 功能。这里只有一个硬件,但是会有两个驱动程序来实现两个不同功能。这些驱动程序需要在各自的子系统中工作,但它们也必须共享对同一硬件的访问。目前的内核中没有标准的方法来将这些驱动程序合并起来,所以开发者发明了一些临时的方法来处理它们之间的交互。最近,Dave Ertman 发布了一组 patch set,介绍了一种新的总线类型,称为 "auxiliary bus",希望解决这个问题。

Complex devices

Linux 已经包含了许多驱动程序用来支持同时具有多种功能的设备(multi-function device)。支持方法之一就是 Multi-Function Devices(MFD)子系统。它将多个独立的设备 "粘合" 在一起,成为一个硬件模块,大家共享一些资源。MFD 允许直接访问设备的寄存器,也允许使用一个普通总线(common bus)。在使用 common bus 的情况下,它可以让我们很方便地在 Inter-Integrated Circuit(I2C)或 Serial Peripheral Interface(SPI)总线上安全地管理多路访问。由于 MFD 子设备都是互相独立的,所以 MFD 驱动程序不会共享公共状态。

Ertman 想支持的这些设备都不能简单使用 MFD 方式。使用 auxiliary bus 的设备会把某个硬件设备的一部分功能提供出来。因为不是针对每种功能都暴露完全不同的一批寄存器,因此它们不能使用 devicetrees 描述,也不能通过 ACPI 来进行识别。它们的驱动程序需要共享访问硬件。那些跟所有子功能(如电源管理)都有关的 event 需要各个驱动程序都能正确处理。这些设备通常是运行 firmware 的一些专用处理器,并且通过消息传递方式来与 host 系统(以及 Linux 驱动程序)进行通信。具体有哪些功能可用,事先都可能并不知道,因此必须在运行起来后进行识别(discovery)。

auxiliary bus 这组 patch 中的文档里面介绍了一些例子。比如 Sound Open Firmware (SOF)驱动程序 所管理的这个硬件设备中可能会提供 HDMI 输出、麦克风、扬声器、测试和调试 hook 等接口。还有同时实现了 Ethernet 和 RDMA 的网卡(NIC)会首先需要一个能支持公共部分功能的驱动程序,然后针对特定的以太网和 RDMA 功能的驱动程序就在此基础上来实现相应的功能。

目前的内核中没有一种通用的方法来描述这种设备的多个驱动程序之间的依赖关系。解决这个问题的方法可以是通过某种方式来将辅助驱动(secondary driver)附加(attach)到主驱动上,这正是 auxiliary bus 所实现的。

Auxiliary devices and drivers

patch set 中引入了两个主要概念:"auxiliary device"和 "auxiliary driver"。它们分别对应了主驱动(main driver)和辅助驱动(secondary driver)。主驱动维护设备的状态,分配和管理所有的共享数据。在关闭设备时,它还会 unregister 所有的辅助驱动。辅助驱动程序则用来处理与它们所针对的特定子系统的交互。

每个主驱动可以为辅助驱动暴露一些功能(devices)。每个功能只能属于一个辅助驱动程序。

主驱动会创建辅助设备,这是由 struct auxiliary_device 表示的:

struct auxiliary_device {
    struct device dev;
    const char *name;
    u32 id;
};

name 和 id 的组合必须是唯一的,设备的完整名称是 module name 和这两个字段的组合,用点(.)来连接。这样就会得到一个类似 modname.device_name.id 的名字。

开发者将这个结构填入到主驱动的 device structure 中,还需要指明主驱动和辅助驱动之间的通信所需的所有共享数据。还可以加一些 callback 函数。

初始化主驱动的流程包含两个步骤。第一步是调用 auxiliary_device_init():

int auxiliary_device_init(struct auxiliary_device *auxdev);

这个函数会验证参数,必要时返回一个错误代码,在这种情况下,设备的初始化就应该被中止。如果这个调用成功了,第二步就是对初始化后的设备来调用 macro auxiliary_device_add(),这就是在设置设备名称并注册设备本身。

unregistration 的过程也有两步,包括对 auxiliary_device_uninit()的调用(auxiliary_device_init()成功的话就需要)和 auxiliary_device_delete()。这些函数的原型如下:

void auxiliary_device_uninit(struct auxiliary_device *auxdev);
void auxiliary_device_delete(struct auxiliary_device *auxdev);

这个两步操作是根据早期版本 patch set 所收到的 review 意见而实现的。因为这样做就允许驱动程序在 auxiliary_device_init()和 auxiliary_device_add()之间对自己的数据进行 allocation,也可以在失败的情况下正确 free 数据。

辅助设备将连接到主驱动,由 struct auxiliary_driver 表示:

struct auxiliary_driver {
    int (*probe)(struct auxiliary_device *auxdev,
     const struct auxiliary_device_id *id);
    int (*remove)(struct auxiliary_device *auxdev);
    void (*shutdown)(struct auxiliary_device *auxdev);
    int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
    int (*resume)(struct auxiliary_device *auxdev);
    const char *name;
    struct device_driver driver;
    const struct auxiliary_device_id *id_table;
};

这个结构里包含一些回调函数来管理此设备的生命周期,而 id_table 则包含了此 driver 能 bind 的所有 device 的名称。所有的回调函数收到的都是指向父设备的 auxiliary_device 的指针,这样就可以访问共享数据了。

辅助设备是通过 auxiliary_driver_register()来设置的:

int auxiliary_driver_register(struct auxiliary_driver *auxdrv);

这个函数会要求 probe() callback 和 id_table 这两项都设置好了。当调用成功时,它会调用所有匹配的设备的 probe() callback。辅助设备可以使用 container_of()和 auxiliary_device 结构来访问公共数据。

当 unregister 一个驱动程序时,开发者应该调用 auxiliary_driver_unregister():

void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)。

First users

在实现 auxiliary bus 的同时,Ertman 发布了对 SOF 驱动的改动。修改后的驱动利用 auxiliary bus 实现了一个测试用的驱动和一个 probe 驱动,允许创建一个新的虚拟音频设备并接入 pipeline,允许在任意节点来进行监听。

另一个使用场景是在网络子系统中;Leon Romanovsky 发布了 mlx5 驱动程序改为使用 auxiliary bus 的版本。更新后的驱动程序为单个物理设备创建了网络、VDPA 以及 RDMA 的驱动程序。进行这些改动之后可以删除掉特定驱动里的许多代码。Parav Pandit 后续还使用这个功能来实现了 device sub-function。

这组 patch-set 已经到了第四个版本,此前更早的版本里面名字还是 ancillary bus 或者 virtual bus。auxiliary bus 这组 patch set 的开发花费了不少时间,而且也开始有其他一些工作在依赖它的了。这给推进 upstream 的流程造成了相当大的压力,这也导致了列表上的一些催促。为了能推动它,Dan Williams 重新发布了这组 patch,并表示 "在我和其他几个利益相关者看来,它很不错"。经过 Greg Kroah-Hartman 的 review 后,auxiliary bus 的代码被合并到了 5.11 内核版本的 mainline 中。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

Managing multifunction devices with the auxiliary bus Linux内核引入辅助总线机制解决多功能设备驱动协同问题 针对Linux内核中多功能硬件设备驱动协同管理的问题,Dave Ertman提出了"辅助总线"(auxiliary bus)解决方案,并已被合并到5.11内核。该机制通过主驱动管理设备状态和共享资源,次级驱动处理特定功能的方式,解决了当前内核缺乏标准方法协调驱动间交互的痛点。辅助总线采用两级架构:主驱动创建并注册auxiliary_device结构,维护共享数据;次级驱动通过auxiliary_driver结构实现特定功能,通过标 阅读详情

相关推荐

SRT协议包头结构

这是SRT可靠传输的基石,用于唯一标识数据包,供接收方检测丢包、乱序,并用于ACK/NAK报告。Message Number(消息编号,位47-78):唯一标识一个应用层消息。在“消息模式”下,所有属于同一消息的数据包共享相同的Message Number,即使它们被分割成多个SRT包。Packet Position Flag(包位置标志,位32-33):两位,表示此包在应用层消息中的位置。00=唯一包或中间包,01=消息的第一包,10=消息的最后一包,11=消息的唯一包(既是第一也是最后)。

weixin_44651073的博客 42

Auxiliary Bus

Auxiliary 总线 在某些子系统中,核心设备(PCI/ACPI/其他)的功能对于单个设备来说过于复杂,无法由单个某驱动程序(例如 Sound Open Firmware)管理,多个设备可能会实现共同的功能交集(例如 NIC+ RDMA),或者驱动程序可能想导出一个接口供另一个子系统驱动(例如 SIOV Physical Function export Virtual Function management)。将功能拆分为代表sub-domains功能的child- devices,可以通过 Lin.

六六哥的博客 1616

通过 auxiliary bus 管理 multifunction 设备

引言 设备驱动通常存在于单个内核子系统中。然而,有时开发人员需要处理此模块之外的功能。例如,一个暴露以太网和 RDMA 功能网络接口卡 (NIC)。只有一个硬件,但有两个驱动用于这两个功能。这些驱动程序需要在各自的子系统内工作,但它们也必须共享对相同硬件的访问方法。当前内核中没有将这些驱动程序连接在一起的标准方法,因此开发人员发明了ad-hoc方法来处理它们之间的交互。最近,Dave Ertman 发布了一个补丁集,介绍了一种称为“auxiliary bus”的新型总线,以解决这个问题。 Comple

六六哥的博客 1453

Linux软件安装

一、Linux系统有两种软件包: 1、源码包 源码包软件都是开源的,有足够能力可以修改软件系统源代码,可以自由选择所需要功能,软件需要编译安装,编译过程时间较长,比二进制包安装耗时较长。 2、二进制包 二进制包分为DPKG包和RPM包。 前者主要用在Debina和Ubuntu等系统中,后者用在Red Hat ,CentOS等系统中。 下面主要说下RPM包。 RPM包管理系统简单,由于是编译过的,不再可以看到源代码。功能选择不由源码包灵活。 二、软件安装 1、源码包软件安装 三步骤:预编译,编译,安装。 编译

阿蔡的博客 179

关于driver_register函数干了什么

现在进入driver_register()函数去看看。在driver_register() 中,调用了driver_find(drv->name, drv->bus)函数,这里是干啥呢?这里是先去驱动打算挂牌的地方先查找一下,这个驱动是否已经挂牌(注册)过了。在哪里查找呢?代码中写得很清楚,去bus->p->drivers_kset中查找,看到这里,我决定这里不要再继续展开细细的分析,否则永远都无

望都者 1715

最新历史版本 :LINUX KERNEL 配置编译中文指南

LINUX KERNEL 配置编译中文指南 序言   近几年,linux大行其道,令不满windows蓝屏的使用者跃跃欲试,结果发现linux安装不及windows方便,界面不及windows友好,配置不及windows容易,软件不及windows丰富,以至浅尝辄止。   其实, Linux有windows无可比拟的两个优势:网络应用和嵌入式技术,这也正是未来最有前途的方向。同时此课题是从理

2772

dpdk 程序适配麦洛斯 mlx5 网卡

使用 dpdk-16.04 版本的数通引擎需要适配 Mellanox 网卡,需要支持 dpdk secondary 进程正常收发包。

龙瑜的博客 7755

linux 内核module_platform_driver解析

该函数实际是一个宏,module_platform_driver在include/linux/platform_device.h中定义如下: /* module_platform_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of * boilerplate. Each module may only use this...

longyuelang的专栏 700

Linux内核配置和编译

一、引言:  本文档的内容大部份内容都是从网上收集而来,然后配合一些新的截 图(内核版本:V2.4.19)。在每一配置项后会有一个选择指南的部份,用来指导大家怎么样 根据自己的情况来做相应的选择;还有在每一个大项和文档的最后会有一个经验谈,它是一些高手们在应对问题和处理特有硬件时的一些经验(这个还得靠各位)。 文档最后会发到网上,到时会根据网友们的回复随时进行更新。  我们的目的是让我们有一个

tangtang_yue的博客 1621

make找不到linux内核函数,Linux编译内核遇到找不到linux/limits.h的问题

这几天在编译新内核,在make menuconfig 的时候老是报下面这个错误:HOSTCCscripts/basic/fixdepIn file included from /usr/include/x86_64-linux-gnu/bits/posix1_lim.h:160:0,from /usr/include/limits.h:143,from /usr/lib/gcc/x86_64-...

weixin_42513928的博客 1612

Linux--Linux内核总线(bus)的意义及其作用

@TOC 1、Linux内核中的总线作用 在Linux内核中,总线属于核心层,是纯软件的东西。在Linux内核中总线左手牵着驱动右手牵着设备,总线的工作就是就是完成总线下的设备和驱动之间的匹配。也就是在左手中找到与右手相匹配的设备驱动,并完成他们之间的匹配。 2、Linux内核中总线的表现形式 Linux系统内核使用bus_type结构体表示总线,此结构体定义在文件include/linux/device.h,具体内容如下: struct bus_type { const char *name; c

一只青木呀 2800

QSFP/QSFP-DD/OSFP 通用管理接口规范(CMIS)解读:11 Page 13h II

本文主要关注光模块CMIS协议文档的 8.11 节关于 Page 13h 的内容。不仅是对文档的简单翻译,还会剖析协议规定背后的深层含义。为了方便与协议文档内容对应,本文的章节编号与协议文档保持一致。

a653952216的博客 271

Natapp 内网穿透完整实操:从注册到远程桌面公网访问全流程

内网穿透并不缺方案。自己搭建 FRP 的自由度很高,但要先有一台带公网 IP 的服务器,再部署服务端、配置客户端、开放端口,后续还要处理升级、安全和日常维护。如果只是想尽快把本地网页、远程桌面或者其他服务接到公网,这些准备工作很容易把人挡在第一步。我用 Natapp 一段时间后,最直观的感受就是省事:不用准备公网服务器,也不用维护一套服务端。注册账号、创建隧道、下载,再用authtoken启动,公网入口就有了。

2301_80863610的博客 1万+

计算机网络综合实训室怎么建?2026版建设思路、云平台架构与课程体系深度拆解

平台架构自下而上分为七个部分:分组硬件设备、教学云、实训云、评测云、课程资源、管理平台和公有云。这套体系背后是"教、学、做"一体化的建设理念:实训室既是教室,也是校内生产性实训基地,学生在里面做的事,和他将来在企业里做的事,流程上应该是一致的。学生完成教师安排的教学实训内容。

whwzzc的博客 1704

开源 lwIP:单片机上的轻量 TCP/IP 协议栈

我们要的是 Linux 那套完整网络世界,还是一份能塞进 MCU 的、可裁剪的 TCP/IP?lwIP 把路走窄了,也走实了:窄在不做通用 OS 网络子系统;实在无数量产固件里默默转发每一包。它不靠刷星证明自己,靠的是——你打开厂商工程时,头文件里已经写着lwip。厂商/官方 echo 例程 → 读懂lwipopts.h→ ping 通 → 一条 TCP/UDP → 再叠 MQTT/HTTP。别第一天就对吞吐和 TLS 一起开战——先让协议栈在板上「活着」。

buhuidage的博客 166

网络传输安全剖析:WebRTC 本地真实 IP 泄漏机制(STUN/TURN)与 Python 防护检测实战

深入剖析 WebRTC 在网络代理环境下通过 STUN/TURN/ICE 协议穿透 NAT 导致本地真实物理 IP 泄漏的底层成因,并使用原生 Python 实现 RFC 5389 二进制报文解析与穿透风险自动化检测。

etsyZS的博客 180

SD-WAN网络可视化实践:如何让IT部门从救火队变成决策者?

网络可视化破解IT运维困局,将“黑盒”网络变为可监控、可管理的透明体系。通过端到端链路监控、应用级流量识别与智能告警,企业实现故障精准定位、资源科学分配与数据驱动决策。从被动救火到主动预警,从经验判断到智能优化,IT角色由“成本中心”转向“业务支撑者”。尤其对多分支企业,可视化结合SD-WAN技术,降低运维门槛,提升网络效率,正成为现代网络运维的标准配置。

OgCloud_ICT的博客 208

对称加密和非对称加密(小记)

首先来看一下什么是对称加密和非对称加密:在互联网中,一台主机可以和任意一台其他主机通信,无论是对称加密还是非对称加密,对于每一对通信我们都需要尽量使用不同的秘钥,否则一但相同秘钥的两对主机监听到了对方的消息,就会导致加密数据被泄露对于对称加密来说,它有以下缺点:而对于非对称加密来说,它有以下缺点:因此在实际使用过程中,我们一般使用非对称加密来完成对称秘钥的确定(破除循环),然后使用对称秘钥进行通信(提高性能)

2302_80221042的博客 182

PPTP和L2TP哪个更安全?老旧协议选择建议

网络通信与数据传输安全评估中,。PPTP依赖的MS-CHAP v2身份验证机制与128位RC4流加密算法已被现代密码学证实存在严重逻辑缺陷,容易遭受离线字典攻击与密钥解密;而L2TP通过与IPsec协议紧密结合,采用高强度AES对称加密算法、SHA数据完整性校验以及双向证书认证,具备完善的机密性与防篡改能力,整体防护等级远超PPTP。

Loongproxy的博客 194
上一篇: LWN:Linux 5.11 合并窗口第一部分!
下一篇: LWN:关注隐私安全自由的PureOS!
LinuxNews搬运工
博客等级 码龄7年 419粉丝 20原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值