feios
文章18
字数23.9k
分类4
使用AppleALC自制声卡驱动

使用AppleALC自制声卡驱动

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:12
01871C20 01871D30 01871E81 01871F01 02171C30 02171D40 02171E01 02171F01 02170C02

LayoutID:15
21771C10 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 OutHP 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声卡解决问题