Erste Schritte mit dem Erlernen von Gerätetreibern

1. In welche Kategorien unterteilt Linux Geräte?

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

2. Hierarchie der Gerätetreiber

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

3. Der Prozess des Benutzerprozesses, der Gerätedienste anfordert

Fügen Sie hier eine Bildbeschreibung ein

4. Jedes bisschen Fahren

Was ist ein Fahrer?

(1) Der Treiber ist die Brücke zwischen Software und Hardware.
(2) Treiber sind spezielle Programme, die dem Betriebssystem hinzugefügt werden.
(3) Ein Treiber ist ein spezielles Programm, das die Kommunikation zwischen einem Computer und einem Gerät ermöglicht.

Warum brauchen Sie einen Fahrer?

(1) Das Softwaresystem kann das anzuschließende Gerät und seine Funktionen nicht direkt identifizieren.
(2) Hardwaregeräte können nur elektronische Signale verstehen und vom Softwaresystem ausgegebene Befehle nicht direkt verstehen.

Wer hat den Fahrer hergestellt?

​ Treiber sind Konfigurationsdateien, die von Hardwareherstellern basierend auf dem Betriebssystem geschrieben werden.

Die Rolle des Fahrers

Der Treiber ist die Brücke zwischen Software und Hardware

​ (1) Informieren Sie das Betriebssystem über die Funktionen der Hardware selbst und schließen Sie die gegenseitige Übersetzung zwischen den elektronischen Signalen des Hardwaregeräts und der höheren Programmiersprache (Java usw.) des Betriebssystems und der Software ab.
(2) Übermitteln Sie die Standardanweisungen des Betriebssystems an das Hardwaregerät.
(3) Wenn das Betriebssystem bestimmte Hardware verwenden muss, z. B. um die Soundkarte Musik abspielen zu lassen, sendet es zunächst die entsprechenden Anweisungen an den Soundkartentreiber. und der Soundkartentreiber empfängt. Danach wird es sofort in elektronische Signalbefehle übersetzt, die nur von der Soundkarte verstanden werden können, wodurch die Soundkarte Musik abspielen kann.

5. Welche Funktion hat die Struktur file_operations()?

Die file_operations-Struktur schließt das Lesen, Schreiben, Speichern usw. des Geräts ab. Diese Vorgänge werden alle von diesen in der file_operations-Struktur gespeicherten Funktionszeigern verarbeitet. Die Funktionen, auf die diese Funktionszeiger zeigen, müssen im Treibermodul implementiert werden.

struct file_operations {
	struct module *owner;    //拥有该结构的模块的指针,一般为THIS_MODULES
	......
	int (*mmap) (struct file *, struct vm_area_struct *);    //用于请求将设备内存映射到进程地址空间
	......
	int (*open) (struct inode *, struct file *);    //打开
	......
}

6.Welche Rolle spielt die Gerätenummer im Treiber? Warum brauchen wir eine Hauptgerätenummer und eine Nebengerätenummer?

Jede Datei ist ein Gerät und die Gerätenummer besteht aus einer Hauptgerätenummer und einer Nebengerätenummer.

Hauptgerätenummer:

  1. Es wird allgemein angenommen, dass eine Hauptgerätenummer einem Treiber entspricht
  2. Ein Treiber kann mehrere Geräte verwalten, d. h. eine Hauptgerätenummer entspricht mehreren Geräten
  3. Eine Hauptgerätenummer kann auch mehreren Treibern entsprechen

Nebengerätenummer:

  1. Eine Nebengerätenummer entspricht einem Gerät

Ein Treiber kann mehrere Geräte dieses Typs verwalten, und die Anzahl der Geräte kann 2 hoch 20 betragen. Der Grund dafür ist, dass die Nebengerätenummer 20 Ziffern hat, es aber unmöglich ist, tatsächlich so viele Geräte zu haben.

7. Was sind die Treiberregistrierungs- und Deregistrierungsfunktionen von Charaktergeräten? Warum müssen Sie sich anmelden und stornieren?

Registrierte Funktionen für Zeichengerätetreiber:

