笔记本电脑:HP Omen 16(2022 款)
Ubuntu:22.04.1
我在一台全新的笔记本电脑上全新安装了 Ubuntu 22.04。Wi-Fi 运行良好,但蓝牙根本无法使用;这与我过去的一般体验完全相反。
笔记本电脑的底部写着:
Contains MediaTek Radio Model: MT7922A22M
lsusb
显示设备:
Bus 001 Device 003: ID 0489:e0e0 Foxconn / Hon Hai Wireless_Device
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x0489 Foxconn / Hon Hai
idProduct 0xe0e0
bcdDevice 1.00
iManufacturer 5 MediaTek Inc.
iProduct 6 Wireless_Device
iSerial 7 000000000
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x00fe
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 8 Config_01
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 3
bFunctionClass 224 Wireless
bFunctionSubClass 1 Radio Frequency
bFunctionProtocol 1 Bluetooth
iFunction 4 BT_FUNCTION
但hciconfig dev
说没有设备存在。
此外,rfkill
没有阻止任何东西:
ID TYPE DEVICE SOFT HARD
0 bluetooth hci0 unblocked unblocked
1 wlan phy0 unblocked unblocked
答案1
编辑(2023 年 5 月):此问题在 Ubuntu 23.04 中不再存在。随附的蓝牙驱动程序开箱即用,非常好用。因此,原始解决方法(见下文)仅在 Ubuntu 版本 22.10 及更低版本中才需要。
所以,我终于“解决”了这个问题。
看来固件/驱动程序已经存在于内核中,mt7921e
我相信是这样的。
看完之后此主题,我也怀疑设备/制造商代码(0489:e0e0
)太新了,因此内核中还不存在。所以,内核根本检测不到蓝牙适配器。
这里链接到一个数据库,显示有关此无线芯片支持的信息。
我检查了btusb
内核中通用驱动程序的最新源代码,发现我的芯片的代码(0489:e0e0
)在中缺失drivers/bluetooth/btusb.c
。顺便说一下,构建的驱动程序存在于/lib/modules/$(uname -r)/kernel/drivers/bluetooth/btusb.ko
,在我的情况下是/lib/modules/5.15.0-46-generic/kernel/drivers/bluetooth/btusb.ko
。
我也注意到一个新的补丁将相关代码添加到内核。
所以,现在我要么等待 Canonical 将此补丁移植到 Ubuntu 22.04(不知道这需要多长时间,如果它真的发生的话),要么我可以尝试在我的笔记本电脑上破解它。我决定选择后者。
现在,我要么获取源代码然后对其进行修补,然后构建一个新的btusb.ko
(很麻烦),要么直接对现有的进行十六进制编辑btusb.ko
(简单的二进制修补)。我决定选择后者。
执行操作dpkg -S /lib/modules/$(uname -r)/kernel/drivers/bluetooth/btusb.ko
表明它是由软件包提供的linux-modules-extra-5.15.0-46-generic
。根据软件包名称中的版本号,我怀疑每次有内核/驱动程序更新时,我都必须重新执行整个过程。哦,好吧。使用下载源代码后,我可以看到其中有一个与我的非常相似的apt-get source linux-modules-extra-5.15.0-46-generic
设备/制造商代码。btusb.c
{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
因此btusb.ko
,在 中已经有了0489:e0cd
礼物,我只需将其编辑为0489:e0e0
。
现在,我使用 GHex(可以使用任何十六进制编辑器)来编辑btusb.ko
。注意字节顺序。在我的笔记本电脑上,代码0489:e0cd
显示为字节89 04 CD E0
。我将其替换为字节89 04 E0 E0
。另外,注意多次出现的情况,确保找到并替换所有出现的情况。另外,在编辑之前,不要忘记保留备份。
现在只需这样做:
sudo modprobe -r btusb
sudo modprobe -v btusb
现在蓝牙应该可以工作了...除非你像我一样启用了 UEFI 安全启动!
内核将拒绝该模块/驱动程序,因为它只接受由可信方(在本例中为 Canonical)数字签名的模块。即使修改一个字节也会btusb.ko
使其“被篡改”。
现在,这听起来可能有点疯狂,但你可以让自己成为笔记本电脑 UEFI 的受信任方,并亲自签署编辑内容btusb.ko
。这将使内核愉快地接受它。
这是有风险的,我不建议这样做。这会增加您的攻击面(对于引导加载程序恶意软件),也会让您承担安全维护秘密签名密钥的负担。
如果您经验丰富,并且知道自己在做什么并且想继续,请继续阅读。
- 为自己生成一对新的密钥对。(公钥和私钥)
- 将私钥保存在安全的地方。
- 将公钥(作为 MOK)注册到 UEFI。
- 重新启动并完成注册公钥。
btusb.ko
使用私钥对内核进行签名。btusb.ko
将会被就地修改。- 重新加载模块:
sudo modprobe -r btusb; sudo modprobe -v btusb
。 - 成功 :-)
现在蓝牙应该可以正常工作了。至少在下一次内核/驱动程序更新之前。
让我们看看 Ubuntu 22.04 要多长时间才能引入对该芯片的支持。