在启动时禁用特定的PCI设备


14

我刚刚在我的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设备?


-edit-该模块最近被重命名,现在来自userland的以下作品:

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

尽管如此,我仍在寻找一种方法来阻止内核首先绑定该设备。


1
可以接受的方法是通过USB总线而不是PCI总线禁用此特定USB设备吗?
slm

您还确定可以使用pci:...这样的字符串将其列入黑名单吗?我只见过/etc/modprobe.d/blacklist文件中的内核模块可列入黑名单。您不能使用lspci -k标识设备需要哪个模块,然后将其列入黑名单吗?
slm

将条目添加到黑名单后,您update-initramfs -u -k all呢?
Stefan Seidel

@StefanSeidel:好点。我现在有,但似乎无济于事。也许slm认为这样的Modalias列入黑名单需要不同的语法或方法是正确的。
Rhymoid

@slm:我不确定是否可以通过modprobe黑名单阻止modalias(我的系统似乎忽略了我给它的那一行),但是我不能只是删除模块(ehci_hcd),因为那样会禁用所有 USB主机我的系统。我只想根据其供应商,开发人员,子供应商和subdev禁用此特定设备。
Rhymoid

Answers:


4

我最近在用多个USB设备配置我的Xen盒时遇到了这个问题。我想要一个供Dom-0使用,另一个供VM使用,因此我需要该设备可用于xen-pciback。但是,usb驱动程序已编译到我的内核中,因此我不能只是将驱动程序列入黑名单。我的解决方案是创建一个自定义的initramfs脚本,该脚本在引导过程的早期就取消绑定特定的pci端口。

这是Ubuntu 2016.04,但应在早期版本中工作。

涉及三个文件。我为我的特定用例命名了它们,但是ymmv:

第一个文件,名为/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并重新启动。

我可以在配置文件中包含对注释的支持,这里有很多清理工作,但这对我有用。


仍然是一个解决方案,您可以在初始化之后取消绑定PCI设备,但是,看起来比解决它还好/etc/init.d!我现在不使用机器,可能永远也不会再用Debian引导它,所以我无法对其进行测试。但是,由于它可能对我而言有效,因此我将其作为答案。
Rhymoid '16

同意,我仍然没有找到在不将模块列入黑名单的情况下防止设备初始化的解决方案。实际上,“ radeon”行是对此进行早期尝试的一个示例。
Steve Czetty

有趣的是,我认为udev所有的总线都在内核引导过程中遍历并加载,而grub所做的任何事情initramfs都是只读的,并且丢失了。加载内核时。我曾尝试设置setpciinitramfs-tools但放弃了,现在正在尝试udev规则。
WinEunuuchs2Unix

4

没有任何答案可以解决我的类似问题,但是它们确实使我走上了解决之路!

我的系统日志错误:

[  334.940158] hub 1-0:1.0: unable to enumerate USB device on port 7

这是我没有的蓝牙选项的内部USB集线器端口。

取消绑定到pci设备只是导致集线器弹出作为另一个集线器(在我的情况下为5)并进一步泛滥syslog。

偶然地,我注意到下方的一个未绑定的结构/sys/bus/usb/drivers/hub。使用上面的示例,我在rc.local中添加了以下内容:

echo "1-0:1.0" > /sys/bus/usb/drivers/hub/unbind

结果是系统日志保持沉默!现在添加kshurig的电源管理脚本示例,我应该很高兴。


4

您可以通过在/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设备地址


这非常有用。但是,正如OP所述,这将导致所有USB端口掉线。无论如何,是否需要为特定设备和供应商ID添加规则,以使这些设备可以与所有其他USB端口一起使用,但是会忽略给定的设备?
Mosty Mostacho 2014年

2

在askubuntu上找到此线程:

使用lspci -vv识别设备的PCI插槽要禁用,这听起来像你可以使用这个命令来打开该插槽的设备关闭:

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

1
我知道我可以在任何其他时间禁用它,但是我想完全停止激活它。此外,由于这是硬连线的PCI设备(像大多数USB控制器一样),因此没有插槽。我正在谈论的机器是一台笔记本电脑,它唯一的插槽(/sys/bus/pci/slots/1)是外部的ExpressCard插槽,我可以手动腾出它。
Rhymoid

2

当你已经拥有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规则,但是由于不会断开网络摄像头,因此它应该可以工作。如果那不能解决问题,我还有另一个建议。


如果上述方法不起作用,则必须找到正确的USB端口。我猜它是“ 1-1.2”(否则请tree /sys/bus/pci/devices/0000\:00\:1a.0/在“ usbX”下进行检查,这表示端口是相似的数字)。如果它是“ 1-1.2”,而不是您echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbind的脚本,则应该具有echo "auto" > /sys/bus/usb/devices/1-1.2/power/control; echo -n "1-1.2" > /sys/bus/usb/drivers/usb/unbind
kschurig

0

解决问题的方法不如解决问题。

为什么不通过修改syslog /(不知道您是否使用syslog或rsyslog或其他东西来简单地抑制将消息记录到控制台,所以我不能真正地将您更具体地指向正确的目录,但是如果您在syslog配置文件中搜索“控制台”和“ tty”,这将为您提供一个良好的起点-实际上,您可以将控制台更改为/ dev / tty1 [例如],并且仅将消息记录到tty1而不是全部控制台。

另一种解决方案(回答您的问题,但我不喜欢),您可以将ehci_hcd模块(如果已加载)列入黑名单,或者重新编译内核以仅将其用作模块。看看h ttp://www.cyberciti.biz/faq/rhel-redhat-c​​entos-kernel-usb-reset-high-speed-ehci_hcd/ ,它可以完全解决您要问的问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.