问题现象

一台安装 Arch Linux 的 MacBook 在系统升级后再次出现内置扬声器无声的问题。系统中声卡设备仍然可以被识别,aplay -l 能看到 Intel HDA PCH 与 CS8409 相关设备,但实际没有声音输出。

这类问题容易被误判为 PipeWire、PulseAudio、ALSA 音量或桌面环境设置问题。但本次排查后确认,根本原因并不在用户层音频服务,而是在内核声卡驱动模块。

硬件与驱动背景

部分 MacBook 使用 Cirrus Logic CS8409 相关音频芯片,实际音频路径还涉及 CS42L83 codec。Linux 内核自带的 snd-hda-codec-cs8409 模块虽然可以识别声卡设备,但对某些 MacBook 的内置扬声器路径支持并不完整。

因此,这类机器通常需要使用 snd_hda_macbookpro 项目提供的修正版 DKMS 驱动。该驱动会覆盖或优先于内核自带的 snd-hda-codec-cs8409 模块,从而让内置声卡正常工作。

初始检查

系统升级后,首先检查当前内核版本、headers、DKMS 状态和声卡模块路径:

uname -r
pacman -Q linux linux-headers dkms
ls -ld /usr/lib/modules/$(uname -r)/build
dkms status
modinfo -n snd-hda-codec-cs8409
aplay -l
lsmod | grep -E 'snd_hda|cs8409|cirrus'

其中最关键的是:

modinfo -n snd-hda-codec-cs8409

如果输出类似:

/lib/modules/当前内核版本/kernel/sound/hda/codecs/cirrus/snd-hda-codec-cs8409.ko.zst

说明系统正在使用内核自带的原始模块。

正确状态应该类似:

/lib/modules/当前内核版本/updates/dkms/snd-hda-codec-cs8409.ko.zst

updates/dkms 表示当前加载的是 DKMS 安装的修正版模块。

问题原因

本次无声的直接原因是:

系统升级到新内核后,snd_hda_macbookpro 对应的 DKMS 模块没有自动重新安装到当前内核中,导致系统退回加载了内核自带的原始 snd-hda-codec-cs8409 模块。

也就是说,声卡设备本身没有消失,ALSA 也能枚举到设备,但当前模块并不是适合这台 MacBook 的修正版模块。

问题链条可以概括为:

系统升级
  ↓
当前内核版本变化
  ↓
DKMS 修正版声卡模块没有安装到新内核
  ↓
系统加载内核自带的 snd-hda-codec-cs8409
  ↓
声卡能被识别,但 codec / 扬声器路径初始化不完整
  ↓
内置扬声器无声

修复过程

如果之前已经拉取过 snd_hda_macbookpro 源码,可以直接进入源码目录:

cd ~/workspace/snd_hda_macbookpro
git pull

然后先尝试移除旧安装:

sudo ./install.cirrus.driver.sh -r || true

如果出现类似提示:

Error! The module/version combo: snd_hda_macbookpro/0.1 is not located in the DKMS tree.
removed /usr/src/snd_hda_macbookpro-0.1

这并不一定是严重错误。它通常表示 DKMS 树中本来就没有该模块记录,但旧的 /usr/src 源码目录已被清理。接下来继续安装即可。

执行安装:

sudo ./install.cirrus.driver.sh -i
sudo depmod -a

成功时会看到类似输出:

Creating symlink /var/lib/dkms/snd_hda_macbookpro/0.1/source -> /usr/src/snd_hda_macbookpro-0.1
Building module(s).... done.
Installing /usr/lib/modules/当前内核版本/updates/dkms/snd-hda-codec-cs8409.ko.zst
Running depmod.... done.

然后检查 DKMS 状态:

dkms status

成功状态类似:

snd_hda_macbookpro/0.1, 当前内核版本, x86_64: installed (Original modules exist)

这里的 Original modules exist 不必紧张,它只是表示原始内核模块仍然存在。DKMS 安装的模块位于 updates/dkms,会以更高优先级生效。

继续确认模块路径:

modinfo -n snd-hda-codec-cs8409

正确结果应类似:

/lib/modules/当前内核版本/updates/dkms/snd-hda-codec-cs8409.ko.zst

确认后重启:

reboot

重启后的确认

重启后再次执行:

modinfo -n snd-hda-codec-cs8409
dkms status
aplay -l
lsmod | grep -E 'snd_hda|cs8409|cirrus'

修复前,aplay -l 中设备可能显示为:

CS8409 Analog

修复后,设备名称可能变为:

CS8409/CS42L83 Analog

这个变化很重要。它说明修正版驱动已经正确识别到 CS42L83 相关 codec,而不仅仅是识别到一个泛化的 CS8409 设备。

此时如果声音恢复,就说明问题已经解决。

ALSA 层测试

如果 DKMS 模块路径已经正确,但仍然没有声音,可以进一步测试 ALSA 层:

speaker-test -D hw:1,0 -c2 -t wav

如果需要检查静音状态:

alsamixer -c 1

alsamixer 中,如果底部显示 MM,表示该通道被静音。可以按 m 取消静音,并用方向键调整音量。

如果 speaker-test 有声音,而浏览器或播放器没有声音,再去检查 PipeWire、PulseAudio 或桌面环境输出设备设置。

后续维护方法

这类问题在内核升级后可能再次出现。以后如果升级系统后 MacBook 内置声卡又无声,可以优先执行:

modinfo -n snd-hda-codec-cs8409
dkms status

如果模块路径从:

updates/dkms

退回到:

kernel/sound/hda/codecs/cirrus

就基本可以判断是同一个问题。

常用恢复流程如下:

cd ~/workspace/snd_hda_macbookpro
git pull
sudo ./install.cirrus.driver.sh -r || true
sudo ./install.cirrus.driver.sh -i
sudo depmod -a
reboot

重启后再确认:

modinfo -n snd-hda-codec-cs8409
dkms status
aplay -l

只要 modinfo -n snd-hda-codec-cs8409 指向 updates/dkms,驱动层通常就是正确的。

总结

这次无声并不是声卡硬件故障,也不是简单的音量设置问题,而是内核升级后 DKMS 修正版声卡驱动没有正确接管当前内核模块。

问题的关键判断标准是:

modinfo -n snd-hda-codec-cs8409

如果路径位于:

kernel/sound/hda/codecs/cirrus

说明正在使用内核自带模块。

如果路径位于:

updates/dkms

说明正在使用 DKMS 修正版模块。

对于使用 CS8409 / CS42L83 声卡方案的 MacBook 来说,后者才是内置扬声器正常工作的关键。

Leave a Reply

Your email address will not be published. Required fields are marked *