3、开发环境搭建:Linux内核源码获取、编译内核并开启ALSA支持、安装alsa-lib和alsa-utils、搭建QEMU模拟环境

好,咱们正式开始动手了。这一章我带你搭一套完整的ALSA开发环境。说实话,环境搭好了,后面的事就顺了。我见过太多新手卡在这一步,不是内核编不过,就是QEMU起不来。别急,咱们一步步来。

3.1 获取Linux内核源码

我个人习惯用主线内核,因为ALSA驱动更新快,bug修得也勤。你可以在 kernel.org 下载,或者直接用git拉取。

# 用git拉取主线内核,大概1-2GB,耐心等
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

嗯,这里要注意:如果你网络不好,可以只拉取最新tag,省时间。

git clone --depth=1 --branch v6.6 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

我曾经在某个项目里,因为内核版本太老,ALSA的某个API已经废弃了,折腾了两天才发现。所以,尽量用新内核。

3.2 编译内核并开启ALSA支持

内核源码拿到了,接下来就是配置和编译。ALSA支持默认是开启的,但有些子模块需要手动勾上。

3.2.1 配置内核

运行 make menuconfig,进入配置界面。你想想看,这就像搭积木,你需要什么就勾什么。

make menuconfig

找到以下路径,确保这些选项是开启的([*] 或 <M>):

配置项 路径 说明
CONFIG_SOUND Device Drivers → Sound card support 总开关,必须开启
CONFIG_SND Device Drivers → Sound card support → Advanced Linux Sound Architecture ALSA核心,必须开启
CONFIG_SND_PCI Device Drivers → Sound card support → PCI sound devices 如果你用PCI声卡,勾上
CONFIG_SND_USB_AUDIO Device Drivers → Sound card support → USB sound devices USB音频设备支持,调试常用
CONFIG_SND_DEBUG Device Drivers → Sound card support → ALSA for sound card → Debug 调试信息,开发必开

重要: 开发阶段建议把 CONFIG_SND_DEBUG 和 CONFIG_SND_VERBOSE_PRINTK 都打开。这样驱动打印的日志会更详细,方便定位问题。

3.2.2 编译内核

配置好了,开始编译。我建议用多线程,省时间。

make -j$(nproc)

第一次编译大概要20-40分钟,取决于你的机器。你可以去泡杯咖啡。编译完成后,内核镜像在 arch/x86/boot/bzImage。

小技巧: 如果你只修改了ALSA相关的代码,可以用 make -j$(nproc) modules 只编译模块,然后 make modules_install 安装。这样比全量编译快得多。

3.3 安装alsa-lib和alsa-utils

内核搞定了,但用户空间也得有工具配合。alsa-lib 提供API,alsa-utils 提供命令行工具,比如 aplay、arecord、amixer 这些。

3.3.1 安装方式

在Ubuntu/Debian上,直接apt安装:

sudo apt-get install alsa-base alsa-utils libasound2-dev

如果你喜欢从源码编译,也可以:

# 下载alsa-lib
git clone git://git.alsa-project.org/alsa-lib.git
cd alsa-lib
autoreconf -i
./configure
make -j$(nproc)
sudo make install

# 下载alsa-utils
git clone git://git.alsa-project.org/alsa-utils.git
cd alsa-utils
autoreconf -i
./configure
make -j$(nproc)
sudo make install

我个人习惯用apt,省事。但如果你要调试alsa-lib本身的问题,那就得源码编译了。

3.3.2 验证安装

装好后,跑一下 aplay -l,看看能不能列出音频设备。

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

如果看到类似输出,说明ALSA用户空间工具已经就绪。

注意: 如果你在QEMU虚拟机里,可能没有物理声卡。别担心,我们接下来会搭建虚拟音频设备。

3.4 搭建QEMU模拟环境

为什么要用QEMU?说白了,就是安全。你写个驱动,万一崩了,不会把宿主机搞死。我在项目中经常先用QEMU验证,没问题了再上真机。

3.4.1 安装QEMU

sudo apt-get install qemu-system-x86

3.4.2 创建根文件系统

QEMU需要根文件系统。你可以用Buildroot或者Debootstrap做一个最小的。

我用Buildroot比较多,因为它简单:

# 下载Buildroot
wget https://buildroot.org/downloads/buildroot-2024.02.tar.gz
tar -xzf buildroot-2024.02.tar.gz
cd buildroot-2024.02

# 配置
make qemu_x86_64_defconfig
make menuconfig

在menuconfig里,确保勾上 Target packages → Audio and video applications → alsa-utils 和 alsa-lib。

make -j$(nproc)

编译完成后,镜像在 output/images/rootfs.ext2。

3.4.3 启动QEMU

有了内核和根文件系统,就可以启动了。

qemu-system-x86_64 \
  -kernel /path/to/linux/arch/x86/boot/bzImage \
  -drive file=/path/to/rootfs.ext2,format=raw \
  -append "root=/dev/sda console=ttyS0" \
  -nographic \
  -soundhw hda

这里 -soundhw hda 是让QEMU模拟一个HDA声卡。你还可以用 -soundhw ac97 模拟AC97声卡。

关键点: 启动后,在QEMU里运行 aplay -l,如果能看到 card 0: Intel [HDA Intel],说明你的ALSA驱动已经加载成功了。这时候你就可以开始写自己的驱动了。

3.4.4 调试小技巧

我曾经在QEMU里调试一个USB音频驱动,发现声音总是断断续续。后来开了 CONFIG_SND_DEBUG,看到一堆 XRUN 日志,才知道是缓冲区太小。嗯,这就是调试信息的重要性。

你可以在QEMU启动参数里加上 -serial stdio,这样内核日志会直接打印到终端,方便观察。

3.5 总结

这一章我们干了三件事:

  • 获取并编译了带ALSA支持的内核
  • 安装了alsa-lib和alsa-utils
  • 搭建了QEMU模拟环境

环境搭好了,下一章我们就可以开始写第一个ALSA驱动了。说实话,看到 aplay -l 列出设备的那一刻,还是挺有成就感的。你试试看。