Inhaltsverzeichnis
驱动层 " >驱动层
Heim Betrieb und Instandhaltung Betrieb und Wartung von Linux Linux-Treiber-IO-Artikel – mmap-Betrieb

Linux-Treiber-IO-Artikel – mmap-Betrieb

Jul 31, 2023 pm 03:55 PM
linux

Vorwort

Wenn wir Linux-Treiber schreiben und mit dem Benutzerbereich interagieren, verwenden wir normalerweise immer copy_from_userKopieren Sie die aus dem Benutzerbereich übergebenen Daten. Warum machen Sie das? copy_from_user把用户空间传过来的数据进行拷贝,为什么要这么做呢?

因为用户空间是不能直接内核空间数据的,他们映射的是不同的地址空间,只能先将数据拷贝过来,然后再操作。

如果用户空间需要传几MB的数据给内核,那么原来的拷贝方式显然效率特别低,也不太现实,那怎么办呢?

想想,之所以要拷贝是因为用户空间不能直接访问内核空间,那如果可以直接访问内核空间的buffer,是不是就解决了。

简单来说,就是让一块物理内存拥有两份映射,即拥有两个虚拟地址,一个在内核空间,一个在用户空间。关系如下:

Linux-Treiber-IO-Artikel – mmap-Betrieb

通过mmap映射就可以实现。

应用层

应用层代码很简单,主要就是通过mmap系统调用进行映射,然后就可以对返回的地址进行操作。

char * buf;
/* 1. 打开文件 */
 fd = open("/dev/hello", O_RDWR);
 if (fd == -1)
 {
      printf("can not open file /dev/hello\n");
      return -1;
 }

/* 2. mmap
       * MAP_SHARED  : 多个APP都调用mmap映射同一块内存时, 对内存的修改大家都可以看到。
       *               就是说多个APP、驱动程序实际上访问的都是同一块内存
       * MAP_PRIVATE : 创建一个copy on write的私有映射。
       *               当APP对该内存进行修改时,其他程序是看不到这些修改的。
       *               就是当APP写内存时, 内核会先创建一个拷贝给这个APP,
       *               这个拷贝是这个APP私有的, 其他APP、驱动无法访问。
       */
buf =  mmap(NULL, 1024*8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Nach dem Login kopieren

mmap的第一个参数是想要映射的起始地址,通常设置为NULLDa der Benutzerbereich nicht direkt auf Kernelbereichsdaten zugreifen kann, werden unterschiedliche Adressräume zugeordnet, sodass die Daten nur zuerst kopiert und dann bearbeitet werden können.

Wenn der Benutzerbereich mehrere MB Daten an den Kernel übertragen muss, ist die ursprüngliche Kopiermethode offensichtlich sehr ineffizient und unrealistisch. Was sollen wir also tun? 🎜🎜Denken Sie darüber nach, der Grund für das Kopieren liegt darin, dass der Benutzerbereich nicht direkt auf den Kernelbereich zugreifen kann. Wenn also direkt auf den Puffer im Kernelbereich zugegriffen werden kann, wäre das Problem gelöst? 🎜🎜🎜Einfach ausgedrückt bedeutet dies, dass ein Teil des physischen Speichers zwei Zuordnungen hat, das heißt, er hat zwei virtuelle Adressen, eine im Kernel-Bereich und eine im Benutzerbereich. 🎜Die Beziehung ist wie folgt: 🎜
Linux-Treiber-IO-Artikel – mmap-Betrieb
🎜Bymmap-Zuordnung kann erreicht werden. 🎜🎜🎜🎜🎜Anwendungsschicht🎜🎜 🎜🎜🎜Der Code der Anwendungsschicht ist sehr einfach, hauptsächlich durch mmap🎜Systemaufruf🎜 für die Zuordnung, und dann können Sie die zurückgegebene Adresse bearbeiten. 🎜
int remap_pfn_range(
  struct vm_area_struct *vma, 
  unsigned long addr, 
  unsigned long pfn, 
  unsigned long size, 
  pgprot_t prot);
Nach dem Login kopieren
Nach dem Login kopieren
🎜NULL < /code>, 🎜 bedeutet, dass der Kernel die Startadresse 🎜 bestimmt. 🎜<p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Der zweite Parameter ist die <strong>Größe des zuzuordnenden Speicherplatzes</strong>. </p><p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Der dritte Parameter<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35 , 0,05);font-family: „Operator Mono“, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">PROT_READ | PROT_WRITE Zeigt an dass der zugeordnete Raum PROT_READ | PROT_WRITE表示映射后的空间是可读可写的。

第四个参数可填MAP_SHAREDMAP_PRIVATElesbar und beschreibbar

