Linux記憶體映射(mmap)

來源:互聯網
上載者:User

一. 概述

          記憶體映射,簡而言之就是將使用者空間的一段記憶體區域對應到核心空間,映射成功後,使用者對這段記憶體地區的修改可以直接反映到核心空間,相反,核心空間對這段地區的修改也直接反映使用者空間。那麼對於核心空間<---->使用者空間兩者之間需要大量資料轉送等操作的話效率是非常高的。

        首先,驅動程式先分配好一段記憶體,接著使用者進程通過庫函數mmap()來告訴核心要將多大的記憶體映射到核心空間,核心經過一系列函數調用後調用對應的驅動程式的file_operation中的mmap函數,在該函數中調用remap_pfn_range()來建立映射關係。直白一點就是:驅動程式在mmap()中利用remap_pfn_range()函數將核心空間的一段記憶體與使用者空間的一段記憶體建立映射關係。

使用者空間mmap()函數:

void *mmap(void *start, size_t length, int prot, int flags,int fd, off_t offset)

start:使用者進程中要映射的某段記憶體地區的起始地址,通常為NULL(由核心來指定)

length:要映射的記憶體地區的大小

prot:期望的記憶體保護標誌

flags:指定映射對象的類型

fd:檔案描述符(由open函數返回)

offset:要映射的使用者空間的記憶體地區在核心空間中已經分配好的的記憶體地區中的位移。大小為PAGE_SIZE的整數倍

 

二. 實現

         首先在驅動程式分配一頁大小的記憶體,然後使用者進程通過mmap()將使用者空間中大小也為一頁的記憶體映射到核心空間這頁記憶體上。映射完成後,驅動程式往這段記憶體寫10個位元組資料,使用者進程將這些資料顯示出來。

驅動程式:

 1 #include <linux/miscdevice.h> 2 #include <linux/delay.h> 3 #include <linux/kernel.h> 4 #include <linux/module.h> 5 #include <linux/init.h> 6 #include <linux/mm.h> 7 #include <linux/fs.h> 8 #include <linux/types.h> 9 #include <linux/delay.h>10 #include <linux/moduleparam.h>11 #include <linux/slab.h>12 #include <linux/errno.h>13 #include <linux/ioctl.h>14 #include <linux/cdev.h>15 #include <linux/string.h>16 #include <linux/list.h>17 #include <linux/pci.h>18 #include <linux/gpio.h>19 20 21 #define DEVICE_NAME "mymap"22 23 24 static unsigned char array[10]={0,1,2,3,4,5,6,7,8,9};25 static unsigned char *buffer;26 27 28 static int my_open(struct inode *inode, struct file *file)29 {30     return 0;31 }32 33 34 static int my_map(struct file *filp, struct vm_area_struct *vma)35 {    36     unsigned long page;37     unsigned char i;38     unsigned long start = (unsigned long)vma->vm_start;39     //unsigned long end =  (unsigned long)vma->vm_end;40     unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);41 42     //得到物理地址43     page = virt_to_phys(buffer);    44     //將使用者空間的一個vma虛擬記憶體區映射到以page開始的一段連續物理頁面上45     if(remap_pfn_range(vma,start,page>>PAGE_SHIFT,size,PAGE_SHARED))//第三個參數是頁幀號,由物理地址右移PAGE_SHIFT得到46         return -1;47 48     //往該記憶體寫10位元組資料49     for(i=0;i<10;i++)50         buffer[i] = array[i];51     52     return 0;53 }54 55 56 static struct file_operations dev_fops = {57     .owner    = THIS_MODULE,58     .open    = my_open,59     .mmap   = my_map,60 };61 62 static struct miscdevice misc = {63     .minor = MISC_DYNAMIC_MINOR,64     .name = DEVICE_NAME,65     .fops = &dev_fops,66 };67 68 69 static int __init dev_init(void)70 {71     int ret;    72 73     //註冊混雜裝置74     ret = misc_register(&misc);75     //記憶體配置76     buffer = (unsigned char *)kmalloc(PAGE_SIZE,GFP_KERNEL);77     //將該段記憶體設定為保留78     SetPageReserved(virt_to_page(buffer));79 80     return ret;81 }82 83 84 static void __exit dev_exit(void)85 {86     //登出裝置87     misc_deregister(&misc);88     //清除保留89     ClearPageReserved(virt_to_page(buffer));90     //釋放記憶體91     kfree(buffer);92 }93 94 95 module_init(dev_init);96 module_exit(dev_exit);97 MODULE_LICENSE("GPL");98 MODULE_AUTHOR("LKN@SCUT");

應用程式:

 1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <fcntl.h> 6 #include <linux/fb.h> 7 #include <sys/mman.h> 8 #include <sys/ioctl.h>  9 10 #define PAGE_SIZE 409611 12 13 int main(int argc , char *argv[])14 {15     int fd;16     int i;17     unsigned char *p_map;18     19     //開啟裝置20     fd = open("/dev/mymap",O_RDWR);21     if(fd < 0)22     {23         printf("open fail\n");24         exit(1);25     }26 27     //記憶體映射28     p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);29     if(p_map == MAP_FAILED)30     {31         printf("mmap fail\n");32         goto here;33     }34 35     //列印映射後的記憶體中的前10個位元組內容36     for(i=0;i<10;i++)37         printf("%d\n",p_map[i]);38     39 40 here:41     munmap(p_map, PAGE_SIZE);42     return 0;43 }

先載入驅動後執行應用程式,使用者空間列印如下:

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.