修复 Legion Y9000X 2022 IAH7 内置扬声器在 Linux 下无声音的问题

  1. 1. 免责声明
  2. 2. 检查错误
  3. 3. 修补问题
    1. 3.1. 查找 Subsystem ID
    2. 3.2. 制作 Patch (v1)
      1. 3.2.1. 修改 sound/pci/hda/patch_realtek.c
      2. 3.2.2. 修改 sound/pci/hda/patch_realtek.c
      3. 3.2.3. 生成补丁文件 sound_17aa386e_fix.patch
    3. 3.3. 制作 Patch (v2)
      1. 3.3.1. 问题分析
      2. 3.3.2. 问题解决
      3. 3.3.3. 补丁文件 sound_17aa386e_fix.patch
    4. 3.4. 制作 Patch (v3)
      1. 3.4.1. 修改日志
      2. 3.4.2. 补丁文件 sound_17aa386e_fix.patch
    5. 3.5. 构建内核
    6. 3.6. 安装内核
    7. 3.7. 重启
  4. 4. 注意事项
  5. 5. 参考资料
  6. 6. 另记

对于拯救者 Y9000X 2022 用户,在安装 sof-firmware 后,尽管内置麦克风工作正常,但无法通过内置扬声器播放声音。本文尝试简单修补 Linux 内核,以避免残缺 ACPI 表带来的参数缺失,正确驱动 CS35L4L 音频放大器。

本文假定您使用 Arch Linux 和 linux-v6.8.5-arch1 内核,尽管您可以参考其过程 backport 到其它内核版本/发行版。

免责声明

由于作者并不了解 Linux 内核开发,纯粹是拿起生疏的工具尝试自食其力地解决问题,故难以保证本文方法的正确性和优雅性。
同时请在尝试本文方法前做好数据备份工作并准备好 Live CD,以防止发生数据损坏、无法启动等问题。
此外,错误的驱动配置可能损坏您的硬件,故请谨慎操作。如出现意外情况将由您自行承担相关损失,与作者无关。

检查错误

查看 CS35L4L 相关信息:

1
journalctl -b -g 'csc|cs35l41' --case-sensitive=false --output short-monotonic

发现 CS35L4L 驱动加载失败:

1
2
3
4
5
6
7
Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 I2C devices.
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Failed property cirrus,dev-index: -22
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
cs35l41-hda: probe of i2c-CSC3551:00-cs35l41-hda.0 failed with error -22
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Failed property cirrus,dev-index: -22
cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
cs35l41-hda: probe of i2c-CSC3551:00-cs35l41-hda.1 failed with error -22

CS35L4L 在 Linux 下具有驱动,但由于某些厂商并没有在 ACPI Table 中正确地描述音频设备,而是在其 Windows 的驱动中硬编码某些配置项(坏文明!),导致 Linux 下无法正确识别音频设备。

这里需要修改内核源码,以硬编码拯救者的音频设备信息。由于大量厂商的设备存在类似问题,内核树中已存在对 CS35L4L 参数硬编码的良好支持,只需要添加一条记录即可。

修补问题

查找 Subsystem ID

查看 ACPI Table:

1
2
3
4
# sudo pacman -S acpica
sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
iasl -d dsdt.dat
less dsdt.dsl

使用 /CSC3551<Enter> 搜索,可以找到相关信息:

1
2
Name (_HID, "CSC3551")  // _HID: Hardware ID
Name (_SUB, "17AA386E") // _SUB: Subsystem ID

即我们需要处理的设备 Subsystem ID 为 17AA386E

制作 Patch (v1)

https://github.com/archlinux/linux/tree/v6.8.5-arch1 查看内核源码,修改相关文件。

修改 sound/pci/hda/patch_realtek.c

和大部分机型不同,Y9000X 2022 IAH7 的两个放大芯片的中断 IRQ 相同,且中断引脚通过 APIC 连接。为了避免以下错误,不直接使用 generic_dsd_config

genirq: Flags mismatch irq 58. 00002088 (cs35l41 IRQ1 Controller) vs. 00002088 (cs35l41 IRQ1 Controller)

作为 workaround,我们自己写一个配置函数,关闭第二个放大器的中断功能:

1
2
3
4
5
6
7
8
static int single_interrupt_dsd_config(struct cs35l41_hda *cs35l41, struct device *physdev, int id, const char *hid)
{
generic_dsd_config(cs35l41, physdev, id, hid);
if (id != 0x40) {
cs35l41->hw_cfg.gpio2.func = CS35L41_NOT_USED;
}
return 0;
}

