Bei der Verwendung lsusb
stelle ich fest, dass sich die Busnummer und die Gerätenummer eines USB-Geräts von Zeit zu Zeit ändern können. Soweit ich weiß, kann die Busnummer bei jedem Neustart geändert werden. Die Gerätenummer ändert sich bei jeder erneuten Verbindung.
Meine Frage ist, welchen Algorithmus das System verwendet, um die Busnummer und die Gerätenummer zu erhalten? Vor allem die Gerätenummer, ist es monoton? Wird es jemals den Fall geben, dass ein neu verbundenes Gerät ohne Neustart des Betriebssystems die alte Busnummer und Gerätenummer eines anderen neu verbundenen Geräts verwendet?
Antworten:
Hinweis: Dies ist eine Linux- Antwort. Andere Kernel werden etwas anders damit umgehen.
Kontext
Es ist schwierig, über USB-Busse zu sprechen, ohne über PCI-Busse zu sprechen. Eine CPU kann nicht mit einem USB-Bus kommunizieren. Dies geschieht, wenn die CPU mit einem PCI-Bus kommuniziert, an den ein USB-Controller angeschlossen ist (und ein USB-Controller / Hub
lsusb
einen USB-Bus bezeichnet). PCI-Busse werden basierend auf dem Abstand zur CPU nummeriert. Beispiel:Wenn
man lspci
wir hineinschauen , sehen wir Folgendes:Deshalb wissen wir jetzt, wie man PCI-Nummern interpretiert. Als nächstes betrachten wir USB-Controller, die an die PCI-Busse angeschlossen sind. Die Maschine, an der ich mich gerade befinde, hat eine interessante USB-Konfiguration, die ich als Beispiel verwenden werde:
Warte, warte, warte, was sind all diese Pluspunkte? Oben haben wir die Domäne und den PCI-Bus
-[0000:00]
(dieser Rechner hat nur einen PCI-Bus). Und dann haben wir mehrere Geräte an diesen Bus angeschlossen. Mal sehen, welche USB-Geräte sind:Gut, jetzt vergleichen wir das mit
lsusb
(ich benutze essort
nur, um es später einfacher zu machen, die Liste zu durchsuchen):Warte nocheinmal. Wir haben 7 USB-Geräte nach,
lspci
aber 10 Geräte nachlsusb
!lspci
listet nur die USB-Controller auf; An einen Controller können mehrere USB-Geräte angeschlossen sein. Lassen Sie uns untersuchen,/sys/bus/
wie dies geschieht.Jetzt fängt das an Sinn zu machen, wir haben 7 USB-Controller, die als Geräte in den PCI-Bus eingesteckt sind. Beispielsweise entspricht der USB-Bus 001 dem PCI-Gerät
0000:00:12.2
und der USB-Bus 007 dem0000:00:14.5
Gerät.Gerätenummerierung
Die Verzeichnisse, die mit der USB-Busnummer beginnen (z. B.
7-1:1.2
), sind die tatsächlichen Geräte, die an den USB-Controller angeschlossen sind. Genau wie an einen PCI-Bus mehrere Geräte angeschlossen sein können, können an einen USB-Controller (einen Hub) mehrere USB-Geräte angeschlossen sein.Gerätenummern sind einfach Zähler: Das erste angeschlossene Gerät erhält eine 1, das nächste eine 2 und so weiter. Aber es gibt noch ein bisschen mehr: USB wurde als Hot-Plug-fähig konzipiert. Daher können Sie Geräte verbinden und trennen. Wenn Sie ein USB-Gerät trennen, wird die Gerätenummer vom Kernel nicht mehr für ein anderes Gerät auf diesem USB-Controller verwendet. Wenn Sie zum Beispiel ein USB-Stick anschließen und trennen und fortfahren,
lsusb
wird die Gerätenummer Ihres USB-Sticks angezeigt.Busnummerierung
Wenn Sie die obigen Informationen aufmerksam gelesen haben, fragen Sie sich möglicherweise über eine Sache, die ich nicht angerührt habe. Die Reihenfolge der PCI-Nummerierung entspricht nicht der Reihenfolge, in der die USB-Controller nummeriert wurden! Lassen Sie uns das noch einmal sehen:
Die Liste ist in Ordnung, aber nicht ganz. Die ersten beiden USB-Controller scheinen nicht in Betrieb zu sein. Es gibt jedoch einen Grund dafür: Wenn Sie oben nachsehen, werden
lspci
Sie feststellen, dass es sich umEHCI
USB (USB 2.0) handelt, während es sich bei allen anderen USB-Controllern umOHCI
USB (USB 1.x) handelt.Daher können wir diese Tabelle neu zeichnen als:
Und die Nummernvergabe wird klar.
quelle
001
, sondern der Kernel verwendet die wenigen größten Gerätenummern erneut. Gibt es eine einfache Möglichkeit, dieses Verhalten zu ändern?udev
mehr oder weniger verstanden werden). Um die Nummerierung zum Zwecke des Lernens zu verstehen, glaube ich, dass der einzige Ort, an dem die Informationen vorliegen, der Kernel-Code ist.