ist. 🎜🎜Der vierte Parameter kann ausgefüllt werden
  • MAP_SHARED: MultipleAPP all call mmap Beim Zuordnen desselben Speichers kann jeder die Änderungen am Speicher sehen. Das heißt, mehrere greifen alle auf denselben Speicher zu.
  • MAP_SHARED:多个APP都调用mmap映射同一块内存时, 对内存的修改大家都可以看到。就是说多个APP、驱动程序实际上访问的都是同一块内存
  • MAP_PRIVATE:创建一个copy on write的私有映射。当APP对该内存进行修改时,其他程序是看不到这些修改的。就是当APP写内存时, 内核会先创建一个拷贝给这个APP,这个拷贝是这个APP🎜Wenn APP diesen Speicher ändert, Andere Programme Ich kann diese Änderungen nicht sehen. Das ist, wennAPPBeim Schreiben in den Speicher erstellt der Kernel zunächst eine Kopie dafürAPP, diese Kopie ist dieseAPP ist privat und kann nicht von anderen APPs und Treibern aufgerufen werden.
  • 驱动层

    驱动层主要是实现mmap接口,而mmap接口的实现,主要是调用了remap_pfn_range函数,函数原型如下:

    int remap_pfn_range(
      struct vm_area_struct *vma, 
      unsigned long addr, 
      unsigned long pfn, 
      unsigned long size, 
      pgprot_t prot);
    Nach dem Login kopieren
    Nach dem Login kopieren

    vma:描述一片映射区域的结构体指针

    addr:要映射的虚拟地址起始地址

    pfn:物理内存所对应的页框号,就是将物理地址除以页大小得到的值

    size:映射的大小

    prot:该内存区域的访问权限

    驱动主要步骤:

    1、使用kmalloc或者kzalloc函数分配一块内存kernel_buf,因为这样分配的内存物理地址是连续的,mmap后应用层会对这一个基地址去访问这块内存。

    2、实现mmap函数

    static int hello_drv_mmap(struct file *file, struct vm_area_struct *vma)
    {
     /* 获得物理地址 */
     unsigned long phy = virt_to_phys(kernel_buf);//kernel_buf是内核空间分配的一块虚拟地址空间
        
        /* 设置属性:cache, buffer*/
     vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        
        /* map */
        if(remap_pfn_range(vma, vma->vm_start, phy>>PAGE_SHFIT,
                          vma->vm_end - vma->start, vma->vm_page_prot)){
     printk("mmap remap_pfn_range failed\n");
        return -ENOBUFS;
     }
     return 0;
    }
    
    static struct file_operations my_fops = {
     .mmap = hello_drv_mmap,
    };
    Nach dem Login kopieren

    1、通过virt_to_phys将虚拟地址转为物理地址,这里的kernel_buf是内核空间的一块虚拟地址空间

    2、设置属性:不使用cache,使用buffer

    3、映射:通过remap_pfn_range函数映射,phy>>PAGE_SHIFT其实就是按page映射,除了这个参数,其他的起始地址、大小和权限都可以由用户在系统调用函数中指定

    当应用层调用mmap后,就会调用到驱动层的mmap函数,最终应用层的虚拟地址和驱动中的物理地址就建立了映射关系,应用层也就可以直接访问驱动的buffer了。

    Das obige ist der detaillierte Inhalt vonLinux-Treiber-IO-Artikel – mmap-Betrieb. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    AI Hentai Generator

    AI Hentai Generator

    Erstellen Sie kostenlos Ai Hentai.

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Unterschied zwischen CentOS und Ubuntu Unterschied zwischen CentOS und Ubuntu Apr 14, 2025 pm 09:09 PM

    Die wichtigsten Unterschiede zwischen CentOS und Ubuntu sind: Ursprung (CentOS stammt von Red Hat, für Unternehmen; Ubuntu stammt aus Debian, für Einzelpersonen), Packungsmanagement (CentOS verwendet yum, konzentriert sich auf Stabilität; Ubuntu verwendet apt, für hohe Aktualisierungsfrequenz), Support Cycle (Centos) (CENTOS bieten 10 Jahre. Tutorials und Dokumente), Verwendungen (CentOS ist auf Server voreingenommen, Ubuntu ist für Server und Desktops geeignet). Weitere Unterschiede sind die Einfachheit der Installation (CentOS ist dünn)

    CentOS 'Wahl nach der Beendigung der Wartung CentOS 'Wahl nach der Beendigung der Wartung Apr 14, 2025 pm 08:51 PM

    CentOS wurde eingestellt, Alternativen umfassen: 1. Rocky Linux (beste Kompatibilität); 2. Almalinux (kompatibel mit CentOS); 3. Ubuntu Server (Konfiguration erforderlich); 4. Red Hat Enterprise Linux (kommerzielle Version, bezahlte Lizenz); 5. Oracle Linux (kompatibel mit CentOS und RHEL). Bei der Migration sind Überlegungen: Kompatibilität, Verfügbarkeit, Unterstützung, Kosten und Unterstützung in der Gemeinde.

    So installieren Sie CentOs So installieren Sie CentOs Apr 14, 2025 pm 09:03 PM

    CentOS -Installationsschritte: Laden Sie das ISO -Bild herunter und verbrennen Sie bootfähige Medien. Starten und wählen Sie die Installationsquelle; Wählen Sie das Layout der Sprache und Tastatur aus. Konfigurieren Sie das Netzwerk; Partition die Festplatte; Setzen Sie die Systemuhr; Erstellen Sie den Root -Benutzer; Wählen Sie das Softwarepaket aus; Starten Sie die Installation; Starten Sie nach Abschluss der Installation von der Festplatte neu und starten Sie von der Festplatte.

    So verwenden Sie Docker Desktop So verwenden Sie Docker Desktop Apr 15, 2025 am 11:45 AM

    Wie benutze ich Docker Desktop? Docker Desktop ist ein Werkzeug zum Ausführen von Docker -Containern auf lokalen Maschinen. Zu den zu verwendenden Schritten gehören: 1.. Docker Desktop installieren; 2. Start Docker Desktop; 3.. Erstellen Sie das Docker -Bild (mit Dockerfile); 4. Build Docker Image (mit Docker Build); 5. Docker -Container ausführen (mit Docker Run).

    Detaillierte Erklärung des Docker -Prinzips Detaillierte Erklärung des Docker -Prinzips Apr 14, 2025 pm 11:57 PM

    Docker verwendet Linux -Kernel -Funktionen, um eine effiziente und isolierte Anwendungsumgebung zu bieten. Sein Arbeitsprinzip lautet wie folgt: 1. Der Spiegel wird als schreibgeschützte Vorlage verwendet, die alles enthält, was Sie für die Ausführung der Anwendung benötigen. 2. Das Union File System (UnionFS) stapelt mehrere Dateisysteme, speichert nur die Unterschiede, speichert Platz und beschleunigt. 3. Der Daemon verwaltet die Spiegel und Container, und der Kunde verwendet sie für die Interaktion. 4. Namespaces und CGroups implementieren Container -Isolation und Ressourcenbeschränkungen; 5. Mehrere Netzwerkmodi unterstützen die Containerverbindung. Nur wenn Sie diese Kernkonzepte verstehen, können Sie Docker besser nutzen.

    So sehen Sie den Docker -Prozess So sehen Sie den Docker -Prozess Apr 15, 2025 am 11:48 AM

    Docker Process Viewing -Methode: 1. Docker Cli -Befehl: Docker PS; 2. SYSTEMD CLI -Befehl: SystemCTL Status Docker; 3.. Docker Compose CLI Command: Docker-Compose PS; 4. Process Explorer (Windows); 5. /proc -Verzeichnis (Linux).

    Welche Computerkonfiguration ist für VSCODE erforderlich? Welche Computerkonfiguration ist für VSCODE erforderlich? Apr 15, 2025 pm 09:48 PM

    VS Code system requirements: Operating system: Windows 10 and above, macOS 10.12 and above, Linux distribution processor: minimum 1.6 GHz, recommended 2.0 GHz and above memory: minimum 512 MB, recommended 4 GB and above storage space: minimum 250 MB, recommended 1 GB and above other requirements: stable network connection, Xorg/Wayland (Linux)

    Was tun, wenn das Docker -Bild fehlschlägt? Was tun, wenn das Docker -Bild fehlschlägt? Apr 15, 2025 am 11:21 AM

    Fehlerbehebung Schritte für fehlgeschlagene Docker -Bild Build: Überprüfen Sie die Dockerfile -Syntax und die Abhängigkeitsversion. Überprüfen Sie, ob der Build -Kontext den erforderlichen Quellcode und die erforderlichen Abhängigkeiten enthält. Sehen Sie sich das Build -Protokoll für Fehlerdetails an. Verwenden Sie die Option -Target -Option, um eine hierarchische Phase zu erstellen, um Fehlerpunkte zu identifizieren. Verwenden Sie die neueste Version von Docker Engine. Erstellen Sie das Bild mit--t [Bildname]: Debugg-Modus, um das Problem zu debuggen. Überprüfen Sie den Speicherplatz und stellen Sie sicher, dass dies ausreicht. Deaktivieren Sie Selinux, um eine Störung des Build -Prozesses zu verhindern. Fragen Sie Community -Plattformen um Hilfe, stellen Sie Dockerfiles an und erstellen Sie Protokollbeschreibungen für genauere Vorschläge.

    See all articles