添加到配置模型表:

1
2
// array cs35l41_prop_model_table
{ "CSC3551", "17AA386E", single_interrupt_dsd_config }

并配置引脚信息和输出模式:

1
2
// array cs35l41_config_table
{ "17AA386E", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }

修改 sound/pci/hda/patch_realtek.c

添加 SND_PCI_QUIRK

1
2
// array alc269_fixup_tbl
SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2)

生成补丁文件 sound_17aa386e_fix.patch

1
2
# i:修改前的源码,w:修改后的源码
git diff --no-index i/ w/ --no-prefix > sound_17aa386e_fix.patch
sound_17aa386e_fix.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
diff --git i/sound/pci/hda/cs35l41_hda_property.c w/sound/pci/hda/cs35l41_hda_property.c
index 4d1f873..e9f721b 100644
--- i/sound/pci/hda/cs35l41_hda_property.c
+++ w/sound/pci/hda/cs35l41_hda_property.c
@@ -98,6 +98,7 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "17AA386E", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -367,6 +368,16 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
return 0;
}

+static int single_interrupt_dsd_config(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+ const char *hid)
+{
+ generic_dsd_config(cs35l41, physdev, id, hid);
+ if (id != 0x40) {
+ cs35l41->hw_cfg.gpio2.func = CS35L41_NOT_USED;
+ }
+ return 0;
+}
+
struct cs35l41_prop_model {
const char *hid;
const char *ssid;
@@ -438,6 +449,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
{ "CSC3551", "10433A60", generic_dsd_config },
+ { "CSC3551", "17AA386E", single_interrupt_dsd_config },
{ "CSC3551", "17AA386F", generic_dsd_config },
{ "CSC3551", "17AA3877", generic_dsd_config },
{ "CSC3551", "17AA3878", generic_dsd_config },
diff --git i/sound/pci/hda/patch_realtek.c w/sound/pci/hda/patch_realtek.c
index f4a02bf..bac3161 100644
--- i/sound/pci/hda/patch_realtek.c
+++ w/sound/pci/hda/patch_realtek.c
@@ -10359,6 +10359,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),

制作 Patch (v2)

问题分析

上述方法直接关闭了第二个放大器的中断功能,这可能导致某些状态下无法自动重新初始化放大器。

关注错误:

genirq: Flags mismatch irq 58. 00002088 (cs35l41 IRQ1 Controller) vs. 00002088 (cs35l41 IRQ1 Controller)

这非常令人困惑,因为日志给出的两个 Flags 是相同的。

进一步调查显示,错误由 __setup_irq 函数中的以下检查引发:

1
2
3
4
5
6
7
8
9
10
if (irqd_trigger_type_was_set(&desc->irq_data)) {
oldtype = irqd_get_trigger_type(&desc->irq_data);
} else {
oldtype = new->flags & IRQF_TRIGGER_MASK;
irqd_set_trigger_type(&desc->irq_data, oldtype);
}

if (!((old->flags & new->flags) & IRQF_SHARED) ||
(oldtype != (new->flags & IRQF_TRIGGER_MASK)))
goto mismatch;

可以看到,检查使用的 oldtype 实际上是通过 irqd_get_trigger_type 获取的。
虽然所有的中断都是用标志位 0x00002088 = IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW 请求的。
但这里获取到的 oldtypeIRQF_TRIGGER_RISING (0x1)(遵从了 DSDT 表中的配置) 而非 IRQF_TRIGGER_LOW (0x8),导致了错误。

由于我们的中断脚是连接到 APIC 的,关注 platform_get_irq_optional

1
2
3
4
5
6
7
8
if (r && r->flags & IORESOURCE_BITS) {
struct irq_data *irqd;

irqd = irq_get_irq_data(r->start);
if (!irqd)
goto out_not_found;
irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
}

可以看到 DSDT 表中的信息将用于配置 trigger type。

问题解决

修改 sound/pci/hda/cs35l41_hda.c,在请求中断时尊重已有的中断配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 	irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);

if (cs35l41->irq && using_irq) {
+ struct irq_data *irq_data;
+
+ irq_data = irq_get_irq_data(cs35l41->irq);
+ if (irq_data && irqd_trigger_type_was_set(irq_data)) {
+ irq_pol = irqd_get_trigger_type(irq_data);
+ dev_info(cs35l41->dev, "Using configured IRQ Polarity: %d\n", irq_pol);
+ }
+
ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);

