Linux新内核及新蓝牙协议栈测试虚拟环境搭建

前言

版本信息:

Bluez: ver 5.87
Linux kernel: 7.2.0-rc2
Linux宿主机

目前AI Agent可以自行更新最新的内核版本和核外协议栈,并自行进行构建,然后运行虚拟环境进行全套蓝牙协议栈自测,最后输出测试报告。
以下是基于 Debian (使用 debootstrap) 构建极简 Rootfs 并集成“核外”最新 BlueZ 测试环境的简约指南。


宿主机准备 (Host)

在宿主机上安装必要的构建工具:

sudo apt update
sudo apt install -y debootstrap qemu-utils binfmt-support

创建工作目录:

mkdir -p ~/bt_test_rootfs_build && cd ~/bt_test_rootfs_build
export ROOTFS_DIR=$(pwd)/debian_minimal

阶段 1:使用 debootstrap 生成极简 Debian 基础

使用 debootstrap 拉取一个没有多余软件包的纯净 Debian 基础系统(推荐使用 bookworm 稳定版作为底座,或者 sid 获取稍新的基础库)。

# 1. 初始化基础系统 (仅包含 essential 包,体积约 100MB)
sudo debootstrap --variant=minbase bookworm $ROOTFS_DIR http://deb.debian.org/debian

# 2. 挂载必要的虚拟文件系统,以便在 chroot 中安装软件
sudo mount --bind /dev $ROOTFS_DIR/dev
sudo mount --bind /proc $ROOTFS_DIR/proc
sudo mount --bind /sys $ROOTFS_DIR/sys
sudo mount --bind /dev/pts $ROOTFS_DIR/dev/pts

阶段 2:配置 Rootfs 内部基础环境

进入 chroot 环境,配置网络、串口控制台和 SSH,使其能够在 QEMU 中正常启动并被访问。

sudo chroot $ROOTFS_DIR

# --- 以下命令均在 chroot 环境内执行 ---

# 1. 配置软件源
cat <<EOF > /etc/apt/sources.list
deb http://deb.debian.org/debian bookworm main contrib non-free-firmware
deb http://deb.debian.org/debian-security/ bookworm-security main
EOF
apt update

# 2. 设置基础系统信息
echo "debian-bt-test" > /etc/hostname
echo "root:root" | chpasswd  # 设置 root 密码为 root (测试环境图方便)

# 3. 配置网络 (使用轻量级的 systemd-networkd)
apt install -y --no-install-recommends systemd systemd-sysv iproute2
cat <<EOF > /etc/systemd/network/20-wired.network
[Match]
Name=en* eth*
[Network]
DHCP=yes
EOF
systemctl enable systemd-networkd

# 4. 配置串口控制台 (QEMU 无头模式必备,否则看不到登录提示)
systemctl enable getty@ttyS0.service
# 允许 root 通过串口登录
sed -i 's/#NAutoVTs=6/NAutoVTs=1/' /etc/systemd/logind.conf

# 5. 安装 SSH 服务 (方便自动化脚本通过 SSH 执行测试)
apt install -y --no-install-recommends openssh-server
systemctl enable ssh
# 允许 root SSH 登录
sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config

# 6. 安装 D-Bus (BlueZ 强依赖 D-Bus,极简系统默认可能没装全)
apt install -y --no-install-recommends dbus
systemctl enable dbus

阶段 3:构建“核外”蓝牙测试环境 (核心)

这是最关键的一步。我们将放弃 apt install bluez,转而从源码编译最新版本的 BlueZ 及其测试工具(包括 btvirt, btmon)。

# 1. 安装编译最新 BlueZ 所需的依赖
apt install -y build-essential pkg-config git autoconf automake libtool \
    libdbus-1-dev libudev-dev libical-dev libreadline-dev libsystemd-dev \
    libell-dev libjson-c-dev libglib2.0-dev libudev-dev udev python3-docutils

# 2. 克隆最新的 BlueZ 源码
cd ~/
git clone git://git.kernel.org/pub/scm/bluetooth/bluez.git
cd bluez

# 3. 配置编译选项
# 关键点:
# --enable-experimental: 启用实验性
# --enable-testing  : 编译单元测试工具
# --disable-*       : 裁剪不需要的功能(如 CUPS, OBEX, Mesh),保持极简
./bootstrap
./configure \
    --prefix=/usr \
    --sysconfdir=/etc \
    --localstatedir=/var \
    --enable-testing \
    --enable-deprecated \
    --enable-experimental \
    --enable-debug \
    --enable-test \
    --disable-cups \
    --disable-mesh \
    --disable-obex \
    #--disable-systemd  # 注意:如果要用 systemd 管理,这里不要 disable,或者用 --enable-systemd

# 4. 编译并安装
make -j$(nproc)
make install

# 5. 验证核外工具是否安装成功 mount -t proc proc /proc
btmon --version
bluetoothctl --version
#btvirt 工具生成在 emulator/ 目录下
./emulator/btvirt --version

# 6. 配置 bluetoothd 服务 (使用 systemd 管理)
# BlueZ 源码中通常自带 systemd service 文件,如果没有,手动创建一个
cat <<EOF > /etc/systemd/system/bluetooth.service
[Unit]
Description=BlueZ Bluetooth Protocol Stack
After=dbus.service

[Service]
Type=dbus
BusName=org.bluez
ExecStart=/usr/libexec/bluetooth/bluetoothd -d -n
# -d 开启 debug 日志,-n 不后台运行 (由 systemd 管理)

