在启动时禁用特定 PCI 设备

在启动时禁用特定 PCI 设备

我刚刚在我的 Sony VAIO 笔记本电脑上重新安装了 Debian,我的dmesg和虚拟控制台都一遍又一遍地收到相同的消息。

[   59.662381] hub 1-1:1.0: unable to enumerate USB device on port 2
[   59.901732] usb 1-1.2: new high-speed USB device number 91 using ehci_hcd
[   59.917940] hub 1-1:1.0: unable to enumerate USB device on port 2
[   60.157256] usb 1-1.2: new high-speed USB device number 92 using ehci_hcd

我相信这些消息来自内部连接的 USB 设备,最有可能是网络摄像头(因为这是唯一不起作用的东西)。我似乎可以让它闭嘴的唯一方法是(不关闭我实际有用的 USB 端口)禁用其中一个 USB 主机控制器:

# echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind

这也会关闭我的蓝牙接口,但我对此没意见。

我希望此设置能够持续,这样我就可以毫不费力地再次使用虚拟控制台,以防万一。我希望我的操作系统(Debian amd64)永远不会唤醒它,但我不知道该怎么做。我试图将 PCI 设备的模块别名列入黑名单,但它似乎被忽略了:

$ cat /sys/bus/pci/devices/0000\:00\:1a.0/modalias 
pci:v00008086d00003B3Csv0000104Dsd00009071bc0Csc03i20

$ cat /etc/modprobe.d/blacklist
blacklist pci:v00008086d00003B3Csv0000104Dsd00009071bc0Csc03i20

如何确保此特定的 PCI 设备永远不会自动激活,而无需完全禁用其驱动程序?


-编辑-该模块最近已重命名,现在用户空间中有以下工作:

echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci-pci/unbind

不过,我正在寻找一种方法来阻止内核绑定该设备。

答案1

我最近在配置带有多个 USB 设备的 xen 盒时遇到了这个问题。我希望其中一个设备由 Dom-0 使用,另一个由 VM 使用,因此我需要该设备可供 xen-pciback 使用。但是,USB 驱动程序已编译到我的内核中,因此我无法直接将该驱动程序列入黑名单。我的解决方案是创建一个自定义 initramfs 脚本,在启动过程的早期解除特定 pci 端口的绑定。

这是 Ubuntu 2016.04,但它应该可以在早期版本中运行。

涉及三个文件。我根据自己的具体用例命名了它们,但你可能不同意:

第一个文件,名为/etc/unbindpcifile,它是 pci 设备编号和驱动程序的简单 csv(根据需要在此处配置):

0000:08:00.0,xhci_hcd
0000:03:00.0,radeon

第二个文件/etc/initramfs-tools/hooks/xenfiles,将上述配置复制到 initramfs 中。

#! /bin/bash

if [ -f /etc/unbindpci ]; then
  cp -pP /etc/unbindpci $DESTDIR/etc/unbindpci
fi

第三个文件是在启动时进行的工作,我将其放在/etc/initramfs-tools/scripts/init-top/unbind-early-pci

#!/bin/sh

PREREQ=""
prereqs()
{
        echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
        prereqs
        exit 0
        ;;
esac

# This only executes if in a xen Dom-0.
# Edit if that's not your use case!          
if [ -f /sys/hypervisor/uuid -a -f /etc/unbindpci ]; then
        if [ $(cat /sys/hypervisor/uuid) = "00000000-0000-0000-0000-000000000000" ]; then
                echo "Unbinding pci ports..."
                IFS=,
                while read addr driver; do
                        if [ -f /sys/bus/pci/drivers/$driver/unbind ]; then
                                echo "Unbinding $addr, device $driver"
                                echo $addr > /sys/bus/pci/drivers/$driver/unbind
                        fi
                done < /etc/unbindpci
        fi
fi

最后,运行update-initramfs -k all -u并重启。

我可以在配置文件中包含对注释的支持,这里需要进行大量的清理工作,但它对我来说很有效。

答案2

您可以通过在 /etc/udev/rules.d 下添加 udev 规则来删除 PCI 设备:

ACTION=="add", KERNEL=="0000:00:03.0", SUBSYSTEM=="pci", RUN+="/bin/sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:03.0/remove'"

替换0000:00:03.0为要移除的 pci 设备地址

答案3

在 askubuntu 上找到这个帖子:

用于lspci -vv识别您想要禁用的设备的 PCI 插槽,听起来您可以使用此命令来关闭该插槽的设备:

% echo 0 > /sys/bus/pci/slot/$N/power

答案4

当您已经echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind启动时/etc/rc.local,您只需要将其放入电源管理守护进程的脚本中。

像这样:0_disable_webcam在目录中创建一个可执行的 bash 脚本文件/etc/pm/sleep.d/

#!/bin/sh
case "$1" in
        resume|thaw)
                echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind
                ;;
esac

它应该立即起作用。我用 USB 拇指驱动器尝试过,只要驱动器插入,它就可以工作(意味着它保持禁用状态)。重新插入需要 udev 规则,但由于您的网络摄像头不会被拔出,它应该可以工作。如果这不起作用,我还有另一个建议。

相关内容