之后我们就可以使用 generic_dsd_config 完成配置了。

补丁文件 sound_17aa386e_fix.patch

sound_17aa386e_fix.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index d3fa6e136744..d9c7b4034684 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <sound/hda_codec.h>
+#include <linux/irq.h>
#include <sound/soc.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
@@ -1511,6 +1512,14 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);

if (cs35l41->irq && using_irq) {
+ struct irq_data *irq_data;
+
+ irq_data = irq_get_irq_data(cs35l41->irq);
+ if (irq_data && irqd_trigger_type_was_set(irq_data)) {
+ irq_pol = irqd_get_trigger_type(irq_data);
+ dev_info(cs35l41->dev, "Using configured IRQ Polarity: %d\n", irq_pol);
+ }
+
ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 8fb688e41414..60ad2344488b 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -109,6 +109,7 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "17AA386E", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -500,6 +501,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
{ "CSC3551", "10433A60", generic_dsd_config },
+ { "CSC3551", "17AA386E", generic_dsd_config },
{ "CSC3551", "17AA386F", generic_dsd_config },
{ "CSC3551", "17AA3877", generic_dsd_config },
{ "CSC3551", "17AA3878", generic_dsd_config },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cdcb28aa9d7b..ac729187f6a7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10382,6 +10382,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),

制作 Patch (v3)

修改日志

根据 LKML 上的讨论,spkid GPIO Index 应该设置为 2,而不是 1。

补丁文件 sound_17aa386e_fix.patch

sound_17aa386e_fix.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index d3fa6e136744..d9c7b4034684 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <sound/hda_codec.h>
+#include <linux/irq.h>
#include <sound/soc.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
@@ -1511,6 +1512,14 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);

if (cs35l41->irq && using_irq) {
+ struct irq_data *irq_data;
+
+ irq_data = irq_get_irq_data(cs35l41->irq);
+ if (irq_data && irqd_trigger_type_was_set(irq_data)) {
+ irq_pol = irqd_get_trigger_type(irq_data);
+ dev_info(cs35l41->dev, "Using configured IRQ Polarity: %d\n", irq_pol);
+ }
+
ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 8fb688e41414..ee195737d388 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -109,6 +109,7 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10433A60", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
+ { "17AA386E", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -500,6 +501,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
{ "CSC3551", "10433A60", generic_dsd_config },
+ { "CSC3551", "17AA386E", generic_dsd_config },
{ "CSC3551", "17AA386F", generic_dsd_config },
{ "CSC3551", "17AA3877", generic_dsd_config },
{ "CSC3551", "17AA3878", generic_dsd_config },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cdcb28aa9d7b..ac729187f6a7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10382,6 +10382,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x386e, "Legion Y9000X 2022 IAH7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),

构建内核

克隆 Arch Linux 内核包构建文件:

1
2
git clone https://gitlab.archlinux.org/archlinux/packaging/packages/linux
git checkout 6.8.5.arch1-1

修改 PKGBUILD, 添加 sound_17aa386e_fix.patchsource 数组:

1
2
3
4
5
6
7
source=(
https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/${_srcname}.tar.{xz,sign}
$url/releases/download/$_srctag/linux-$_srctag.patch.zst{,.sig}
config # the main kernel config file
docutils.patch # fix the docs build
+ sound_17aa386e_fix.patch
)

同时添加 SKIPsha256sumsb2sums 数组,以跳过校验。

linux 包本身存在批量应用 patch 的功能,故无需修改 prepare() 函数

1
2
3
4
5
6
7
8
9
local src
for src in "${source[@]}"; do
src="${src%%::*}"
src="${src##*/}"
src="${src%.zst}"
[[ $src = *.patch ]] || continue
echo "Applying patch $src..."
patch -Np1 < "../$src"
done

构建包:

1
2
# 很慢,坐和放宽(sit back and relax)
makepkg -s

安装内核

1
sudo pacman -U linux-6.8.5.arch1-1-x86_64.pkg.tar.zst

重启

1
sudo reboot

注意事项

推荐提前设置好 ~/.config/pacman/makepkg.conf 文件,以加速构建过程,例如:

1
MAKEFLAGS="-j$(nproc)"

内核编译需要占用大量空间,请提前检查 BUILDDIR 空间是否足够。

参考资料

另记

又通宵了一个晚上(虽然是因为我菜,对内核不了解🥹),困死了。果然晚上不适合开始任何非劳力型的工作。