So erstellen Sie einen eingebetteten Linux-Gerätetreiber (2)

Zweites Mal: Registrieren von Systemaufrufhandlern und -treibern (statische Methode)

Über diese Serie

HowTo-Artikel zum Entwickeln eingebetteter Linux-Gerätetreiber als Kernelmodule. Der gesamte Inhalt dieses Artikels kann auf Raspberry Pi ausgeführt werden.

Der gesamte Quellcode, der in diesem Artikel angezeigt wird

https://github.com/take-iwiw/DeviceDriverLesson/tree/master/02_01

Inhalt dieser Zeit

Ermöglichen Sie Benutzern den Zugriff auf Gerätetreiber auf die alte (?) Weise. Letztes Mal habe ich eine Halo-Welt-ähnliche Sache erstellt, die nur Handler bereitstellt, wenn ein Modul geladen / entladen wird (insmod / rmmod). Öffnen / schließen Sie diesmal das eigentliche Programm oder die Shell, damit der Wert gelesen / geschrieben werden kann. Implementieren Sie dazu die Verarbeitung für Systemaufrufe wie Öffnen / Schließen / Lesen / Schreiben. Außerdem registriert der Benutzer das Gerät im Kernel, um auf diesen Gerätetreiber als Gerätedatei (/ dev / XXX) zuzugreifen. Dieses Mal ist das Gerät fest statisch registriert. Diese Methode ist alt und scheint jetzt veraltet zu sein, aber ich werde diesen Schritt unternehmen, um sie zu verstehen.

Makefile zum Erstellen

Da es nur eine Datei gibt, bereiten Sie das folgende Makefile vor. Erstellen Sie MyDeviceModule.ko aus dem Quellcode myDeviceDriver.c.

CFILES = myDeviceDriver.c

obj-m := MyDeviceModule.o
MyDeviceModule-objs := $(CFILES:.c=.o)

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

Quellcode des Gerätetreibers

myDeviceDriver.c


#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/uaccess.h>

#define DRIVER_NAME "MyDevice_NAME"
#define DRIVER_MAJOR 63

/*Funktion beim Öffnen aufgerufen*/
static int myDevice_open(struct inode *inode, struct file *file)
{
	printk("myDevice_open\n");
	return 0;
}

/*Funktion wird beim Schließen aufgerufen*/
static int myDevice_close(struct inode *inode, struct file *file)
{
	printk("myDevice_close\n");
	return 0;
}

/*Funktion beim Lesen aufgerufen*/
static ssize_t myDevice_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	printk("myDevice_read\n");
	buf[0] = 'A';
	return 1;
}

/*Funktion zum Zeitpunkt des Schreibens aufgerufen*/
static ssize_t myDevice_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	printk("myDevice_write\n");
	return 1;
}

/*Handlertabelle für verschiedene Systemaufrufe*/
struct file_operations s_myDevice_fops = {
	.open    = myDevice_open,
	.release = myDevice_close,
	.read    = myDevice_read,
	.write   = myDevice_write,
};

/*Straße(insmod)Funktionen, die manchmal aufgerufen werden*/
static int myDevice_init(void)
{
	printk("myDevice_init\n");
	/*★ Registrieren Sie diesen Treiber im Kernel*/
	register_chrdev(DRIVER_MAJOR, DRIVER_NAME, &s_myDevice_fops);
	return 0;
}

/*Entladen(rmmod)Funktionen, die manchmal aufgerufen werden*/
static void myDevice_exit(void)
{
	printk("myDevice_exit\n");
	unregister_chrdev(DRIVER_MAJOR, DRIVER_NAME);
}

module_init(myDevice_init);
module_exit(myDevice_exit);

Definition des Handlers für den Systemaufruf

Definieren Sie eine Handlerfunktion für Systemaufrufe (Öffnen, Schließen, Lesen, Schreiben) des Benutzers. Dieses Mal werde ich vorerst nur ein Protokoll ausgeben oder einen festen Wert zurückgeben. Speichern Sie diese Funktionen in s_myDevice_fops.

