Mac下进入网课直播间软件和系统组件卡死,经排查发现问题在万能声卡驱动VoodooHDA,开始研究通过AppleALC原生注入声卡驱动
感谢黑果小兵的教程
分析
我的设备是台式机,有四个显卡输出,两个音频线输出,显卡输出已经有了,但是我没有自带音箱的显示屏,音频输出需要依靠一前一后两个音频输出,后面接音箱,前面接耳机
通过Ubuntu提取关键信息
这里使用Ubuntu19.04提取Code/acpi,并找到有效节点
做成系统启动u盘之后,开机选择启动项,用livecd(不用安装)启动系统
这样启动的系统root密码为空,可以用sudo passwd root
来设置密码
提取Codec/acpi
组合键CTRL+ALT+t
打开终端
cd ~/Desktop/ # 进入用户桌面
cp /proc/asound/card0/codec* . # 将codec开头的文件复制到当时位置
sudo cp -R /sys/firmware/acpi/tables . # 将acpi/tables目录复制到当时位置,tables目录包括了全部的DSDT和SSDT
ll # 列表
sudo chown -R ubuntu:ubuntu * # 将当前目录下所有文件及目录所有人修改为ubuntu
ll # 列表
找出有效节点
终端输入dmesg | grep snd_hda_codec_realtek
结果如下
ubuntu@ubuntu:~$ dmesg | grep snd_hda_codec_realtek
[ 19.282672] snd_hda_codec_realtek hdaudioC0D0: autoconfig for ALC671: line_outs=1 (0x14/0x0/0x0/0x0/0x0) type:line
[ 19.282673] snd_hda_codec_realtek hdaudioC0D0: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
[ 19.282674] snd_hda_codec_realtek hdaudioC0D0: hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
[ 19.282675] snd_hda_codec_realtek hdaudioC0D0: mono: mono_out=0x0
[ 19.282675] snd_hda_codec_realtek hdaudioC0D0: inputs:
[ 19.282676] snd_hda_codec_realtek hdaudioC0D0: Mic=0x18
[ 19.282676] snd_hda_codec_realtek hdaudioC0D0: Line=0x1b
经过整理,有效节点为
- 0x14 Speakerout
- 0x21 HP out
- 0x18 Mic in
- 0x1b Line in
这种方法比在Mac下通过verbit.sh codec#0
提取信息再整理有效节点方便得多,也不会出错:
注意这里Address: 0,后面会用上
user$./verbit.sh codec#0
Verbs from Linux Codec Dump File: codec#0
Codec: Realtek ALC671 Address: 0 DevID: 283903601 (0x10ec0671)
Jack Color Description Node PinDefault Original Verbs
--------------------------------------------------------------------------------------------------------
Unknown Unknown Line Out at Ext N/A 18 0x12 0x40000000 01271c00 01271d00 01271e00 01271f40
1/8 Green Line Out at Ext Rear 20 0x14 0x01014010 01471c10 01471d40 01471e01 01471f01
1/8 Black Speaker at Ext Rear 23 0x17 0x411111f0 01771cf0 01771d11 01771e11 01771f41
Mic at Ext Rear 0x18 0x18 27365440 01871c40 01871d90 01871ea1 01871f01
1/8 Black Speaker at Ext Rear 25 0x19 0x411111f0 01971cf0 01971d11 01971e11 01971f41
1/8 Black Speaker at Ext Rear 26 0x1a 0x411111f0 01a71cf0 01a71d11 01a71e11 01a71f41
Line In at Ext Rear 0x1b 0x1b 25243696 01b71c30 01b71d30 01b71e81 01b71f01
ATAPI Green SPDIF Out at Ext N/A 29 0x1d 0x40434601 01d71c01 01d71d46 01d71e43 01d71f40
1/8 Black Speaker at Ext Rear 30 0x1e 0x411111f0 01e71cf0 01e71d11 01e71e11 01e71f41
1/8 Black HP Out at Ext Front 33 0x21 0x02211020 02171c20 02171d10 02171e21 02171f02
--------------------------------------------------------------------------------------------------------
Jack Color Description Node PinDefault Modified Verbs
--------------------------------------------------------------------------------------------------------
Unknown Unknown Line Out at Ext N/A 18 0x12 0x40000000 01271c00 01271d00 01271e00 01271f40
1/8 Green Line Out at Ext Rear 20 0x14 0x01014010 01471c50 01471d40 01471e01 01471f01
Mic at Ext Rear 0x18 0x18 27365440 01871c40 01871d90 01871ea1 01871f01
Line In at Ext Rear 0x1b 0x1b 25243696 01b71c30 01b71d30 01b71e81 01b71f01
ATAPI Green SPDIF Out at Ext N/A 29 0x1d 0x40434601 01d71c60 01d71d40 01d71e43 01d71f40
1/8 Black HP Out at Ext Front 33 0x21 0x02211020 02171c20 02171d10 02171e21 02171f01
--------------------------------------------------------------------------------------------------------
Modified Verbs in One Line: 01271c00 01271d00 01271e00 01271f40 01471c50 01471d40 01471e01 01471f01 01871c40 01871d90 01871ea1 01871f01 01b71c30 01b71d30 01b71e81 01b71f01 01d71c60 01d71d40 01d71e43 01d71f40 02171c20 02171d10 02171e21 02171f01
--------------------------------------------------------------------------------------------------------
整理有效路径
先把之前的数据整理成表格
有效节点 | 10进制 | 设备名称 |
---|---|---|
0x14 | 20 | Speakerout |
0x21 | 33 | HP out |
0x18 | 24 | Mic in |
0x1b | 27 | Line in |
生成路径图
使用codecgraph生成pathmap图
# 准备codecgraph命令
brew install graphviz
graphviz环境两天没下载成功,只好寻找其他解决办法,还真有
getdump获取节点
gitdump是万能声卡驱动VoodooHDA自带的程序
sudo cp ~/Downloads/getdump /usr/local/bin # 将getdump命令复制到/usr/local/bin目录下
sudo chmod +x /usr/local/bin/getdump # 为getdump添加执行权限
getdump > ~/Desktop/voodoo_dump.txt
用它可以生成一份voodoo_dump.txt
的文件,里面会有两段以DUMPING Playback/Record Paths
开头的文字描述,这里面即包括了有效节点,同时也包括了有效的路径,问题迎刃而解
+-------------------------------+
| DUMPING Playback/Record Paths |
+-------------------------------+
Playback:
nid=33 [pin: Headphones (Black Front)]
|
+ <- nid=13 [audio mixer] [src: mix] bindSeq=00000001
|
+ <- nid=3 [audio output] [src: pcm] bindSeq=00000001
Record:
nid=9 [audio input]
|
+ <- nid=34 [audio selector] [src: speaker, mic] bindSeq=00000001
|
+ <- nid=24 [pin: Microphone (Pink Rear)] [src: mic] bindSeq=00000001
+ <- nid=29 [beep widget]
有效节点 | 10进制 | 设备名称 | 路径 |
---|---|---|---|
0x21 | 33 | HP out | 33->13->3 |
+-------------------------------+
| DUMPING Playback/Record Paths |
+-------------------------------+
Playback:
nid=20 [pin: Line-out (Green Rear)]
|
+ <- nid=12 [audio mixer] [src: mix] bindSeq=00000001
|
+ <- nid=2 [audio output] [src: pcm] bindSeq=00000001
Record:
nid=8 [audio input]
|
+ <- nid=35 [audio mixer] [src: mix] bindSeq=00000001
|
+ <- nid=27 [pin: Line-in (Blue Rear)] [src: line] bindSeq=00000001
+ <- nid=29 [beep widget]
Input Mix:
nid=12 [audio mixer]
|
+ <- nid=2 [audio output] [src: pcm] bindSeq=00000001
nid=13 [audio mixer]
|
+ <- nid=3 [audio output] [src: pcm] bindSeq=00000001
nid=35 [audio mixer]
|
+ <- nid=27 [pin: Line-in (Blue Rear)] [src: line] bindSeq=00000001
+ <- nid=29 [beep widget]
有效节点 | 10进制 | 设备名称 | 路径 |
---|---|---|---|
0x14 | 20 | Speakerout | 20->12->2 |
这里会发现没有记录麦克风节点,其实这台电脑前面的(Black Front)应该是输入输出二合一接口,但Ubuntu没有识别到麦克风,再加上我没有麦克,暂时不搞了
整理ConfigData
查看驱动中的
我用PlistEdit pro
打开PinConfigs.kext
里的info.plist
中搜索671,找到两组数据,复制这两组中ConfigData
一栏的数据
LayoutID:1201871C20 01871D30 01871E81 01871F01 02171C30 02171D40 02171E01 02171F01 02170C02
LayoutID:1521771C10 21771D00 21771E13 21771F90 21471C20 21471D10 21471E21 21471F02 21470C02 22171C30 22171D40 22171E11 22171F91 22170C02 21971C50 21971D10 21971E81 21971F02 21871C60 21871D30 21871E81 21871F01
整理一下
12
01871C20 01871D30 01871E81 01871F01
02171C30 02171D40 02171E01 02171F01 02170C02
节点为0x18 0x21
15
21771C10 21771D00 21771E13 21771F90 21471C20 21471D10 21471E21 21471F02 21470C02
22171C30 22171D40 22171E11 22171F91 22170C02
21971C50 21971D10 21971E81 21971F02
21871C60 21871D30 21871E81 21871F01
节点为0x21 0x22 0x21 0x21
怪不得注入这两个id声卡没反应,原来这俩和我们的情况不一样
提取并整理自己的
整理格式
翻出之前的ALC671_dump.txt
整理一下格式
- [Fixed]是内部设备
- [Jack]是通过插孔进行连接的外部设备
- [N/A]是其它未知设备
0x411111f0
是名字后面带N/A
的是[N/A],因为是台式机没有内部设备,剩下的是[Jack]。
两个Jack设备刚好和之前整理的表格对上了
Jack Color Description Node PinDefault
-------------------------------------------------------------------
Unknown Unknown [N/A] Line Out 18 0x12 0x40000000
1/8 Green [Jack] Line Out 20 0x14 0x01014010
1/8 Black [N/A] Speaker at Ext Rear 23 0x17 0x411111f0
1/8 Black [N/A] Speaker at Ext Rear 25 0x19 0x411111f0
1/8 Black [N/A] Speaker at Ext Rear 26 0x1a 0x411111f0
ATAPI Green [N/A] SPDIF Out at Ext N/A 29 0x1d 0x40434601
1/8 Black [N/A] Speaker at Ext Rear 30 0x1e 0x411111f0
1/8 Black [Jack] HP Out 33 0x21 0x02211020
-------------------------------------------------------------------
将PinDefault
进行小端转换
把 0x40000000拆成 0x 40 00 00 00,去掉0x再调换顺序即可
Node | c d e f | Description |
---|---|---|
12 | 00 00 00 40 | [N/A] Line Out |
14 | 10 40 01 01 | [Jack] Line Out |
17 | f0 11 11 41 | [N/A] Speaker at Ext Rear |
19 | f0 11 11 41 | [N/A] Speaker at Ext Rear |
1a | f0 11 11 41 | [N/A] Speaker at Ext Rear |
1d | 01 46 43 40 | [N/A] SPDIF Out at Ext N/A |
1e | f0 11 11 41 | [N/A] Speaker at Ext Rear |
21 | 20 10 21 02 | [Jack] HP Out |
修正数据
然后修正数据,让它看起来更Apple
首先[N/A]都当成无效节点,按照Apple
的规范,使用f0 00 00 40
来屏蔽
Node | c d e f | Description |
---|---|---|
12 | f0 00 00 40 | [N/A] Line Out |
14 | 10 40 01 01 | [Jack] Line Out |
17 | f0 00 00 40 | [N/A] Speaker at Ext Rear |
19 | f0 00 00 40 | [N/A] Speaker at Ext Rear |
1a | f0 00 00 40 | [N/A] Speaker at Ext Rear |
1d | f0 00 00 40 | [N/A] SPDIF Out at Ext N/A |
1e | f0 00 00 40 | [N/A] Speaker at Ext Rear |
21 | 20 10 21 02 | [Jack] HP Out |
整理数据
最终ConfigData
的计算公式为:
Final Config:
Address + Node + 71c +【c】
Address + Node + 71d +【d】
Address + Node + 71e +【e】
Address + Node + 71f +【f】
整理出来之后
01271cf0 01271d00 01271e00 01271f40
01471c10 01471d40 01471e01 01471f01
01771cf0 01771d00 01771e00 01771f40
01971cf0 01971d00 01971e00 01971f40
01a71cf0 01a71d00 01a71e00 01a71f40
01d71cf0 01d71d00 01d71e00 01d71f40
01e71cf0 01e71d00 01e71e00 01e71f40
02171c20 02171d10 02171e21 02171f02 02170c02
可以发现最后一行多了一段,因为
具有
EAPD
的节点需要添加参数SET_EAPD_BTLENABLE
,转换成数值为0x70c
,完整的数值为:Address
+节点
+70c
+02
,即:01470c02
,它通过hda-verb
可以执行,比如CodecCommander
就是调用的hda-verb
执行的命令.
一个简单判断EAPD
节点的方法:那就是它通常会位于Speaker Out
和HP Out
这两个输出节点上.至于其它教程提到过的关于01470c02
是组神奇的代码,可以让外放发声的说法是错误的,它可能刚好声卡的Speaker Out
的输出节点是0x14
而已.如果您的Speaker Out
输出节点是0x16
,那么就需要把它修改为01670c02
,当然要遵守这个公式:Address
+节点
+71c
+02
去掉格式,数据整理成最终的01271cf0 01271d00 01271e00 01271f40 01471c10 01471d40 01471e01 01471f01 01771cf0 01771d00 01771e00 01771f40 01971cf0 01971d00 01971e00 01971f40 01a71cf0 01a71d00 01a71e00 01a71f40 01d71cf0 01d71d00 01d71e00 01d71f40 01e71cf0 01e71d00 01e71e00 01e71f40 02171c20 02171d10 02171e21 02171f02 02170c02
2020-2-28-00:55未完待续
2020-3-3-22:03
使用USB声卡解决问题