尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Linux WiFi驱动开发实战:从设备树到mac80211的完整指南

Linux WiFi驱动开发实战:从设备树到mac80211的完整指南 1. 为什么 WiFi 驱动开发总卡在开头先分清无线子系统和硬件总线接手 Linux WiFi 设备驱动开发的人十个里有七八个第一步就栽了拿到一块 WiFi 芯片翻出厂商的驱动源码make一下全是错误或者编译过了 insmod 报一堆Unknown symbol然后就开始怀疑人生。我在这个方向上折腾了好几年最重要的一个经验是——WiFi 驱动开发的最大难点不在无线两个字而在Linux 驱动模型和网络子系统的交界处。你既要懂sk_buff、net_device、mac80211这些网络侧的概念又要懂platform_driver、sdio_driver、pci_driver、device tree这些总线侧的概念还得知道cfg80211这个连接用户空间和内核空间的枢纽怎么工作。先说清楚一个基本事实Linux 下任何 WiFi 设备不管它挂在 SDIO、PCIe 还是 USB 总线上最终都要通过内核的无线子系统向上层提供能力。这个子系统从下往上大致是硬件设备 → 总线驱动 → 硬件抽象层如 mac80211→ cfg80211 → 用户空间的 wpa_supplicant / NetworkManager。驱动开发者的工作大多数情况下是写让芯片适配 mac80211 / cfg80211 的那一层以及让芯片在自己的总线上被枚举出来的那一部分。两者缺一不可但它们的调试手段完全不同。还有一个很多人忽略的问题WiFi 驱动的编译通过只是万里长征第一步。真正难的是运行时行为——固件有没有加载中断有没有触发DMA 缓冲区有没有正确映射TX/RX 队列有没有卡死省电模式和 roaming 会不会把连接搞挂这些问题的排查思路和写一个字符设备驱动完全是两个世界。在往下拆解之前我先把常见的几种 WiFi 芯片方案和它们的驱动套路放在这里方便你对号入座芯片/方案常见总线内核侧主要框架典型驱动形态Realtek RTL8188/8723 系列USB / SDIOcfg80211 mac80211 或 vendor 专用rtl8xxxu、rtl8723bsBroadcom BCM43438 / 4339SDIOcfg80211 mac80211brcmfmacQualcomm Atheros QCA9377 / AR938xPCIe / SDIOath10k / ath9kmac80211ath10k_pci、ath9kMediaTek MT76xx / MT79xxUSB / PCIe / SDIOmac80211mt76、mt7921e全志/瑞昱等国产方案SDIO厂商驱动 mac80211vendor 目录下独立驱动不同总线意味着不同的枚举方式、中断处理方式和 DMA 机制这直接决定了你的设备树怎么写、驱动怎么注册、调试日志该怎么看。很多人纠结WiFi 驱动开发应该从哪入手我的建议很直白先搞清楚你手上的板子走的是哪条总线再谈别的。2. 设备树、总线枚举与内核配置让内核先把芯片认出来驱动开发的第一步不是写驱动而是让内核能在启动阶段看到这个设备。如果你的芯片走的是 SDIO 或 PCIe那么设备树Device Tree和内核 Kconfig 的配合就是第一个拦路虎。2.1 SDIO WiFi 的设备树节点怎么配SDIO WiFi 在嵌入式板子上极其常见尤其是全志、瑞芯微、联咏这些 SoC 的方案。它挂在 SoC 的 SDIO 控制器上设备树里要做的第一件事是把 WiFi 芯片的compatible和中断引脚、复位引脚、电源引脚交代清楚。以瑞芯微 RK3399 平台接 AP6356SBroadcom BCM43456为例典型的设备树节点长这样sdio0 { status okay; bus-width 4; cap-sd-highspeed; cap-sdio-irq; disable-wp; keep-power-in-suspend; non-removable; rockchip,default-sample-phase 90; #address-cells 1; #size-cells 0; brcmf: wifi1 { reg 1; compatible brcm,bcm43456-fmac; interrupt-parent gpio0; interrupts RK_PA3 IRQ_TYPE_LEVEL_LOW; pinctrl-names default, sleep; pinctrl-0 wifi_host_wake_l; pinctrl-1 wifi_host_wake_sleep; }; };这里有三个关键点每个都是新手容易踩的坑第一non-removable和keep-power-in-suspend必须加上。WiFi 芯片是焊死在板子上的它在系统 suspend 的时候不能掉电否则固件状态全丢醒来直接连不上。cap-sdio-irq也要打开否则走不了 SDIO 的中断机制只能用轮询性能惨不忍睹。第二中断引脚要用IRQ_TYPE_LEVEL_LOW而不是边沿触发。Broadcom 和 Realtek 的 WiFi 芯片 HOST_WAKE 引脚基本都是电平触发驱动注册中断的时候如果配成IRQ_TYPE_EDGE_FALLING你会发现系统频繁丢中断RX 吞吐量上不去甚至出现WiFi 连上了但 ping 不通的诡异现象。第三rockchip,default-sample-phase这类参数是 SoC 平台特有的它控制 SDIO 控制器的采样相位。WiFi 芯片的 SDIO 时钟频率跑 50MHz 甚至更高的时候信号完整性会受 PCB 布线影响相位调不对就会随机 CRC 错误。这个值没有通用解只能一档一档试然后跑长时间吞吐测试来判断。2.2 PCIe WiFi 的枚举问题PCIe 接口的 WiFi 芯片比如 Intel AX200/AX210 系列、Qualcomm QCA6174/QCA6390相对省心因为 PCIe 是真正的即插即用总线内核枚举出来之后会主动匹配驱动。但省心不等于没坑。最常见的两个一是BIOS/固件没有给 WiFi 卡分配足够的 PCIe 资源导致lspci看得到设备但报unclaimed也就是没有驱动认领。这时候先用lspci -vnn看设备的 vendor/device ID 和当前资源分配再用dmesg | grep pci看枚举日志。二是PCIe ASPM电源管理引发的不稳定。很多 WiFi 卡和 SoC 在开启 ASPM 的情况下空闲时会进入低功耗链路状态但驱动或者固件没有正确配合就会导致系统挂着挂着 WiFi 就消失了或者恢复后连不上。遇到这种情况可以在内核参数里加pcie_aspmoff先验证如果关掉就稳定再回头去调驱动里的 ASPM 处理逻辑。2.3 内核 Kconfig 配置的隐藏依赖很多人在 menuconfig 里勾选了CONFIG_WLAN_VENDOR_BROADCOM和CONFIG_BRCMFMAC但编译出来还是没有 brcmfmac 模块为什么因为BRCMFMAC 依赖CONFIG_CFG80211而CONFIG_CFG80211又依赖CONFIG_WIRELESS和CONFIG_NET。如果你是从一个裁剪过的内核配置开始改的这三层依赖可能断在某一节。另外一个特别容易被忽略的CONFIG_BRCMFMAC_SDIO和CONFIG_BRCMFMAC_PCIE是两个独立选项你必须根据实际总线选择正确的那个。我见过有人要调 SDIO 接口的 BCM43438结果只改了CONFIG_BRCMFMACSDIO 相关的代码根本没编进去然后花了三天找为什么驱动没 probe。连上之后验证是否认到设备我一般用这几条命令# 查看 SDIO/PCIe/USB 总线是否枚举到设备 lsusb lspci -nnk cat /sys/bus/sdio/devices/*/device # 查看驱动有没有 bind dmesg | grep -i brcmfmac ls /sys/bus/sdio/drivers/brcmfmac/ # 确认无线接口有没有生成 ip link iw dev如果ip link看不到wlan0但驱动已经 probe 成功那就是从net_device_ops注册到cfg80211注册之间出了问题这是我们下一节要拆的内容。3. cfg80211 / mac80211 驱动模型你的驱动到底要注册什么WiFi 驱动和普通平台驱动的最大区别在于普通驱动只需要实现probe、remove和一堆文件操作就行但 WiFi 驱动必须向内核无线子系统上报自己的能力并实现若干个回调接口。这个模型理解得越透调试就越有方向。3.1 三种驱动形态的取舍Linux 无线子系统里驱动可以分成三类FullMAC 驱动芯片固件自己处理 802.11 MAC 层的绝大部分功能驱动只需要做控制和数据转发。比如brcmfmac就是典型的 FullMAC 驱动。驱动的代码量小但固件闭源出问题不好查。SoftMAC 驱动mac80211MAC 层的管理功能由内核mac80211子系统和驱动共同完成驱动要上报ieee80211_ops注册ieee80211_hw。ath9k、mt76、rtl8xxxu都是这种。可定制性强但开发量也大。纯粹的 vendor 驱动不走 mac80211自己实现net_device_ops自己处理 802.11 帧。早期很多国产方案的祖传驱动就是这么写的代码又臭又长但文档稀疏只能硬啃。我的建议很明确如果你手里的芯片有 mac80211 驱动的公开源码优先适配它不要从零写。WiFi 协议栈的复杂程度远远超过个人或小团队能维护的范畴从零写意味着你要处理 Beacon 管理、扫描逻辑、速率控制、省电、重传、加密卸裁等等每个都是一年起步的工程。厂商不给你 mac80211 驱动多半是固件层就封死了那你也只能接受 FullMAC 的形态。3.2 核心数据结构与回调把驱动挂进子系统以 SoftMAC 驱动为例你的probe函数里要做的事情大致可以概括为三步第一步分配ieee80211_hw结构struct ieee80211_hw *hw; hw ieee80211_alloc_hw(sizeof(struct my_priv), my_ops); if (!hw) return -ENOMEM;这里的my_ops就是你的驱动要实现的ieee80211_ops。这个结构体里几十个回调但实际必须实现的没那么多关键在于start、stop、config、add_interface、remove_interface、tx、configure_filter、set_key这几个。第二步填充hw的能力位。这一块尤其重要因为用户空间的wpa_supplicant会通过NL80211_CMD_GET_WIPHY读取你的能力位然后决定它支持什么操作。比如hw-flags IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; hw-wiphy-interface_modes BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); hw-wiphy-bands[NL80211_BAND_2GHZ] my_2ghz_band; hw-wiphy-bands[NL80211_BAND_5GHZ] my_5ghz_band;这里有个细节如果你声明了支持IEEE80211_HW_HAS_RATE_CONTROL那么速率控制完全由驱动自己负责mac80211 不会帮你做速率选择。很多移植驱动的人在这里偷懒结果吞吐率惨不忍睹还找不到原因。第三步注册ret ieee80211_register_hw(hw);注册成功之后内核无线子系统才会向用户空间暴露phy0设备wpa_supplicant才能通过nl80211和它对话。如果注册失败iw dev什么都看不到。3.3 数据路径TX 和 RX 的完整链路数据路径是 WiFi 驱动最容易出诡异 bug 的地方。先说 TX。上层发包时最终会进到你ieee80211_ops.tx回调传入一个ieee80211_tx_control和一个sk_buff。你的任务是把sk_buff里的数据搬到 DMA 缓冲区或者打包成固件认识的 TX descriptor塞进芯片的 TX FIFO然后通知固件发出去。发完之后要记得ieee80211_tx_status_irqsafe(hw, skb)否则 mac80211 的队列管理会一直认为包还在飞拥堵窗口永远不恢复。RX 路径更典型硬件收到一帧通过 DMA 把数据放到内存触发中断。在中断或者 tasklet/NAPI 的上下文里你要从 RX ring 里取回缓冲区拆掉硬件加的头把 802.11 帧组装进一个新的sk_buff然后交给ieee80211_rx_irqsafe(hw, skb)。如果这个函数没有被调用你连iw dev wlan0 station dump都看不到 RSSI。这里有一个经验教训不要在你的中断处理函数里做太多事。WiFi 芯片的 RX 吞吐量动不动就是几百 Mbps如果 RX 路径不进入napi_schedule而是全在 hardirq 里处理CPU 直接被打满系统卡到怀疑人生。所以老手写的 WiFi 驱动RX 基本都是顶到 NAPI 机制里的。4. 固件加载与电源时序probe 之前最容易翻车的隐藏环节很多人把驱动的核心逻辑写完probe却一直报失败然后拿着dmesg看半天最后发现问题居然出在固件加载和电源时序上。这两块是 WiFi 驱动开发里最脏也最考验经验的环节文档往往写得含含糊糊只能靠踩坑积累。4.1 固件求不到、加载路径错probe 直接失败大多数 WiFi 芯片的 MAC/基带处理都在固件里Linux 驱动的工作之一就是把固件通过特定接口上传到芯片里。如果你的驱动依赖request_firmware()或者request_firmware_direct()那么固件文件必须放在/lib/firmware/下对应的子目录里。一旦放错路径或者版本不对驱动 probe 通常直接失败dmesg里会出现brcmfmac: brcmf_fw_alloc_request: unknown chip: BCM43456或者firmware: failed to load brcm/brcmfmac43456-sdio.bin这类报错九成是固件文件没放对路径或者compatible字符串和固件文件名对不上。我自己的调试习惯是第一次拿到不熟悉的芯片时先在/lib/firmware/brcm/底下ls -l看一眼实际文件名然后去驱动源码里查BRCMF_FW_NAME的拼接规则。还有个常见坑固件版本和驱动版本不匹配。新的内核驱动可能要求新的固件 API 版本老的固件接口号对不上大概率是 probe 成功但扫描不到任何 AP或者连接直接失败。这种问题只能靠换固件版本二分排除。4.2 电源域时序等不到的readyWiFi 芯片的上电时序非常讲究。以 SDIO WiFi 为例典型时序是拉高电源使能脚通常给 3.3V 或 1.8V 供电。拉高复位脚释放复位。等待芯片的ready信号常见是一个 GPIO 电平变化或者是 SDIO 总线能顺利枚举到设备。执行 SDIO 控制器初始化。如果你的设备树里没有把power-gpios和reset-gpios配好或者配了但顺序不对芯片就可能永远枚举不出来。这类问题在dmesg里的表现非常具有欺骗性mmc1: error -110 whilst initialising SDIO card-110是超时。我一开始以为这是 SDIO 时序或时钟频率的问题调了好几天采样相位最后才发现是 GPIO 的复位时序在设备树里根本没被驱动控制。后来我在probe里手动加了一段复位逻辑gpiod_set_value(reset_gpio, 0); // 拉低复位 usleep_range(50000, 100000); // 保持 50-100ms gpiod_set_value(reset_gpio, 1); // 释放复位 usleep_range(200000, 300000); // 等 200ms 让芯片起振这一挂就好了。所以遇到超时先别急着怀疑高速信号先排查最基本的电源、复位、时钟三件事。4.3 平台电源域的坑不只是 GPIO现代嵌入式 SoC 的 WiFi 经常挂在某个 PMIC电源管理芯片的电源域上光拉 GPIO 不够还得通过 regulator 框架使能对应的电源轨。设备树里的vmmc-supply、vqmmc-supply就是干这个的。如果你的 WiFi 电压是 1.8V/3.3V 切换的紫光、瑞芯微、高通这些平台还有额外的sdio_vcc时序要求。搞不定的时候我常常在驱动的probe前面加一堆regulator_get和regulator_enable来验证确认没问题再挪回设备树。5. 移植第三方驱动时的故障排查一套能复用的定位链路移植或适配第三方 WiFi 驱动最怕的是逐行 debug 别人的代码。真正高效的做法是先建立一个可观测的基线再按链路从上到下逐层定位。我整理了一个通用排查流程适配过多个平台基本屡试不爽。5.1 从现象到方向的快速判断先看现象再猜内核这个顺序不能反。我把最常见的现象和对应的排查方向列成一张表你可以先把你的问题对号入座现象最可能的根因排查命令/手段ip link看不到无线接口驱动没 probe 成功 / cfg80211 注册失败dmesg、ls /sys/bus/*/drivers/*/probe 报-110超时SDIO/电源时序/固件加载dmesg的 mmc 日志、手动复位probe 成功但扫描不到 AP固件不匹配 / antenna 配置 / 射频前端iw dev wlan0 scan、dmesg的固件日志能扫描到 AP 但连不上加密/密钥回调未实现 / 驱动不支持 WPA2wpa_supplicant -ddd抓日志连接成功但 ping 不通TX/RX 数据路径问题ethtool -S wlan0看丢包计数吞吐量极低速率控制/AMPDU/中断负载iw dev wlan0 link看速率、perf top长时间运行后 WiFi 消失电源管理 / DMA 泄漏关掉省电模式测试、看kmemleak5.2 现场日志抓取的完整套路内核侧我喜欢的组合是# 打开无线子系统与驱动动态调试 echo file drivers/net/wireless/* p /sys/kernel/debug/dynamic_debug/control echo file net/mac80211/* p /sys/kernel/debug/dynamic_debug/control echo 8 /proc/sys/kernel/printk用户空间侧wpa_supplicant的-ddd参数能提供海量信息它的日志会明确告诉你当前在哪个状态扫描、认证、关联、4 次握手、获取 IP。我见过太多人一上来就抓tcpdump结果抓了一堆加密后的 802.11 帧什么信息都得不到。正确顺序是先看wpa_supplicant的日志确定卡在协议栈哪个阶段再决定要不要用tcpdump -i wlan0 -e和airodump-ng级别的手段。5.3 一个真实案例连上 AP 但 ping 不通的完整定位为了说明这套链路怎么用我讲一个自己踩过的典型case。某平台用的 RTL8723DSSDIO 接口现象是wpa_supplicant能成功关联iw dev wlan0 link显示 connected但ping 192.168.1.1就是不通而且ping的时候dmesg里有大量rtl8723ds: tx timeout。我的第一步不是看驱动而是确认 ARP 能不能通。在同一台机器上arping -I wlan0 192.168.1.1发现 ARP 请求也发不出去。这说明问题出在 TX 数据路径不是路由或防火墙。第二步看驱动里的 TX timeout 处理。tx timeout是 mac80211 在排队后一定时间内没看到 TX 完成中断时报的错。这通常意味着发包给固件之后固件没有产生中断或者中断丢了。我用perf top看了一眼CPU 大部分时间在rtl8723ds的irq_handler里转——说明中断确实在来但频繁进中断处理却没有及时清 DMA 完成。第三步打开驱动的调试开关把RTW_DEBUG级别调到最高打印tx_ok和tx_err计数。结果发现tx_ok一直是 0所有包都走的是tx_err。再追一层问题在 DMA驱动的 TX descriptor 写在某个缓冲区内固件要求该缓冲区地址必须 4 字节对齐而且长度必须是特定单位的整数倍。这个驱动在某个配置组合下会生成奇数字节长度的包导致 DMA 描述符里的长度字段非法固件直接丢弃。解决办法是在ndo_start_xmit里强制 skb 线性化并对齐if (skb-len % 4) { ret skb_pad(skb, 4 - (skb-len % 4)); if (ret) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; } }加上之后ping 立刻通了吞吐测试也从接近于零的水平恢复到正常值。这类对齐问题在 WiFi 驱动里非常普遍尤其 SDIO 和 DMA 场景。这也是为什么我强调拿到驱动后第一件事不是看业务逻辑而是看所有skb进入硬件之前有没有做对齐和线性化处理。6. 从能跑到跑好吞吐、稳定性与功耗的深度调优如果驱动已经能正常连接和上网你的工作只完成了 60%。剩下 40% 是调性能、调稳定性、调功耗这恰恰是把它从demo 能用变成产品可交付的必经之路。6.1 吞吐量卡住的常见瓶颈吞吐量低的排查我按照以下优先级来查速率选择和 MCS 有没有生效。iw dev wlan0 link里如果速率始终徘徊在 6/9/12 Mbps说明速率控制没有正常工作。SoftMAC 驱动里要看sta_rc_update和get_rates这几个回调有没有正确上报能力。FullMAC 驱动则多半是固件配置问题。AMPDU 和 BABlock ACK协商。WiFi 4/5/6 的吞吐靠的是聚合帧如果 BA session 建立失败吞吐会掉一个量级。抓固件日志看有没有BA setup相关报错。中断和 NAPI 调度。高吞吐场景下如果驱动把 RX 处理放在 hardirq 里CPU 会先爆掉。用 NAPI 是标准解法。SDIO/PCIe 总线带宽是否成为瓶颈。SDIO 4-bit 模式理论上限约 200Mbps 左右PCIe Gen1 x1 约 250MB/s实际上都不可能跑满。如果硬件本身就只有 SDIO 2.0 的接口你不可能通过驱动优化突破物理上限。必须接受这个现实然后在协议栈层面做优化比如调整 TCP 缓冲、关闭tcp_segmentation_offload之类的具体因平台而异。6.2 稳定性问题的三类来源长期跑挂了99% 来自三类问题第一类是RX 路径的 skb 泄漏。WiFi RX 往往需要给每个收到的帧分配skb如果某个分支把skb丢掉了而没有kfree_skb内存就会缓慢增长。判断方法很简单跑 24 小时压测每隔 1 小时看cat /proc/meminfo和kmemleak的输出。第二类是省电模式与固件状态的同步。很多嵌入式平台默认开启iw dev wlan0 set power_save on但某些固件对这个命令的处理有 bug会导致 AP 侧认为你已经睡了而你实际还在发数据最终死锁。排查方法是关掉省电模式再压测iw dev wlan0 set power_save off如果关闭后问题消失那就是省电相关的固件路径有问题。第三类是TDLS 和 roaming 触发的状态机 bug。这两种功能都涉及驱动状态机的动态切换容易在边缘情况下漏处理。我遇到过某平台启用 802.11r fast roaming 后切换 AP 时偶尔会卡在认证阶段最后定位到是驱动没有在新 AP 的assoc完成前清掉旧 AP 的 BA session。6.3 功耗调优别只看 soc 的 cpufreqWiFi 模块的功耗大头在 RF 前端和基带驱动能控制的主要是TX power 上限、listen interval、power save 模式、以及空闲时是否让固件进入休眠。许多驱动都有一个dynamic_ps_timeout参数表示在空闲多久后进入省电模式。实机上我曾经通过调整监听间隔从 1 调到 10单位是 beacon 间隔让整机待机功耗降低了 40%。但是注意listen interval 加大会导致「手机/设备会错过一些 beacon 帧延迟收到下行业务」。这个值需要根据产品形态去权衡——交互类设备可以用短间隔IoT 低功耗设备才能用长间隔。没有万能参数。7. 我常用的调试工具箱与君子协定最后分享一组我实际项目里每天都在用的工具和习惯不一定有很多技术含量但真的能让排查效率翻倍。动态调试 (dynamic_debug)WiFi 驱动源码里布满了pr_debug、netdev_dbg之类的日志默认不输出。通过/sys/kernel/debug/dynamic_debug/control按文件、函数、行号精准打开比直接改源码加 printk 再编译重烧快太多。iw/mlan/wl私有命令不同芯片有不同私有调试接口。brcmfmac有debugfs下的dhd命令mt76有/sys/kernel/debug/mt76/*/Realtek 驱动常有 own 的ioctl工具。优先用厂商私有工具去读寄存器、看固件状态、拉 TX/RX 计数这些信息在内核日志里永远看不到。ftrace排查驱动回调的调用顺序和函数耗时非常好用。开function_graph追踪ieee80211_ops里的tx、config、add_interface可以快速看到某个操作卡在哪个函数内部。逻辑分析仪SDIO 和 I2C 类总线问题软件手段往往不够一个十几块钱的 24MHz 逻辑分析仪就能看到波形到底有没有数据、时序对不对。调试 SDIO WiFi 枚举失败时这是终极手段。压测脚本要自动化反复手动iw scan、wpa_cli disconnect、wpa_cli reconnect很容易遗漏问题。写一个 shell 循环每隔 N 秒重连一次连续跑一整晚第二天看日志找异常能自动暴露掉线、内存泄漏等稳定性问题。另外有两条君子协定级别的经验值得刻在工位上不要在内核线程里 sleep。WiFi 驱动的很多回调运行在中断上下文或 softirq 上下文一旦调用msleep、udelay、wait_event这类可能睡眠的函数系统会挂得很莫名其妙。正确做法是把耗时操作扔进workqueue或者tasklet再在 workqueue 里慢慢等。每次改驱动之前先保存一个已知可用的基线版本。WiFi 驱动的改动经常牵一发动全身你不知道哪一行会是压死骆驼的最后一根稻草。用 git 在每次能正常编译、能连接、能跑基本吞吐的时候打一个 tag出问题随时回退对比比任何 debug 手段都可靠。8. 写在最后一次失败移植带给我的最大教训说实话Linux WiFi 设备驱动开发从来不是照着厂商 README 编译一下就行的活也不是把代码编过、insmod 成功就算完事的活。它要求你对内核网络子系统、无线子系统、总线框架、DMA/中断机制都有足够深入的理解而且每一块知识都能在关键时刻拿出来用。我见到不少同事一开始被一堆ieee80211_hw、cfg80211_ops的术语吓退其实这些结构体并不可怕怕的是你跳过了对框架的理解直接钻进某个芯片的私有驱动里。学 WiFi 驱动先把 Linux 无线子系统的抽象层次理清楚再下手写任何一行代码你的效率至少翻一倍。如果只让我留一条经验给准备入坑的朋友那就是出了问题先确认问题出在哪个层。是总线路由层是探测/上电层是协议栈状态机还是数据路径把层次找准了剩下的就是按图索骥。别急着把锅甩给硬件不稳定或厂商固件有 bug多数情况下问题还是出在我们自己写的这一层。
返回列表