Deaktivieren Sie bestimmte PCI-Geräte beim Booten

14

Ich habe gerade Debian auf meinem Sony VAIO-Laptop neu installiert und meine dmesgund virtuellen Konsolen werden immer wieder mit denselben Nachrichten überflutet.

[   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

Ich glaube, diese Nachrichten stammen von einem intern angeschlossenen USB-Gerät, höchstwahrscheinlich der Webcam (da dies das einzige ist, was nicht funktioniert). Der einzige Weg, wie ich scheinen kann, es herunterzufahren (ohne meine tatsächlich nützlichen USB-Ports zu zerstören), ist, einen der USB-Host-Controller zu deaktivieren:

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

Dadurch wird auch meine Bluetooth-Schnittstelle heruntergefahren, aber damit bin ich einverstanden.

Ich möchte, dass diese Einstellung beibehalten wird, damit ich meine virtuelle Konsole bei Bedarf problemlos wieder verwenden kann. Ich möchte, dass mein Betriebssystem (Debian amd64) es niemals startet, aber ich weiß nicht, wie ich das machen soll. Ich habe versucht, den Modul-Alias ​​für das PCI-Gerät auf eine Blacklist zu setzen, aber er scheint ignoriert zu werden:

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

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

Wie kann ich sicherstellen, dass dieses spezielle PCI-Gerät niemals automatisch aktiviert wird, ohne den Treiber insgesamt zu deaktivieren?


-edit- Das Modul wurde kürzlich umbenannt, jetzt funktioniert folgendes aus dem userland:

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

Trotzdem suche ich nach einer Möglichkeit, den Kernel davon abzuhalten, dieses Gerät zu binden.

Rhymoid
quelle
1
Wäre es ein akzeptabler Ansatz, dieses bestimmte USB-Gerät über den USB-Bus und nicht über den PCI-Bus zu deaktivieren?
Slm
Sind Sie auch sicher, dass Sie mit einer solchen pci: ... -Zeichenfolge eine Blacklist erstellen können? Ich habe bisher nur Kernelmodule gesehen, die in der Datei /etc/modprobe.d/blacklist auf eine schwarze Liste gesetzt werden können. Könnten Sie nicht mit lspci -k herausfinden, welches Modul das Gerät haben möchte, und dieses stattdessen auf die schwarze Liste setzen?
Slm
Nachdem Sie den Eintrag zur Blacklist hinzugefügt haben, haben Sie es getan update-initramfs -u -k all?
Stefan Seidel
@ StefanSeidel: Guter Punkt. Ich habe jetzt, aber es scheint nicht zu helfen. Vielleicht hat slm recht, wenn er denkt, dass für die Blacklisting eines solchen Modalias eine andere Syntax oder Methode erforderlich ist.
Rhymoid
@slm: Ich bin nicht sicher, ob ich Modaliases über die Modprobe-Blacklist blockieren kann (mein System scheint die angegebene Zeile zu ignorieren), aber ich kann das Modul nicht einfach entfernen ( ehci_hcd), da dadurch alle USB-Hosts deaktiviert würden mein System. Ich möchte nur dieses bestimmte Gerät deaktivieren, basierend auf seinem Hersteller, Entwickler, Sub-Anbieter und Sub-Entwickler.
Rhymoid

Antworten:

4

Ich bin kürzlich auf dieses Problem gestoßen, als ich meine Xen-Box mit mehreren USB-Geräten konfiguriert habe. Ich wollte, dass einer von Dom-0 und der andere von einer VM verwendet wird, also musste das Gerät für Xen-pciback verfügbar sein. Der USB-Treiber wurde jedoch in meinen Kernel aufgenommen, sodass ich den Treiber nicht einfach auf die schwarze Liste setzen konnte. Meine Lösung bestand darin, ein benutzerdefiniertes initramfs-Skript zu erstellen, das die Bindung des spezifischen PCI-Ports sehr früh im Startprozess aufhebt.

Dies ist Ubuntu 2016.04, aber es sollte in früheren Versionen funktionieren.

Es handelt sich um drei Dateien. Ich habe sie für meinen speziellen Anwendungsfall benannt, aber ymmv:

Die erste Datei mit dem Namen /etc/unbindpcifile ist eine einfache CSV-Datei aus der PCI-Gerätenummer und dem Treiber (hier nach Bedarf konfigurieren):

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

Zweite Datei /etc/initramfs-tools/hooks/xenfiles, die die obige Konfiguration in das initramfs kopiert.

#! /bin/bash

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

Die dritte Datei ist, was die Arbeit beim Booten macht, ich habe es in /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

Führen Sie zum Schluss einen update-initramfs -k all -uNeustart durch.

Ich könnte die Unterstützung für Kommentare in die Konfigurationsdatei aufnehmen, und hier muss viel aufgeräumt werden, aber es funktioniert für mich.

Steve Czetty
quelle
Es ist immer noch eine Lösung, bei der Sie das PCI-Gerät nach der Initialisierung lösen, aber hey, es sieht besser aus als es zu lösen /etc/init.d! Ich benutze die Maschine momentan nicht und boote sie möglicherweise nie wieder mit Debian, so dass ich sie nicht testen kann. Da es in meinem Fall wahrscheinlich geklappt hätte, akzeptiere ich es als Antwort.
Rhymoid
Einverstanden, ich habe immer noch keine Lösung gefunden, um die Geräteinitialisierung zu verhindern, ohne das Modul auf die schwarze Liste zu setzen. Die "Radeon" -Linie ist eigentlich ein Beispiel für einen frühen Versuch.
Steve Czetty
Komisch, dachte ich, dass udevder gesamte Bus beim Booten des Kernels durchgelaufen und geladen initramfswurde und alles, was in Grub gemacht wurde, nur gelesen und verloren wurde. wenn der Kernel geladen ist. Ich hatte die Einrichtung versucht , setpciin initramfs-toolsaber aufgegeben und ich versuche , eine udevjetzt Regel.
WinEunuuchs2Unix
4

Keine der Antworten hat mein ähnliches Problem gelöst, aber sie haben mich auf den Weg gebracht, es zu lösen!

Mein Syslog-Fehler:

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

Dies ist ein interner USB-Hub-Port für eine Bluetooth-Option, die ich nicht habe.

Das Aufheben der Bindung an das PCI-Gerät hat dazu geführt, dass der Hub als ein weiterer Hub (in meinem Fall 5) wieder hochgefahren und das Syslog weiter überflutet wurde.

Durch Zufall bemerkte ich eine ungebundene Struktur unter /sys/bus/usb/drivers/hub. Anhand der obigen Beispiele habe ich in rc.local Folgendes hinzugefügt:

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

Ergebnis ist Syslog-Stille! Nun, um Kshurigs Skriptbeispiel für die Energieverwaltung hinzuzufügen, sollte ich golden sein.

Kujo770
quelle
4

Sie können ein PCI-Gerät entfernen, indem Sie eine udev-Regel unter /etc/udev/rules.d hinzufügen:

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

Ersetzen Sie 0000:00:03.0durch die PCI-Geräteadresse, die Sie entfernen möchten

Mondsturm
quelle
Das ist ziemlich nützlich. Dies führt jedoch, wie im OP erwähnt, dazu, dass alle USB-Ports ausfallen. Gibt es überhaupt eine Regel für ein bestimmtes Gerät und eine Hersteller-ID, damit das Gerät mit allen anderen USB-Anschlüssen funktioniert, ein bestimmtes Gerät jedoch ignoriert?
Mosty Mostacho
2

Diesen Thread auf askubuntu gefunden:

Wenn lspci -vvSie den PCI-Steckplatz eines Geräts identifizieren, den Sie deaktivieren möchten, haben Sie den Eindruck, Sie könnten diesen Befehl verwenden, um das Gerät dieses Steckplatzes auszuschalten:

% echo 0 > /sys/bus/pci/slot/$N/power
slm
quelle
1
Ich weiß, wie ich es zu einem anderen Zeitpunkt deaktivieren kann, aber ich möchte den Kernel davon abhalten, es überhaupt zu aktivieren. Da es sich um ein festverdrahtetes PCI-Gerät handelt (wie die meisten USB-Controller), verfügt es über keinen Steckplatz. Die Maschine, über die ich spreche, ist ein Laptop, und der einzige Steckplatz, über den er verfügt ( /sys/bus/pci/slots/1), ist der ExpressCard-Steckplatz an der Außenseite, den ich manuell räumen kann.
Rhymoid
2

Wenn Sie bereits echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbindin /etc/rc.localfür Boot , als Sie brauchen nur in ein Skript für das Power - Management setzen deamon ebenfalls.

Gehen Sie folgendermaßen vor: Erstellen Sie eine ausführbare Bash-Skriptdatei mit dem Namen 0_disable_webcamim Verzeichnis /etc/pm/sleep.d/:

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

Es sollte sofort funktionieren. Ich habe es mit einem USB-Stick versucht und es funktionierte (was bedeutet, dass es deaktiviert blieb), solange das Laufwerk eingesteckt war. Das Umstecken würde udev-Regeln erfordern, aber da Ihre Webcam nicht ausgesteckt wird, sollte es funktionieren. Wenn das nicht ausreicht, habe ich einen anderen Vorschlag.

kschurig
quelle
Wenn dies nicht funktioniert, müssen Sie den richtigen USB-Anschluss finden. Ich denke, es ist "1-1.2" (ansonsten überprüfen Sie mit tree /sys/bus/pci/devices/0000\:00\:1a.0/unter "usbX", was bedeutet, dass der Port eine ähnliche Nummer ist). Wenn es "1-1.2" anstelle von Ihrem ist, sollte echo "0000:00:1a.0" > /sys/bus/pci/drivers/ehci_hcd/unbinddas Skript haben echo "auto" > /sys/bus/usb/devices/1-1.2/power/control; echo -n "1-1.2" > /sys/bus/usb/drivers/usb/unbind.
kschurig
0

Keine Antwort auf Ihre Frage, sondern ein Workaround.

Warum unterdrücken Sie nicht einfach die Protokollierung der Nachrichten an der Konsole, indem Sie syslog / ändern? (Ich weiß nicht, ob Sie syslog oder rsyslog oder etwas anderes verwenden, also kann ich Sie nicht genauer auf das richtige Verzeichnis verweisen, sondern nur auf Sie Durchsuchen Sie Ihre Syslog-Konfigurationsdateien nach "console" und "tty", was Ihnen einen guten Startplatz verschafft. Tatsächlich können Sie wahrscheinlich die Konsole in / dev / tty1 [zum Beispiel] ändern und Nachrichten nur in tty1 anstatt in allen protokollieren lassen Konsolen.

Die andere Lösung (um Ihre Frage zu beantworten, aber ich mag sie nicht) ist, dass Sie das Modul ehci_hcd auf eine schwarze Liste setzen (falls es geladen ist) oder Ihren Kernel neu kompilieren, um es nur als Modul zu verwenden. Schauen Sie unter http://www.cyberciti.biz/faq/rhel-redhat-centos-kernel-usb-reset-high-speed-ehci_hcd/ nach, um genau die Frage zu beantworten, die Sie sich stellen

Davidgo
quelle