[Install]
WantedBy=multi-user.target
EOF
systemctl enable bluetooth

# 7. 清理编译垃圾 (减小镜像体积)
#rm -rf ~/bluez
apt clean
rm -rf /var/lib/apt/lists/*

阶段 4:系统清理与镜像打包

退出 chroot,卸载虚拟文件系统,并将目录打包为 QEMU 可用的磁盘镜像。

# 退出 chroot
exit

# 卸载虚拟文件系统
sudo umount $ROOTFS_DIR/dev/pts
sudo umount $ROOTFS_DIR/dev
sudo umount $ROOTFS_DIR/proc
sudo umount $ROOTFS_DIR/sys

# 方案 A:打包为 ext4 磁盘镜像 (推荐,支持持久化修改和快照)
dd if=/dev/zero of=debian_bt_test.ext4.img bs=1M count=4096  # 创建 4GB 镜像
sudo mkfs.ext4 debian_bt_test.ext4.img
sudo mkdir -p /mnt/rootfs_mount
sudo mount -o loop debian_bt_test.ext4.img /mnt/rootfs_mount
sudo cp -a $ROOTFS_DIR/* /mnt/rootfs_mount/
sudo umount /mnt/rootfs_mount

# 方案 B:打包为 initramfs (cpio 格式,全部加载到内存,启动极快,但不持久化)
# cd $ROOTFS_DIR && sudo find . | sudo cpio -H newc -o | gzip -9 > ../initramfs-bt-test.cpio.gz && cd ..

准备最新测试内核

获取最新内核源码

# 克隆 Linux 主线 (Mainline) 或者克隆蓝牙子系统的开发树 (bluetooth-next,包含最新的蓝牙特性),或者stable分支都行
# 这里以主线为例
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

配置并编译内核(开启虚拟蓝牙支持)
在宿主机上编译内核。为了进行虚拟蓝牙测试,必须确保开启 vhci 相关配置。

# 1. 使用当前系统的配置作为基础(或者使用 defconfig)
make x86_64_defconfig

# 2. 使用 menuconfig 或直接修改 .config,确保以下蓝牙选项被开启:
# 我这里蓝牙相关的配置基本上全开了,都打上的y
# CONFIG_BT=y
# CONFIG_BT_BREDR=y
# CONFIG_BT_LE=y
# CONFIG_BT_HCIVHCI=y    <-- 核心:虚拟主机控制器接口
# CONFIG_BT_DEBUGFS=y    <-- 建议开启:用于通过 debugfs 调试蓝牙状态
# CONFIG_BT_SELFTEST=y   <-- 建议开启:内核启动时自动运行蓝牙基础自检

# 快捷开启方法(直接追加到 .config):
./scripts/config --enable CONFIG_BT_HCIVHCI
./scripts/config --enable CONFIG_BT_DEBUGFS

# 3. 编译内核和模块 (利用多核加速)
make -j$(nproc) bzImage modules

阶段 5:在 QEMU 中启动与验证

启动

现在,你拥有了一个包含“核外”最新蓝牙测试环境的极简 Rootfs。结合前文的“最新内核”测试方案,启动 QEMU:

# 假设你编译的最新内核在 /path/to/linux/arch/x86/boot/bzImage
# 假设你打包的 ext4 镜像在 ~/bt_test_rootfs_build/debian_bt_test.ext4.img

qemu-system-x86_64 \
  -name "Minimal_BT_Test" \
  -machine q35,accel=kvm \
  -cpu host \
  -m 1024 \
  -smp 2 \
  -kernel /path/to/linux/arch/x86/boot/bzImage \
  -drive file=debian_bt_test.ext4.img,format=raw,if=virtio \
  -append "root=/dev/vda rw console=ttyS0 earlyprintk=serial,ttyS0,115200" \
  -nographic \
  -netdev user,id=net0,hostfwd=tcp::2222-:22 \
  -device virtio-net-pci,netdev=net0

验证虚拟蓝牙环境

进入 QEMU 终端(或 SSH 进入 ssh -p 2222 root@localhost)后,执行以下验证:

# 1. 确认内核版本是最新的
uname -r

# 2. 确认加载了虚拟蓝牙控制器
modprobe vhci_hci
ls -l /dev/vhci

# 3. 确认 bluetoothd 正在运行
systemctl status bluetooth
bluetoothctl --version  # 检查版本号是否与源码编译的一致

# 4. 启动核外虚拟外设工具
cd ~/bluez
./emulator/btvirt -l2 &  # 创建 2 个虚拟 LE 设备

# 5. 使用 bluetoothctl 扫描并连接
bluetoothctl
[bluetooth]# power on
[bluetooth]# scan on
# 此时应该能看到 btvirt 创建的虚拟设备 MAC 地址

问题和优化

报错

./emulator/btvirt -B -l2不报错,./emulator/btvirt -L -l2报错:

Bluetooth: hci0: Opcode 0x0c03 failed: -110
Failed to open Virtual HCI device

跟踪分析代码,btdev_create(btdev.c)中bt_crypto_new失败
检查内核密码相关的配置,特别是CONFIG_CRYPTO_USER_API*

CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_AEAD=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_CCM
CONFIG_CRYPTO_CMAC
CONFIG_CRYPTO_ECB

进阶优化

CI/CD 自动化进阶优化,Docker 化构建过程:将上述 debootstrap 和 chroot 编译的过程封装在一个 Dockerfile 中。在 CI 的宿主机上运行 Docker 容器生成 ext4 镜像,然后提取出来给 QEMU 使用。这样可以保证构建环境的绝对一致性。