2. Linux 内核源码结构:内核源码目录树解析
在开始 WiFi/蓝牙驱动移植之前,必须深刻理解 Linux 内核源码的组织方式。内核源码树是一个高度模块化、层次分明的工程结构,掌握其目录布局是裁剪与适配工作的基础。本章将详细解析核心目录、构建系统以及版本选择策略。
2.1 内核源码顶层目录树解析
Linux 内核源码根目录下包含数十个一级子目录,每个目录承担特定的功能角色。对于驱动开发者而言,以下目录最为关键:
| 目录 | 全称 / 作用 | 驱动开发关注度 |
|---|---|---|
| arch/ | 体系结构相关代码(ARM、x86、RISC-V 等) | ★★★★★ |
| drivers/ | 设备驱动代码(WiFi、蓝牙、I2C、SPI、USB 等) | ★★★★★ |
| net/ | 网络协议栈(TCP/IP、MAC80211、Bluetooth 协议) | ★★★★☆ |
| include/ | 内核头文件(API 定义、数据结构、硬件抽象层) | ★★★★★ |
| kernel/ | 核心调度、进程管理、中断处理 | ★★☆☆☆ |
| mm/ | 内存管理子系统 | ★★☆☆☆ |
| fs/ | 文件系统实现(VFS、ext4、procfs、sysfs) | ★★★☆☆ |
| scripts/ | 构建脚本、Kconfig 解析器、DT 编译工具 | ★★★☆☆ |
| Documentation/ | 内核文档、设备树绑定说明、驱动 API 手册 | ★★★★☆ |
驱动开发者核心路径: 当移植 WiFi 模块时,你主要工作在
drivers/net/wireless/ 和 net/mac80211/;蓝牙模块则涉及 drivers/bluetooth/ 和 net/bluetooth/。同时需要 arch/arm/boot/dts/ 或 arch/arm64/boot/dts/ 中的设备树文件来声明硬件连接。
2.2 Kconfig 与 Makefile:内核配置与构建的骨架
Kconfig 和 Makefile 是内核源码中控制“编译什么”和“怎么编译”的两大核心机制。每个驱动目录下都包含这两个文件。
2.2.1 Kconfig:定义配置选项
Kconfig 文件定义了内核模块的配置菜单项,供 make menuconfig 等配置工具使用。一个典型的 WiFi 驱动 Kconfig 条目如下:
config RTL8822CS
tristate "Realtek 8822CS SDIO WiFi support"
depends on MMC
select CFG80211
select MAC80211
help
This driver supports Realtek 8822CS SDIO WiFi chip.
Choose M to build as module, Y to build-in.
关键语法说明:
- tristate:三态选项(N=不编译,M=模块,Y=编译进内核)
- depends on:依赖关系,如依赖 MMC 子系统
- select:反向选择,自动启用被依赖的选项(如 CFG80211)
- help:帮助信息,描述驱动用途
2.2.2 Makefile:控制编译行为
Makefile 根据 Kconfig 的配置结果,决定哪些源文件被编译以及如何链接。示例:
# drivers/net/wireless/realtek/rtl8822cs/Makefile
obj-$(CONFIG_RTL8822CS) += rtl8822cs.o
rtl8822cs-objs := main.o fw.o mac.o phy.o sdio.o
# 条件编译
ifeq ($(CONFIG_RTL8822CS_DEBUG),y)
rtl8822cs-objs += debug.o
ccflags-y += -DDEBUG
endif
Makefile 变量含义:
| 变量 | 含义 | 示例 |
|---|---|---|
obj-y | 无条件编译进内核 | obj-y += core.o |
obj-m | 编译为可加载模块 | obj-m += rtl8822cs.o |
obj-$(CONFIG_XXX) | 根据配置决定编译方式 | obj-$(CONFIG_RTL8822CS) += rtl8822cs.o |
xxx-objs | 由多个 .o 文件链接成一个模块 | rtl8822cs-objs := main.o fw.o |
ccflags-y | 传递给 C 编译器的额外标志 | ccflags-y += -DDEBUG -Wall |
移植技巧: 在添加新驱动时,通常需要同时修改该目录下的 Kconfig 和 Makefile。如果驱动依赖外部固件,还需在
drivers/net/wireless/ 的顶层 Kconfig 中添加 source 语句来包含子目录。
2.3 内核版本选择与获取
选择合适的内核版本是驱动移植成功的前提。不同版本的内核在 API、子系统架构和驱动框架上存在差异。
2.3.1 版本选择原则
| 场景 | 推荐版本 | 理由 |
|---|---|---|
| 新项目开发(2024+) | LTS 6.1 / 6.6 | 长期支持,驱动 API 稳定,社区活跃 |
| 现有产品维护 | 厂商 BSP 内核版本 | 与硬件平台验证匹配,减少适配工作量 |
| WiFi 6 / BT 5.3 支持 | ≥ 5.15 | 内核原生支持较新无线协议栈 |
| 老旧芯片(如 RTL8188) | 4.19 / 5.4 LTS | 驱动向后兼容性好,社区资源丰富 |
| 实验 / 学习 | 最新稳定版 | 体验最新特性,但 API 可能变动 |
2.3.2 获取内核源码
官方获取方式有三种,推荐优先级从高到低:
- kernel.org 直接下载(最权威)
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.30.tar.xz
tar -xf linux-6.6.30.tar.xz
- Git 克隆主线仓库(适合持续跟踪)
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v6.6
- SoC 厂商 BSP 包(如 Rockchip、NXP、Allwinner 提供的 SDK)
# 厂商通常提供基于特定 LTS 版本的分支
git clone https://github.com/rockchip-linux/kernel.git -b rk3588-linux
版本兼容性警告: 不要盲目选择最新内核。某些 WiFi/BT 芯片(如 RTL8822CS、BCM43455)的驱动可能只在内核 5.10 ~ 6.1 之间经过充分测试。在移植前,务必查阅芯片厂商的
Release Notes 确认支持的内核版本范围。
2.3.3 版本号解读
Linux 内核版本号遵循 主版本.次版本.修订版-补丁级别 格式:
| 示例 | 主版本 | 次版本 | 修订版 | 含义 |
|---|---|---|---|---|
| 6.6.30 | 6 | 6 | 30 | LTS 长期支持版,第 30 次修订 |
| 6.8-rc4 | 6 | 8 | rc4 | 候选发布版(Release Candidate),不稳定 |
| 5.15.148 | 5 | 15 | 148 | 旧 LTS 版本,已维护多年 |
选择建议: 对于产品级驱动移植,始终选择 LTS 版本(如 6.1.x、6.6.x)。LTS 版本会获得至少 2 年的安全更新和关键修复,且驱动 API 不会在生命周期内发生破坏性变更。
2.4 本章小结
- arch/ 包含平台相关代码,驱动移植时需关注设备树(DTS)文件。
- drivers/ 是 WiFi/BT 驱动的主战场,按总线(SDIO、UART、USB)和功能分类。
- net/ 提供无线协议栈支持(mac80211、Bluetooth 子系统)。
- include/ 定义了驱动开发所需的全部内核 API 和数据结构。
- Kconfig 定义配置选项,Makefile 控制编译逻辑,两者必须同步修改。
- 内核版本选择应优先考虑 LTS 版本,并参考芯片厂商的官方支持列表。