# TI CC33xx WiFi / 蓝牙驱动 —— Linux 6.12 版本

> 板子：TL3568-EVM（Rockchip `rk3568-evb1-ddr4-v10` 定制版）
> 源码：TI 官方 SDK `CC33XX-LINUX-MPU 1.0.2.17` + `TexasInstruments-Sandbox/cc33xx-linux-mpu-ports` 的 6.12 适配补丁
> 内核树：`/mnt/sdb/RK356X_SDK/kernel-6.12`（6.12.69，commit `470f9dccb`）
> 生成日期：2026-10-10

---

## 一、为什么需要它

板子原厂 rootfs 里的四个 `.ko` 是按 **Linux 5.10.198** 编译的（`modinfo` 的 vermagic 是铁证）。
内核换成 6.12 后 vermagic 不匹配，`insmod` 会直接拒绝加载 —— 所以这四个模块必须重编。

（屏、触摸、背光、PMIC 的驱动是**编译进内核的 builtin**，不需要模块，DTS 说清楚就行。）

---

## 二、产物

四个模块，与板子原厂一一对应：

| 模块 | 体积(字节) | 对应原厂 | SHA256 |
|---|---|---|---|
| `cc33xx.ko` | 1,688,624 | `cc33xx.ko` | `85820b2bd893edea13cb60a298cb414503aadbfd18099502efe17ac8143493ec` |
| `cc33xx_sdio.ko` | 121,336 | `cc33xx_sdio.ko` | `08728dd87b1f1e65b854de5c3bc900436779f4d5aaa3e004ceb9d7da811140a6` |
| `btti.ko` | 130,288 | `btti.ko` | `17983a6dc9b8e636f7b6316e004d84d3220b1df1e0809b970300dfe6c77d0034` |
| `btti_uart.ko` | 110,784 | `btti_uart.ko` | `c6d1353074366051bc6e0490faacd35c232d2a93f9545678a22f4afb7e074d58` |

**总体积 2,051,032 字节（2.05 MB）**

全部模块的 `vermagic`：

```
6.12.69-g470f9dccbdc4-dirty SMP mod_unload aarch64
```

全部 `license: GPL` / `GPL v2`（与上游一致）。

### 元信息核对（证明是同一套驱动，非替代实现）

| 模块 | 关键信息 |
|---|---|
| `cc33xx.ko` | `alias: platform:cc33xx` |
| `cc33xx_sdio.ko` | `alias: sdio:c*v0097d4076*` / `sdio:c*v0097d4077*` |
| `btti.ko` | `description: Texas Instruments Bluetooth driver ver ti_1.0` |
| `btti_uart.ko` | `alias: of:N*T*Cti,cc33xx-bt` ← **与板子原版模块的别名完全一致** |

---

## 三、安装到板子

```bash
# 假设板子已可通过 SSH 访问
scp modules/*.ko root@<板子IP>:/system/lib/modules/

# 先卸载旧模块（如果已加载）
rmmod btti_uart btti cc33xx_sdio cc33xx 2>/dev/null

# 加载新模块
insmod /system/lib/modules/cc33xx.ko
insmod /system/lib/modules/cc33xx_sdio.ko
insmod /system/lib/modules/btti.ko
insmod /system/lib/modules/btti_uart.ko

# 看日志
dmesg | grep -iE "cc33xx|btti"
ip link            # 应该出现 wlan0
```

或者直接把它们放进新 rootfs 的 `/system/lib/modules/`，开机由 `rk-wifi-bt.service` 自动加载。

---

## 四、⚠️ 重要：vermagic 的 `-dirty` 后缀

四个模块的 vermagic 是 `6.12.69-g470f9dccbdc4-dirty`，**结尾带 `-dirty`**。

原因：编译用的内核树里有未提交的改动（我加的板型 DTS `rk3568-tl3568-evm.dts`）。
**这是正常的，但要记住一条规则**：

> 模块的 vermagic 必须和内核查到的完全一致，否则拒绝加载。
> 所以：**这四个 `.ko` 必须配套使用「从同一棵 `-dirty` 树编出来的内核 Image」**。

- 如果直接用从这棵 6.12 树编出来的 `Image` → 匹配 ✓
- 如果之后你在**干净**的内核树上重编内核（vermagic 变成不带 `-dirty`）→ 这四个 `.ko` 会**加载失败**，需要用同一棵干净树重编模块
- 想让 vermagic 干净：把改动 `git commit` 掉，再重编内核和模块

---

## 五、编译过程记录（复现要点）

原厂的内核树里**完全没有** cc33xx（`.repo/project-objects/rk/kernel.git` 全分支搜索为空），属**树外模块**。
走的是 TI 官方路径：SDK 源码补丁 + 6.12 适配补丁。

### 两个补丁的关系（关键）

| 补丁 | 作用 | 能否直接套 6.12 |
|---|---|---|
| `cc33xx_kernel.patch`（SDK 自带，719 KB） | 驱动源码本体 | ⚠️ 驱动部分可以；`net/mac80211`、`8250_omap` 部分**不行** |
| `0001-...-for-linux-6.12..patch`（TI ports 库） | 把驱动适配到 6.12 的 API | ⚠️ **必须叠在基础补丁之上**，单独用会失败 |

**只取驱动本体的做法**（不要 TI 自家板子的 mac80211 / 串口改动）：

