Von register_chdev im Linux-Kernel zurückgegebener Wert

Von register_chdev im Linux-Kernel zurückgegebener Wert

Dieses Videozeigt ein Beispiel für ein Raspberry Pi Linux-Kernelmodul, das ein neues Zeichengerät erstellt. Es verwendet die Kernel-API . In einem Kommentar zum Video (ich kann keinen direkten Link dazu generieren) gibt der Autor register_chdevin Bezug auf den Rückgabewert von an :register_chdev

Wenn der Rückgabewert ungleich 0 ist, wird die Gerätenummer bereits verwendet. Die oberen 12 Bits des Rückgabewerts sind Ihre Hauptgerätenummer, die unteren 20 Bits sind die Nebengerätenummer.

Ich vermute, dass er mit „die Gerätenummer wird bereits verwendet“ meint, „die im Kernelmodul willkürlich gewählte, von Null verschiedene Hauptgerätenummer wird bereits verwendet“.

Obwohl sich mehrere Webseiten mit diesem Thema befassen (die offizielle, DannDieses hierUndDieses hier) konnte ich zu dieser internen Unterteilung des Rückgabewertes keine Informationen finden.

Wenn ich (mit meinem Kernelmodul) ein Gerät mit einer bereits verwendeten Hauptnummer erstelle, akzeptiert der Kernel dies nie und lehnt die Registrierung des Geräts ab. Dies tritt sowohl auf, wenn die von mir gewählte Hauptnummer mit der eines Blockgeräts übereinstimmt, als auch, wenn die von mir gewählte Hauptnummer mit der eines Zeichengeräts übereinstimmt. register_chdevgibt immer einen negativen Wert zurück. Im letzteren Fall erwartete ich stattdessen einen positiven Rückgabewert ungleich Null, wobei die oberen 12 Bits die Hauptgerätenummer und die unteren 20 Bits die Nebengerätenummer darstellen (möglicherweise größer als 0: wenn die Hauptnummer bereits verwendet wurde, hatte das System möglicherweise bereits mindestens ein zugehöriges Gerät mit der Nebennummer 0).

Stimmt das, was im Youtube-Kommentar steht? Wo finde ich eine Dokumentation dazu?


Ich verwende Raspbian 10 und uname -aes zeigt:

Linux raspberrypi 5.10.63-v7+ #1459 SMP Wed Oct 6 16:41:10 BST 2021 armv7l GNU/Linux

Antwort1

register_chrdevselbst ist nicht im Kernel dokumentiert, aberseine Definition ist kurz:

static inline int register_chrdev(unsigned int major, const char *name,
                  const struct file_operations *fops)
{
    return __register_chrdev(major, 0, 256, name, fops);
}

was im Grunde bedeutet, dass es anruft__register_chrdevum eine Haupttonart mit einer vollständigen Palette von Nebentonarten (256 Nebentonarten beginnend bei 0) zu registrieren und das Ergebnis dieser Funktion zurückzugeben. Letzteres ist dokumentiert als

Wennmajor== 0. Diese Funktion weist dynamisch einen Major zu und gibt seine Nummer zurück.

Wennmajor> 0: Diese Funktion versucht, ein Gerät mit der angegebenen Hauptnummer zu reservieren und gibt bei Erfolg Null zurück.

Gibt im Fehlerfall eine negative Fehlernummer zurück.

Es gibt keine Möglichkeit, Minor-Versionen, verschlüsselt oder anderweitig, zurückzugeben. Der Zweck dieser Funktionen besteht darin, in jedem Fall eine Major-Version zu registrieren, möglicherweise mit einer Teilmenge von Minor-Versionen; nicht eine einzelne Minor-Version.

DerCodierungkommt ins Spiel, wenn der Gerätetreiber einen openAnruf verarbeitet oder wenn er zu einem anderen Zeitpunkt bestimmen muss, welchem ​​Minor (und vielleicht Major, wenn er mehrere Majors verarbeitet) ein bestimmtes Gerät entspricht. Ein Treiber erhält den Inode, den er verarbeiten soll; für einen Geräteknoten enthält dies die Gerätenummer, die Major und Minor kodiert. DerMAJORUndMINORMakros oder ausgehend von einem Inode, derimajorUndiminorFunktionen sollten zum Extrahieren der Werte verwendet werden.

Einige Zeichengeräte bieten Multiplexing zusätzlich zu den oben beschriebenen Registrierungsmechanismen; sieheWie steuert ein einzelner Treiber all diese unterschiedliche Hardware?für ein Beispiel hierfür.

verwandte Informationen