Registrieren Sie den Treiber im Kernel

Wenn das Modul geladen wird (dh in myDevice_init), wird dieser Gerätetreiber von der Funktion register_chrdev im Kernel als Zeichengerät registriert. "Die Hauptnummer dieses Gerätetreibers ist DRIVER_MAJOR (63) und der Name ist DRIVER_NAME (" MyDevice_NAME "). Die Handlertabelle für jeden Systemaufruf befindet sich in" s_myDevice_fops "", sagt er. Die hier angegebene Hauptnummer ist eine sehr wichtige Nummer zur Identifizierung des Geräts.

Übrigens scheinen die Hauptnummern 60-63, 120-127, 240-254 reservierte Nummern für lokale Experimente zu sein. Deshalb habe ich diesmal 63 verwendet.

Funktionsprüfung

Bauen und laden

Erstellen und laden Sie mit dem folgenden Befehl.

make
sudo insmod MyDeviceModule.ko

Überprüfen Sie danach die Liste der registrierten Geräte. Dann können Sie, wie im Code registriert, sehen, dass dieses Gerät ("MyDevice_NAME") anstelle von Zeichengeräten als Kennzahl 63 registriert ist.

cat /proc/devices
Character devices:
  1 mem
Kürzung
 63 MyDevice_NAME

Erstellen Sie eine Gerätedatei für den Benutzerzugriff

Benutzer greifen normalerweise über Gerätedateien auf Gerätetreiber zu. Ich werde die Gerätedatei vorbereiten. Verwenden Sie dazu den Befehl mknod. Das erste Argument ist der Name der Gerätedatei. Das ist mit allem in Ordnung. Das zweite Argument ist der Gerätetyp. Diesmal ist es ein Zeichengerät, also setze c. Das dritte Argument ist die Hauptnummer des Geräts, die der zu erstellenden Gerätedatei entspricht. Dies sollte mit der zuvor erstellten Gerätetreibernummer übereinstimmen. Diesmal war es 63, also geben Sie 63 an. Das vierte Argument ist die kleine Zahl. Es wird verwendet, um zu unterscheiden, wenn mehrere Gerätedateien für dasselbe Gerät erstellt werden. Setzen Sie vorerst 1.

Ändern Sie nach dem Erstellen von / dev / myDevice mit mknod das Zugriffsrecht, damit jeder darauf zugreifen kann.

sudo mknod /dev/myDevice c 63 1
sudo chmod 666 /dev/myDevice

ls -la /dev
crw-rw-rw-  1 root root    63,   1 Dec 17 23:08 myDevice

Versuchen Sie, aus der Shell zu lesen und zu schreiben

Um den Vorgang zu überprüfen, können Sie C-Code schreiben, der das diesmal erstellte / dev / myDevice öffnet, es liest / schreibt und schließt. Der Einfachheit halber überprüfen Sie es jedoch über die Shell.

Überprüfen Sie zunächst das Schreiben mit dem folgenden Befehl

echo "a" > /dev/myDevice
dmesg

Wenn Sie sich das Protokoll mit dmesg nach der Ausgabe des Befehls ansehen, können Sie sehen, dass die implementierte Schreibfunktion aufgerufen wird. Ich denke, es wird zweimal wegen 'a'und' \ 0 'aufgerufen. Auch Öffnen und Schließen werden automatisch aufgerufen.

[11974.888831] myDevice_open
[11974.888934] myDevice_write
[11974.888944] myDevice_write
[11974.888968] myDevice_close

Überprüfen Sie als Nächstes das Lesen mit dem folgenden Befehl.

cat /dev/myDevice

Wenn Sie diesen Befehl eingeben, wird 'A' endlos auf der Konsole ausgegeben. Beenden Sie ihn daher bitte mit Strg-c. Dies liegt daran, dass die Funktion myDevice_read immer einen Wert zurückgibt. Tatsächlich sollte es 0 zurückgeben, wenn keine Werte mehr zu lesen sind.