static inline int register_chrdev(unsigned int major, const char *name,
				  const struct file_operations *fops)
{
	return __register_chrdev(major, 0, 256, name, fops);
}
/*__register_chrdev() - 创建并注册一个占有较小大小的字符设备
  major:主设备号,当用户设置为0时,内核会动态分配一个设备号。
  baseminor: 次设备号,要在一定范围内从0开始
  count: 次设备号的范围
  name: 设备名称
  fops: 文件系统的接口指针
  
  如果major == 0,此函数将动态分配一个major并返回它的编号。
  如果major > 0,此函数将尝试使用给定的主设备号来保留设备,成功时将返回0。
  
  失败时返回-ve errno。
*/
int __register_chrdev(unsigned int major, unsigned int baseminor,
		      unsigned int count, const char *name,
		      const struct file_operations *fops)
{
	struct char_device_struct *cd;
	struct cdev *cdev;
	int err = -ENOMEM;

	cd = __register_chrdev_region(major, baseminor, count, name);	//注册一个主设备号和一个一定范围内具体的次设备号
	if (IS_ERR(cd))
		return PTR_ERR(cd);

	cdev = cdev_alloc();	//分配空间
	if (!cdev)
		goto out2;
	//对cdev进行赋值操作
	cdev->owner = fops->owner;
	cdev->ops = fops;
	kobject_set_name(&cdev->kobj, "%s", name);

	err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);	//把这个设备添加到系统中
	if (err)
		goto out;

	cd->cdev = cdev;	//完成cd与cdev的关联

	return major ? 0 : cd->major;
out:
	kobject_put(&cdev->kobj);
out2:
	kfree(__unregister_chrdev_region(cd->major, baseminor, count));
	return err;
}

Funktion zur Aufhebung der Registrierung für den Zeichengerätetreiber:

static inline void unregister_chrdev(unsigned int major, const char *name)
{
	__unregister_chrdev(major, 0, 256, name);
}
void __unregister_chrdev(unsigned int major, unsigned int baseminor,
			 unsigned int count, const char *name)
{
	struct char_device_struct *cd;

	cd = __unregister_chrdev_region(major, baseminor, count);
	if (cd && cd->cdev)
		cdev_del(cd->cdev);
	kfree(cd);
}

Durch die Registrierung wird der entsprechende Gerätetreiber zur Verwendung generiert

Durch das Abmelden wird Speicher freigegeben, damit andere Prozesse ausgeführt werden können.

8.I/O-Ports und I/O-Speicher

Wenn es sich im E/A-Bereich befindet, wird es oft als E/A-Port bezeichnet

Wenn sich der entsprechende Speicherplatz im Speicher befindet, wird er als E/A-Speicher bezeichnet

Fügen Sie hier eine Bildbeschreibung ein

9. Lesen und schreiben Sie den globalen Speicher im Zeichengerät im Anwenderprogramm

Fügen Sie hier eine Bildbeschreibung ein

10. Registrieren Sie den Blockgerätetreiber

Fügen Sie hier eine Bildbeschreibung ein

11. Der Unterschied zwischen Blockgeräten und Zeichengeräten

Fügen Sie hier eine Bildbeschreibung ein

(1) Das Dateisystem kann auf Blockgeräten gemountet werden, jedoch nicht auf Zeichengeräten. Dies ist offensichtlich ein Vorteil des Direktzugriffs, da das Dateisystem in der Lage sein muss, Daten in Blöcken zu speichern und außerdem in der Lage sein muss, Daten zufällig zu lesen und zu schreiben.

(2) Daten, die ein Blockgerät durchlaufen, müssen im Vergleich zum Betrieb eines Zeichengeräts eine Datenpufferschicht durchlaufen. Das heißt, wenn die Anwendung Daten an ein Blockgerät überträgt, interagiert sie nicht direkt mit dem Zeichengerät, sondern muss eine Zwischenpufferschicht durchlaufen, um die Daten zu speichern. Erst dann können die Daten verwendet werden, um die Gesamtsystemleistung (Durchsatz) zu verbessern.

(3) Die Schnittstelle des Zeichentreibers ist relativ klar und einfach zu verwenden, die Schnittstelle des Blocktreibers ist jedoch etwas komplizierter. Dafür gibt es zwei Gründe: Zum einen liegt es an seiner Geschichte – die Blocktreiberschnittstelle ist seit der ersten Version in jeder Linux-Version vorhanden und hat sich als schwierig zu modifizieren oder zu verbessern erwiesen; die Leistung, ein langsamer Zeichengerätetreiber ist unerwünscht, aber immer noch akzeptabel , aber ein langsamer Blocktreiber beeinträchtigt die Gesamtsystemleistung. Daher wird das Schnittstellendesign eines Blocktreibers häufig von Geschwindigkeitsanforderungen beeinflusst.

Supongo que te gusta

Origin blog.csdn.net/qq_58538265/article/details/133916635
Recomendado
Clasificación