基础流程
-
wifi驱动加载(insmod或者modprobe)
-
设备驱动匹配探测(我们常见的probe函数)
整体流程
驱动加载 → 注册支持设备 → 设备插入 → 匹配驱动 → 初始化硬件 → 创建网络接口
明确两点
两个流程
- 驱动加载:指将编译好的驱动程序模块加载到内核中,使其能够被系统识别和使用。
- 设备探测匹配:指当设备插入时,内核如何识别该设备并绑定正确的驱动程序
两个流程的关系
- 驱动加载是前提,只有驱动被加载到内核,才能进行后续的设备识别和绑定。
- 设备探测匹配是驱动加载后的自动过程,当设备连接到系统时,内核通过设备信息(如USB的厂商ID和产品ID)查找已注册的驱动,进行匹配。
所以
驱动加载不正确,设备根本无法被识别,设备探测匹配失败,即使驱动存在,设备也无法正常工作
硬件
- 基于tplink wn722n v1网卡
详细框架流程
- 无线驱动注册:内核调用 ath9k_htc_init,使用usb_register 注册将wifi驱动到 USB 子系统
- 设备探测:匹配设备 ID 后,调用 probe 分配资源、加载固件。
- mac80211 注册:通过 ieee80211_alloc_hw 和 ieee80211_register_hw 注册无线设备。
- 网络接口创建:由 mac80211 生成 wlan 接口,用户可配置连接。
流程解析
- 模块初始化
当执行 sudo modprobe ath9k_htc 或系统自动加载驱动时,内核调用 ath9k_htc_init
- 驱动注册:它定义了 ath9k_hif_usb 驱动的核心结构体 usb_driver,并通过 usb_register 将驱动注册到内核
驱动加载内核日志:
支持ID的列表说明:
USB驱动探测函数ath9k_hif_usb_probe的实现。当USB设备插入并匹配到驱动时,内核会调用这个函数来初始化设备 - 驱动探测函数(当 USB 设备插入时,内核调用此函数进行设备探测,负责设备的初始化和固件加载)
- 固件加载
- 固件加载完成后的回调函数负责继续设备的初始化流程
初始化 USB 设备函数 - 初始化硬件(调用到关键函数)
- ath9k_htc_probe_device 负责完成设备的探测和初始化
mac80211为所指向的驱动程序分配一个私有数据区域
初始化无线设备,包括硬件配置、固件版本检查、注册表初始化、收发队列初始化,并最终注册到 mac80211 子系统,创建网络接口
续上图
一个图总结整个流程
ath9k_htc_init(void) //驱动初始化→ ath9k_hif_usb_init(void) //驱动注册→ ath9k_hif_usb_probe() //设备探测→ ath9k_hif_request_firmware() //请求加载固件→ ath9k_hif_usb_firmware_cb() //固件加载完成后的回调→ ath9k_htc_hw_alloc //为设备分配硬件资源(如内存、DMA 缓冲区)。→ ath9k_hif_usb_dev_init() //初始化 USB 设备(将固件数据通过 USB 传输到设备,为 USB 数据传输分配URB)→ ath9k_htc_hw_init() //初始化硬件(总函数)→ ath9k_htc_probe_device() //负责探测并初始化硬件设备,完成了从分配硬件资源到注册网络接口的完整流程(上一个函数调用)→ ieee80211_alloc_hw(&ath9k_htc_ops) //内核函数,分配无线硬件描述符,ath9k_htc_ops:无线硬件的操作函数集,用于管理无线硬件的操作和状态→ ath9k_init_device() //初始化无线设备硬件(如配置寄存器、启动固件),并注册到 mac80211 子系统→ ath9k_set_hw_capab() //设置硬件的功能集(如支持的频段、接口类型等),设置mac地址→ ath9k_tx_init(priv); //初始化队列(Queue)用于管理数据包的发送→ ieee80211_register_hw(hw) //将设备注册到 mac80211 子系统,创建网络接口(如 wlan0)→ release_firmware(); //释放固件并标记设备就绪
疑问:
- wifi mac是wifi探测设备的必经流程,那mac地址是在哪获取和设置的呢?
将设备从EEPROM中读取的真实MAC地址(common->macaddr)设置为网络接口的永久硬件地址
通过ath9k_hw_common访问到macaddr字段
设置mac地址
- 当无线网卡设备成功被驱动探测并初始化后,内核会通过哪种方式在文件系统中显示设备信息?
我们这里句几个除了工具不常用到的例子,都能说明设备正常被加载
设备通用信息:/sys/bus/usb/devices/1-1
或者:/sys/class/net
这里的常用信息
设备的加载驱动和子系统信息:
还有就是无线物理层PHY参数
或者/proc/net/dev
基础概念加深
- 驱动匹配机制
匹配过程:
1)内核遍历所有已注册的 USB 驱动(通过 usb_register_driver)。
2)对比设备的 (VID, PID) 与驱动 id_table 中的条目。
3)若匹配成功,调用驱动的 probe() 函数(即 ath9k_htc_probe)。 - 无线子系统(mac80211)
1)mac80211 是 Linux 内核中用于实现无线wifi协议栈的核心框架,它为无线网卡驱动提供了统一的软件接口,简化了无线设备驱动的开发。
2)它是现代 Linux 无线驱动的基石,支持多种无线模式(如 AP、STA、Monitor 等)和复杂的 Wi-Fi 功能(如加密、扫描、速率控制等)。
mac80211 的定位与作用
- 功能定位
1)硬件抽象层:将底层无线硬件的操作抽象为统一的 API,驱动开发者只需实现这些接口,无需关心复杂的 802.11 协议逻辑。
2)协议实现:处理 802.11 协议的核心功能,如帧的封装/解析、认证、关联、扫描、加密(WEP/WPA/WPA2/WPA3)等。
3)多模式支持:支持多种无线模式(Access Point, Station, Monitor, Mesh, Ad-Hoc ) - 与其他子系统的关系
1)cfg80211:mac80211 的配置层,提供用户空间工具(如 iw、hostapd)通过 nl80211(基于 Netlink)配置无线接口的接口。
2)硬件驱动:驱动通过实现 mac80211 的回调函数(如发送/接收数据、设置频道等)与物理设备交互。
3)用户空间工具:如 iw、wpa_supplicant,通过 cfg80211 控制无线网络行为。