```bash
# 用切分脚本按 diff 段精确挑路径，避开 net/mac80211 和 drivers/tty
python3 /mnt/sdb/RK356X_SDK/split_cc33xx_patch.py
cd /mnt/sdb/RK356X_SDK/kernel-6.12
patch -p0 --forward < /mnt/sdb/RK356X_SDK/cc33xx-driver-only.patch
patch -p1 --forward < /mnt/sdb/RK356X_SDK/update-cc33xx-only.patch
```

### 踩过的坑（都记在这里，免得重来）

1. **`git apply --include` 会把挂载钩子误判为 skipped**
   → 结果是驱动源码文件被 check 了，但 `drivers/net/wireless/ti/Makefile` 里的
   `obj-$(CONFIG_CC33XX) += cc33xx/` **没进去** → 驱动永远不参与编译。
   **改用 `patch -p0` + 按 diff 段切分**（`git apply` 的这个行为不可靠）。

2. **`ti/Makefile` 的 hunk 匹配失败**
   6.12 的这个文件只剩 5 行，补丁的上下文里还有 `# small builtin driver bit` /
   `obj-$(CONFIG_WILINK_PLATFORM_DATA)` —— **那两行 6.12 已删除**，所以匹配不上。
   **手工补上钩子**：
   ```
   obj-$(CONFIG_CC33XX)			+= cc33xx/
   ```

3. **配置符号名不是你以为的那个**
   实际是 `CC33XX` / `CC33XX_SDIO` / `BT_TI` / `BT_TI_UART`（**不是** `BT_BTTI`）：
   ```bash
   scripts/config --module CC33XX --module CC33XX_SDIO --module BT_TI --module BT_TI_UART
   ```

4. **`make modules_prepare` 不生成 `Module.symvers`**
   → modpost 阶段报几百条 `"xxx" [yyy.ko] undefined!`（**连内核自带的 `hci_uart.ko` 都编不过**）。
   **必须先做一次全量内核构建**，才有符号表。

5. **6.12 新增的严格检查，不是 TI 的代码问题**
   ```bash
   make ... KCFLAGS="-Wno-error=missing-prototypes"
   ```

6. **手动修的两处真实代码问题**（TI 的 6.12 适配补丁漏掉的）
   | 文件 | 问题 | 改法 |
   |---|---|---|
   | `cc33xx/scan.c:782` | `void inline f()` —— 6.12 要求 `inline` 在前 | 改成 `inline void f()` |
   | `cc33xx/sysfs.c:551` | 格式串 `%d` 配 `sizeof` 型参数（`unsigned long`） | 改成 `%zu` |

### 编译命令

```bash
cd /mnt/sdb/RK356X_SDK/kernel-6.12
K="ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- KCFLAGS=-Wno-error=missing-prototypes"

make $K M=drivers/net/wireless/ti/cc33xx modules -j16
make $K M=drivers/bluetooth modules -j16
```

---

## 六、依赖：内核侧还需要什么

这四个模块能编出来，但它们要**跑起来**还依赖内核本身的这些配置（需在 6.12 的 `.config` 里打开）：

- `CONFIG_CFG80211` / `CONFIG_MAC80211`（WiFi 栈）
- `CONFIG_BT` / `CONFIG_BT_HCIUART`（蓝牙栈）
- `CONFIG_MMC_SDHCI` + Rockchip SDIO 控制器（`cc33xx_sdio` 走 SDIO 总线）
- 固件路径：`/lib/firmware/ti-connectivity/`（`cc33xx_2nd_loader.bin` / `cc33xx_fw.bin` / `cc33xx-conf.bin`）

### ⚠️ 一个已知的悬案

TI 的基础补丁还改了 `net/mac80211/{mlme,util,wpa}.c`（增加 `RX_FLAG_PN_VALIDATED` 等），
这部分**因为没有打上去**，所以：

- 如果运行时发现 WiFi 的加密/PN 校验行为异常 → 需要回头看这三个文件的改动
- 编译期没报错，说明驱动代码没有直接引用那些新符号

---

## 七、相关文件位置

| 内容 | 路径 |
|---|---|
| TI SDK 解包 | `/mnt/sdb/RK356X_SDK/cc33xx-sdk-1017/cc33xx_linux_package_1_0_2_17/cc33xx/` |
| TI ports 补丁库 | `/mnt/sdb/RK356X_SDK/cc33xx-ports/` |
| 切分脚本 | `/mnt/sdb/RK356X_SDK/split_cc33xx_patch.py` |
| 切出的基础补丁 | `/mnt/sdb/RK356X_SDK/cc33xx-driver-only.patch` |
| 切出的适配补丁 | `/mnt/sdb/RK356X_SDK/update-cc33xx-only.patch` |
| 编译日志 | `/mnt/sdb/RK356X_SDK/build-driver2.log` |
| 内核树 | `/mnt/sdb/RK356X_SDK/kernel-6.12/` |
| 内核 Image | `kernel-6.12/arch/arm64/boot/Image`（43,901,440 B） |
| 板型 DTB | `kernel-6.12/arch/arm64/boot/dts/rockchip/rk3568-tl3568-evm.dtb`（197,267 B） |

---

## 八、与 rootfs 的关系

本目录的模块是**给「换 6.12 内核」这条线**用的。

如果你暂时**只刷 rootfs、不换内核**（内核仍是 5.10.198），那么**不要**用这里的模块 ——
新 rootfs 里 `/system/lib/modules/` 放的仍是按 5.10.198 编的原版模块，
vermagic 与现有内核匹配，**WiFi / 蓝牙照常能用**。

换内核时再把这四个换成这里的 6.12 版。