Verarbeitung beenden

Wenn Sie damit fertig sind, entladen Sie den Gerätetreiber mit dem folgenden Befehl und löschen Sie die Gerätedatei. Da es sich um einen Gerätetreiber handelt, denke ich nicht, dass es ein tatsächlicher Anwendungsfall ist, um die Verwendung zu beenden, aber ich denke, dass er beim Debuggen verwendet wird. Sobald die Gerätedatei (/ dev / myDevice) erstellt wurde, ruft der Kernel den neu geladenen Gerätetreiber auf, solange die Hauptnummer dieselbe ist, unabhängig davon, wie viele Gerätetreiber rmmod und insmod sind. Es scheint, dass es herauskommen wird.

sudo rmmod MyDeviceModule
sudo rm /dev/myDevice

Recommended Posts

So erstellen Sie einen eingebetteten Linux-Gerätetreiber (11)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (1)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (4)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (7)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (2)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (3)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (6)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (5)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (10)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (9)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (12) (vollständig)
Wie man Yubico Yubikey von Manjaro Linux erkennt
So erstellen Sie ein interaktives CLI-Tool mit Golang
So erstellen Sie einen HTTPS-Server mit Go / Gin
[Python] Erstellen einer Adjazenzmatrix / Adjazenzliste [Graphentheorie]
So erstellen Sie ein Hacking-Labor - Kali Linux (2020.1) VirtualBox 64-Bit Teil 2-
So erstellen Sie ein Hacking-Labor - Kali Linux (2020.1) VirtualBox 64-Bit-Edition -
Wie erstelle ich ein Python-Paket (geschrieben für Praktikanten)
So erstellen Sie eine ISO-Datei (CD-Image) unter Linux
Wie erstelle ich eine japanisch-englische Übersetzung?
Wie man einen lockeren Bot macht
So installieren Sie VMware-Tools unter Linux
Wie erstelle ich einen Crawler?
So erstellen Sie eine rekursive Funktion
So installieren Sie MBDyn (Linux Ubuntu)
[Blender] So erstellen Sie ein Blender-Plug-In
[Blender] So erstellen Sie Blender-Skripte mehrsprachig
Wie erstelle ich einen Crawler?
So erstellen Sie den MongoDB C-Sprachtreiber
So überprüfen Sie die Linux-Betriebssystemversion
So machen Sie einen String in Python zu einem Array oder ein Array zu einem String
So bringen Sie den Druckertreiber für Oki Mac in Linux
So machen Sie Word Cloud-Zeichen monochromatisch
Wie baue ich meinen eigenen Linux-Server?
Wie man Selen so leicht wie möglich macht
[Linux] Unterteilen von Dateien und Ordnern
So erstellen Sie einen LINE-Bot mit künstlicher Intelligenz mit der Flask + LINE Messaging-API
So installieren Sie das aws-session-manager-Plugin unter Manajro Linux
python3 So installieren Sie ein externes Modul
Ich möchte wissen, wie LINUX funktioniert!
[Linux] Verwendung des Befehls echo
So aktualisieren Sie PHP unter Amazon Linux 2
So zeigen Sie Piktogramme unter Manjaro Linux an
So installieren Sie Pakete unter Alpine Linux
[Cocos2d-x] So erstellen Sie eine Skriptbindung (Teil 2)
So bedienen Sie Linux von der Konsole aus
So installieren Sie das Windows-Subsystem für Linux
So schalten Sie Linux unter Ultra96-V2 aus
So aktualisieren Sie die Sicherheit unter CentOS Linux 8
Ich möchte ein Automatisierungsprogramm erstellen!
Wie installiere ich php7.4 unter Linux (Ubuntu)
So machen Sie Multi-Boot-USB (Windows 10-kompatibel)
So erstellen Sie einen benutzerdefinierten Backtrader-Indikator
Wie erstelle ich eine Pelican Site Map?