UHS-II Linux SCSI驱动编译与加载指南

本文档详细描述UHS-II SD卡驱动的编译、加载和调试方法,适用于x86和RISC-V等多种Linux平台。

环境准备

硬件环境

  • GG8 Board: 使用lspci命令确认GG8 Chip ID (9860~9863)
  • Linux Host PC: x86 PC或其他架构PC(如RISC-V)

操作系统要求

平台 推荐系统 内核版本
x86 Ubuntu 22.04+ uname -r > 6.0
RISC-V Spacemit K1 Bianbu Linux 6.1.15

编译工具安装

x86平台

1
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev

RISC-V平台

参考Spacemit官方文档:https://bianbu.spacemit.com/development/kernel_compile

安装内核头文件

编译内核模块依赖内核头文件库:

1
sudo apt-get install linux-headers-`uname -r`

编译驱动模块

1. 获取源码包

根据目标平台选择对应的源码包:

平台 源码包
x86 linux-scsi-master-20241021-x86.zip
RISC-V linux-scsi-master-20241021-riscv.zip

2. 解压源码

1
2
unzip linux-scsi-master-20241021-x86.zip
cd linux-scsi-master

3. 执行编译

1
make -j$(nproc)

编译成功后在当前目录生成 bht-sd.ko 内核模块文件。

卸载内核内置SD驱动

重要:Linux内核6.0+版本已包含GG8-linux-SD7.0-UHS-I驱动,该驱动不支持UHS-II协议,必须先卸载后才能加载我们的驱动。

步骤1:检查当前SD驱动状态

1
sudo lsmod | grep sdhci

正常输出示例:

1
2
3
sdhci_pci              81920  0
cqhci 40960 1 sdhci_pci
sdhci 86016 1 sdhci_pci

步骤2:卸载SDHCI驱动模块

1
2
3
4
5
6
7
8
# 卸载驱动链
sudo rmmod sdhci_pci
sudo rmmod cqhci
sudo rmmod sdhci

# 确认卸载完成
sudo lsmod | grep sdhci
# 应无任何输出

内核6.13+版本额外处理

对于较新的内核版本(如6.13),还需要卸载UHS2相关模块:

1
sudo rmmod sdhci_pci sdhci_uhs2 sdhci

加载bht-sd驱动

1. 加载驱动模块

1
2
cd linux-scsi-master
sudo insmod bht-sd.ko

2. 验证模块加载状态

1
2
3
4
5
6
7
8
# 检查模块是否已加载
sudo lsmod | grep bht

# 输出示例:
# bht_sd 557056 0
# 第二列(557056)是模块内存占用,第三列(0)是引用计数
# 引用计数为0表示当前没有设备使用此驱动
# 引用计数为1表示驱动正在被PCI设备使用

3. 查看驱动日志

1
sudo dmesg

正常情况下会看到大量BHT相关打印日志,确认驱动初始化成功。

插入UHS-II卡测试

1. 插入SD卡

插入UHS-II SD卡,系统应能识别并自动挂载。

2. 验证设备节点

1
2
3
ls -l /dev/sd*
# 或
cat /proc/partitions

3. 性能测试

使用ddfio进行读写性能测试:

1
2
3
4
# 读取测试
sudo dd if=/dev/sdX of=/dev/null bs=1M count=1024 status=progress

# UHS-II模式下读取速度应达到约200MB/s

4. 捕获详细日志

1
2
3
4
5
6
7
8
# 清空内核日志缓冲区
dmesg -c

# 插入卡并执行操作
# ...

# 保存日志
dmesg > uhs2-dmesg.log

常见编译问题解决

问题1:编译器版本不匹配

错误信息

1
warning: the compiler differs from the one used to build the kernel

原因:Ubuntu 22.04默认gcc链接到gcc-11,但新内核6.8-generic由gcc-12编译。

解决方案

1
2
3
sudo apt install --reinstall gcc-12
sudo ln -s -f /usr/bin/gcc-12 /usr/bin/gcc
gcc --version

问题2:内核头文件缺失

错误信息

1
Makefile:10: *** missing separator.

解决方案

1
sudo apt-get install linux-headers-$(uname -r)

问题3:内核源码版本不匹配

如果需要针对特定版本内核编译:

  1. 下载与目标内核版本匹配的内核源码
  2. 修改Makefile中的KERNEL_SOURCE路径:
1
2
# 指向内核源码目录
KERNEL_SOURCE = ~/linux-6.1-bl-v1.0.y

完整加载脚本

以下是一个完整的驱动加载脚本示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/bin/bash
# load-uhs2-driver.sh

set -e

echo "=== UHS-II SD Driver Loader ==="

# 1. 卸载内核内置SD驱动
echo "[1/5] Unloading kernel built-in SD drivers..."
sudo rmmod sdhci_pci 2>/dev/null || true
sudo rmmod cqhci 2>/dev/null || true
sudo rmmod sdhci 2>/dev/null || true
sudo rmmod sdhci_uhs2 2>/dev/null || true
echo " Done"

# 2. 确认GG8设备存在
echo "[2/5] Checking GG8 device..."
if ! lspci | grep -q "SD"; then
echo " WARNING: GG8 device not found!"
else
lspci | grep SD
fi

# 3. 编译驱动
echo "[3/5] Building bht-sd.ko..."
cd linux-scsi-master
make -j$(nproc)
echo " Done"

# 4. 加载驱动
echo "[4/5] Loading bht-sd.ko..."
sudo insmod bht-sd.ko
echo " Done"

# 5. 验证加载状态
echo "[5/5] Verifying driver status..."
if lsmod | grep -q bht_sd; then
count=$(lsmod | grep bht_sd | awk '{print $3}')
if [ "$count" -gt "0" ]; then
echo " SUCCESS: Driver loaded and active (refcount=$count)"
else
echo " SUCCESS: Driver loaded (refcount=$count)"
fi
echo ""
echo "Insert UHS-II SD card to test..."
else
echo " FAILED: Driver not loaded"
exit 1
fi

# 显示dmesg日志
echo ""
echo "=== Driver Messages ==="
dmesg | tail -20

卸载驱动

如需卸载驱动:

1
2
3
4
5
6
# 卸载bht-sd模块
sudo rmmod bht-sd

# 可选:重新加载内核内置SD驱动
sudo modprobe sdhci
sudo modprobe sdhci_pci

参考链接