1. ALSA架构概述

ALSA(Advanced Linux Sound Architecture)是 Linux 内核中负责音频设备驱动与管理的标准子系统。自 Linux 2.6 内核起,ALSA 取代了旧有的 OSS(Open Sound System),成为主线音频框架。理解 ALSA 在系统中的位置、用户态与内核态的分层协作,以及核心组件的职责,是后续进行驱动移植与 Kconfig 裁剪的基础。

1.1 ALSA 在 Linux 音频子系统中的位置

在完整的 Linux 音频软件栈中,ALSA 处于承上启下的核心层:

  • 硬件层:I2S、PCM、AC97、HDMI/DP 等音频接口控制器与 Codec 芯片。
  • 内核层(ALSA 核心):提供标准字符设备接口、PCM 数据路径、控制通道、定时器、MIDI 等抽象。
  • 用户空间层:应用通过 ALSA lib(libasound)或直接操作 /dev/snd/* 设备节点与内核交互。
  • 上层框架:PulseAudio、PipeWire、JACK 等音频服务器基于 ALSA lib 构建,提供混音、路由、低延迟等高级功能。
关键认知: 嵌入式系统中,ALSA 直接管理硬件寄存器与 DMA 传输,不依赖中间层音频服务器。驱动移植的核心工作就在 ALSA 内核层。
ALSA 在 Linux 音频软件栈中的位置 Linux 音频软件栈分层 硬件层:I2S / PCM / AC97 / HDMI 接口 + Codec 芯片 内核层:ALSA 核心子系统 snd | snd-pcm | snd-control | snd-timer | snd-midi 用户空间:ALSA lib (libasound) / /dev/snd/* 上层音频服务:PulseAudio / PipeWire / JACK 应用层:播放器 / 录音 / VoIP / 游戏

1.2 用户空间与内核空间的分层

ALSA 采用典型的 Unix 字符设备模型,将音频硬件抽象为文件描述符,用户空间通过 open()、read()、write()、ioctl()、mmap() 等系统调用与内核驱动通信。分层设计带来以下优势:

空间 组件 职责 关键接口/文件
用户空间 ALSA lib (libasound) 提供 API 封装、PCM 配置、插件机制、混音 /usr/lib/libasound.so
用户空间 设备节点 字符设备访问入口 /dev/snd/pcmC0D0p、/dev/snd/controlC0
内核空间 ALSA 核心 (snd) 设备管理、proc 文件系统、DMA 内存管理 /proc/asound/
内核空间 PCM 中间层 (snd-pcm) PCM 设备注册、DMA 缓冲区管理、运行时配置 struct snd_pcm、snd_pcm_ops
内核空间 Control 中间层 (snd-control) 混音器、音量、开关等控制通路 struct snd_kcontrol、snd_ctl_ops
内核空间 硬件驱动层 操作具体 SoC 音频接口与 Codec 寄存器 struct snd_soc_dai_driver、struct snd_soc_codec_driver
嵌入式移植要点: 驱动开发者主要工作在内核空间,尤其是硬件驱动层与 PCM/Control 中间层的回调函数实现。用户空间的 ALSA lib 通常不需要修改,但需要确保内核配置正确导出设备节点。

1.3 核心组件介绍

ALSA 内核子系统由多个模块化组件构成,通过 Kconfig 和 Makefile 组织编译。以下三个组件是所有音频驱动的基础:

1.3.1 snd — ALSA 核心框架

  • 功能:提供设备注册/注销、proc 文件系统(/proc/asound/)、DMA 内存分配、中断管理、日志等基础设施。
  • Kconfig 符号:CONFIG_SND
  • 依赖:通常需要 CONFIG_SND_TIMER 提供定时器支持。
  • 裁剪原则:CONFIG_SND 必须开启,否则整个 ALSA 子系统不可用。

1.3.2 snd-pcm — PCM 设备中间层

  • 功能:管理 PCM 播放/捕获设备的注册、DMA 缓冲区分配、运行时参数协商(采样率、格式、通道数)、mmap 映射。
  • Kconfig 符号:CONFIG_SND_PCM
  • 数据结构:struct snd_pcm 表示一个 PCM 设备,struct snd_pcm_substream 表示一个数据流方向(播放或录音)。
  • 裁剪原则:如果系统只需要播放(如智能音箱),可只注册 playback substream;纯录音设备可只注册 capture substream。

1.3.3 snd-control — Control 设备中间层

  • 功能:提供混音器通路、音量控制、开关、枚举选择等用户可调节参数。
  • Kconfig 符号:CONFIG_SND_CTL
  • 数据结构:struct snd_kcontrol 表示一个控制项,通过 snd_ctl_add() 注册到声卡。
  • 裁剪原则:如果硬件没有可调节的增益/混音通路(如纯数字 HDMI 音频),可以裁剪 CONFIG_SND_CTL 以减小内核体积。
ALSA 核心组件关系图 ALSA 核心组件与依赖关系 用户空间应用 / ALSA lib 内核空间 snd (核心框架) CONFIG_SND snd-pcm CONFIG_SND_PCM snd-control CONFIG_SND_CTL 硬件驱动层:SoC DAI / Codec / DMA 引擎 说明:snd-pcm 和 snd-control 都依赖于 snd 核心框架,硬件驱动层实现具体的回调函数

1.4 设备节点与访问方式

当 ALSA 驱动加载成功后,会在 /dev/snd/ 目录下创建设备节点。典型的设备节点包括:

# 查看声卡 0 的设备节点
ls -l /dev/snd/
crw-rw---- 1 root audio 116,  0 Jan  1 00:00 controlC0   # 控制设备
crw-rw---- 1 root audio 116,  4 Jan  1 00:00 pcmC0D0p    # 声卡0, 设备0, 播放
crw-rw---- 1 root audio 116,  5 Jan  1 00:00 pcmC0D0c    # 声卡0, 设备0, 捕获
crw-rw---- 1 root audio 116,  1 Jan  1 00:00 seq         # 音序器
crw-rw---- 1 root audio 116,  2 Jan  1 00:00 timer       # 定时器

设备节点命名规则:pcmC<card>D<device><方向>,其中 p 表示 playback(播放),c 表示 capture(捕获)。主设备号 116 由 ALSA 核心统一分配。

常见问题: 嵌入式系统如果未创建 /dev/snd/ 目录或节点权限不正确,应用层将无法打开音频设备。需确保 udev/mdev 规则正确,或手动 mknod 创建设备节点。

1.5 本章小结

ALSA 是 Linux 音频驱动的标准框架,采用用户空间/内核空间分层设计。核心组件 snd、snd-pcm、snd-control 分别提供基础框架、PCM 数据流和控制通路管理。在嵌入式驱动移植中,开发者需要重点关注内核空间硬件驱动层的实现,并根据实际硬件功能通过 Kconfig 合理裁剪组件,以平衡功能与内核体积。