RK3588 kernel-6.1:sound/core 功能与实现要点
源码基准:/home/work2/SeagullYpcEncode/rk3588/kernel-6.1/sound/core/。
六文件专项(sound.c、init.c、memory.c、control.c、misc.c、device.c)见: rk3588-kernel-6.1-sound-core-sound-init-memory-control-misc-device分析.md。
源码级走读(调用链、状态机、snd_pcm_period_elapsed、compress 状态等)见: rk3588-kernel-6.1-sound-core源码详细分析.md。
此处实现 ALSA 内核通用中层(Core):在用户可见硬件驱动之上、sound/soc、sound/usb、sound/pci 等之下,统一 snd_card、字符设备 minor、ioctl 语义与 PCM/Control 生命周期。公开数据结构:include/sound/*.h(如 core.h、pcm.h、control.h)。
内核文档入口:Documentation/sound/kernel-api/writing-an-alsa-driver.rst。
整机 sound 分层可与 linuxDoc/sound/rk3588-kernel-6.1-sound声卡架构分析.md 对照阅读:彼处偏重 sound/soc + Rockchip;本文只做 sound/core 的文件级拆解。
0. 代码的作用与解决了什么问题
0.1 作用(要解决的核心痛点)
在没有 ALSA Core 时,各家声卡驱动会直接占用 misc/自建字符设备,ioctl、缓冲区生命周期与电源管理 互不兼容。sound/core 解决:
- 统一「声卡」容器:
snd_card(init.c):分配编号、slots参数绑定模块、snd_card_register/free/disconnect与用户可见/proc/asound、/dev/snd/* 挂钩; - 有序挂载子组件:
device.c:snd_device_new按enum snd_device_type(CONTROL、PCM、RAW MIDI…)排序链表,统一dev_register/dev_disconnect/dev_free顺序; - 控制面抽象:
control.c:snd_kcontrol、SNDRV_CTL_IOCTL_*、用户控件与安全max_user_ctl_alloc_size上限; - 数据面 PCM:
pcm*.c+memalloc.c:snd_pcm/substream/runtime、hw/sw params、mmap、ioctl与用户pcm_native路径; - 时间基准:
timer.c、可选hrtimer.c、pcm_timer.c(SND_PCM_TIMER):节拍器 / PCM 定时对齐; - 其它 ALSA 子设备:
rawmidi.c、hwdep.c、compress_offload.c、seq/(序列器)、jack.c/ctljack.c(上报插头)、可选control_led.c; - 观测与调试:
info.c(/proc/asound相关信息,SND_PROC_FS)、pcm_drm_eld.c、pcm_iec958.c; - 历史兼容:
sound_oss.c、oss/目录:/dev/dsp、/dev/mixer等仿真路径; - 入口 glue:
sound.c:全局snd_major、minor 表、打开/dev/snd/*时的snd_lookup_minor_data、模块按需request_module。
0.2 明确解决的工程问题
| 问题 | sound/core 中的典型位置 |
|---|---|
| 多块卡、多 PCM、minor 冲突与索引混乱 | sound.c minor 路由 + snd_cards[] |
热插拔/卸载时仍打开的 /dev/snd/* |
init.c:snd_monitor_file、shutdown_list、断开后再收尾 |
| PCM DMA buffer / coherent / mmap | pcm_memory.c、memalloc.c、memory.c、misc.c |
| SoC DMAEngine 通用 PCM | pcm_dmaengine.c(独立 snd-pcm-dmaengine.o,CONFIG_SND_DMAENGINE_PCM) |
| 虚拟主音量链路(共享控件聚合) | vmaster.c |
| Legacy ISA DMA | isadma.c(CONFIG_ISA_DMA_API) |
1. 顶层 Makefile 产物映射(节选)
来自 sound/core/Makefile:
| 内核对象 | 组成文件(节选) | CONFIG |
|---|---|---|
snd.o |
sound.o、init.o、memory.o、control.o、misc.o、device.o;可选 info[_oss].o、isadma.o、sound_oss.o、vmaster.o、jack/ctljack |
CONFIG_SND |
snd-pcm.o |
pcm.o、pcm_native.o、pcm_lib.o、pcm_misc.o、pcm_memory.o、memalloc.o;可选 pcm_timer、pcm_drm_eld、pcm_iec958 |
CONFIG_SND_PCM |
snd-pcm-dmaengine.o |
pcm_dmaengine.c |
CONFIG_SND_DMAENGINE_PCM |
snd-timer.o |
timer.c(及 timer_compat) |
CONFIG_SND_TIMER |
snd-hrtimer.o |
hrtimer.c |
CONFIG_SND_HRTIMER |
snd-rawmidi.o |
rawmidi.c |
CONFIG_SND_RAWMIDI |
snd-hwdep.o |
hwdep[_compat].c |
CONFIG_SND_HWDEP |
snd-seq-device.o |
seq_device.c |
CONFIG_SND_SEQ_DEVICE |
snd-compress.o |
compress_offload.c |
CONFIG_SND_COMPRESS_OFFLOAD |
oss/、seq/ |
OSS PCM/Mixer、MIDI 序列器全栈 | SND_OSSEMUL、SND_SEQUENCER |
Kconfig 位于 sound/core/Kconfig,细分 PCM IEC958、OSS emulation、compress design(参见 Documentation/sound/designs/*.rst)。
2. 关键源文件职责一览(不含 seq/oss 全部枚举)
| 文件 | 职责概要 |
|---|---|
sound.c |
ALSA 字符设备 major/minor、设备节点查找、snd_request_card |
init.c |
snd_card/snd_cards、slots、监控打开的 file 以防卸下过早释放 |
device.c |
snd_device_*:PCM/control 等设备链表及注册顺序 |
memory.c |
Core 侧内存助手(与 PCM pcm_memory 分工协作) |
misc.c |
各式共用 helper |
control.c |
Mixer/control ioctl、kctl 链表与用户控件限额 |
control_compat.c/control_led.c |
兼容 ioctl、LED 类控件扩展 |
pcm.c |
snd_pcm_new/链表,绑定 snd_device |
pcm_native.c |
面向用户的 PCM ioctl、mmap、poll 主路径 |
pcm_lib.c |
缓冲区、boundary、avail、XRUN、snd_pcm_period_elapsed 等中段逻辑 |
pcm_misc.c |
PCM 杂项 |
pcm_compat.c |
32 位 ioctl 兼容 |
pcm_timer.c |
PCM 关联 snd_timer |
timer.c |
内核节拍定时器抽象(兼容代码通过 #include "timer_compat.c" 并入) |
hrtimer.c |
高精度定时后端 |
rawmidi.c |
原始 MIDI 流 |
hwdep.c |
硬件依赖 / FW loader / vendor ioctl 通道 |
compress_offload.c |
压缩音频 offload(Documentation/sound/designs/compress-offload.rst) |
info.c、info_oss.c |
/proc/asound 相关信息 |
jack.c、ctljack.c |
声学插头开关与用户控件映射 |
seq/ |
ALSA Sequencer:端口、队列、FIFO、dummy、synth、seq/oss 兼容 |
3. 子目录 seq/ 与 oss/
seq/:MIDI 与时间驱动的序列协议栈(内核 sequencer)。依赖CONFIG_SND_SEQUENCER(上层sound/core/Makefile引入)。oss/oss:/dev/dsp、mixer、seq仿真(设计:Documentation/sound/designs/oss-emulation.rst)。
二者与现代 PulseAudio/PipeWire 经由 ALSA lib 的路径并行存在:BSP 常按需裁剪 OSS。
4. 与 RK3588 的关系
凡 CONFIG_SND=y(RK BSP 典型),snd-* 核心模块即会被链接或模块化;Rockchip ASoC(sound/soc/rockchip/*) 最终在 snd_card_register() 前后通过这些 Core API 暴露 PCM/control。调试 aplay -l、amixer 所见节点,背后均由 sound/core 的 snd_pcm_*、snd_ctl_* 与 /dev/snd/* minor 管理支撑。
5. 小结
sound/core 提供 ALSA 「一张卡 + 多子设备 + 统一字符接口」 的中层实现:PCM 负责音频样本路径,control 负责配置与通知,timer/rawmidi/hwdep/compress/seq 覆盖附属能力,OSS 维持旧 API。RK3588 音频驱动开发主要工作在 sound/soc,但理解 sound/core 才能理清 snd_pcm_open → ops → DMA 与 snd_ctl_notify 的全链路。
正在加载留言…