欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2146|回復: 0
收起左側

學習筆記-Linux 內存映射應用

[復制鏈接]
ID:140343 發表于 2016-9-24 22:33 | 顯示全部樓層 |閱讀模式
在實際應用過程中,為了更加高效率的讓用戶層與底層進行大量數據交換,可以采用內存映射的方式,將物理內存映射到進程空間內,應用程序可以直接對那塊內存進行操作從而提高效率。

貼出經過驗證的代碼,共后續分析原理使用。

驅動程序
  1. /*
  2. *    Copyright (c) 2016, Lovemengx
  3. *    All rights reserved.
  4. *
  5. *    文件名稱: zhc_led.c
  6. *    摘    要: mmap 學習驅動
  7. *
  8. *    當前版本: 1.0
  9. *    作    者: Love 夢想
  10. *    完成日期:
  11. *
  12. *    取代版本:
  13. *    原作者  :
  14. *    完成日期:
  15. */
  16. #define __ISDEBUG__                // 開啟打印信息
  17. #include <mach/zhc_public.h>
  18. #include <linux/miscdevice.h>
  19. #include <linux/delay.h>
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/init.h>
  23. #include <linux/mm.h>
  24. #include <linux/fs.h>
  25. #include <linux/types.h>
  26. #include <linux/delay.h>
  27. #include <linux/moduleparam.h>
  28. #include <linux/slab.h>
  29. #include <linux/errno.h>
  30. #include <linux/ioctl.h>
  31. #include <linux/cdev.h>
  32. #include <linux/string.h>
  33. #include <linux/list.h>
  34. #include <linux/pci.h>
  35. #include <linux/vmalloc.h>
  36. #define DEVICE_NAME "mymap"
  37. #define MALLOC_SIZE        (8192 * 100)
  38. #define USE_KMALLOC        1
  39. static unsigned char array[10]= {0,1,2,3,4,5,6,7,8,9};
  40. unsigned char     *g_mmap_buff = NULL;
  41. int             g_mmap_buff_size = MALLOC_SIZE;

  42. // 分配內存
  43. int mmap_alloc(unsigned char **mmap_buff, int require_buf_size)
  44. {
  45.     struct page     *page;
  46.     unsigned char     *mmap_buf_t;
  47.     int             mmap_size;
  48.     int                i;

  49.     mmap_size = PAGE_ALIGN(require_buf_size);

  50. #if USE_KMALLOC //for kmalloc

  51.     mmap_buf_t = kzalloc(mmap_size, GFP_KERNEL);
  52.     if (!mmap_buf_t)
  53.     {
  54.         return -1;
  55.     }
  56.     for (page = virt_to_page(mmap_buf_t ); page < virt_to_page(mmap_buf_t + mmap_size); page++)
  57.     {
  58.         SetPageReserved(page);
  59.     }

  60. #else //for vmalloc

  61.     mmap_buf_t  = vmalloc(mmap_size);
  62.     if (!mmap_buf_t )
  63.     {
  64.         return -1;
  65.     }
  66.     for (i = 0; i < mmap_size; i += PAGE_SIZE)
  67.     {
  68.         SetPageReserved(vmalloc_to_page((void *)(((unsigned long)mmap_buf_t) + i)));
  69.     }

  70. #endif
  71.    
  72.     *mmap_buff = mmap_buf_t;
  73.     return mmap_size;
  74. }

  75. void mmap_free(unsigned char *mmap_buf, int mmap_size)
  76. {

  77. #if USE_KMALLOC

  78.     struct page *page;
  79.     for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++)
  80.     {
  81.         ClearPageReserved(page);
  82.     }
  83.     kfree(mmap_buf);

  84. #else

  85.     int i;
  86.     for (i = 0; i < mmap_size; i += PAGE_SIZE)
  87.     {
  88.         ClearPageReserved(vmalloc_to_page((void *)(((unsigned long)mmap_buf) + i)));
  89.     }
  90.     vfree(mmap_buf);

  91. #endif

  92.     mmap_buf = NULL;
  93. }

  94. static int my_open(struct inode *inode, struct file *file)
  95. {
  96.     dprintk();
  97.     return 0;
  98. }

  99. static int my_map(struct file *filp, struct vm_area_struct *vma)
  100. {
  101.     int             ret;
  102.     unsigned long     pfn;
  103.     unsigned long     start = vma->vm_start;
  104.     unsigned long     size = PAGE_ALIGN(vma->vm_end - vma->vm_start);
  105.     int                i;
  106.     unsigned char     *mmap_buff = g_mmap_buff;

  107.     if (size > g_mmap_buff_size || !g_mmap_buff)
  108.     {
  109.         return -EINVAL;
  110.     }
  111.    
  112.     dprintk("g_mmap_buff = 0x%x", g_mmap_buff);
  113.     //往該內存寫10字節數據
  114.     for(i=0; i<10; i++)
  115.     {
  116.         mmap_buff[i] = array[i];
  117.     }
  118.    
  119. #if USE_KMALLOC

  120.     return remap_pfn_range(vma, start, (virt_to_phys(g_mmap_buff) >> PAGE_SHIFT), size, PAGE_SHARED);

  121. #else
  122.     /* loop over all pages, map it page individually */
  123.     while (size > 0)
  124.     {
  125.         pfn = vmalloc_to_pfn(mmap_buff);
  126.         if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0)
  127.         {
  128.             return ret;
  129.         }
  130.         start += PAGE_SIZE;
  131.         mmap_buff += PAGE_SIZE;
  132.         size -= PAGE_SIZE;
  133.     }
  134.    
  135. #endif
  136.     return 0;
  137. }

  138. static struct file_operations dev_fops =
  139. {
  140.     .owner    = THIS_MODULE,
  141.     .open    = my_open,
  142.     .mmap   = my_map,
  143. };

  144. static struct miscdevice misc =
  145. {
  146.     .minor = MISC_DYNAMIC_MINOR,
  147.     .name = DEVICE_NAME,
  148.     .fops = &dev_fops,
  149. };

  150. static ssize_t hwrng_attr_current_show(struct device *dev,
  151.                           struct device_attribute *attr,
  152.                            char *buf)
  153. {
  154.     int i;
  155.     for(i = 0; i < 10 ; i++)
  156.     {
  157.         printk("%d\n",g_mmap_buff[i]);
  158.     }
  159.     return 0;
  160. }

  161. static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR,
  162.                    hwrng_attr_current_show,
  163.                    NULL);
  164.                   
  165. static int __init dev_init(void)
  166. {
  167.     int ret;

  168.     dprintk();
  169.     //注冊混雜設備
  170.     ret = misc_register(&misc);
  171.    
  172.     //內存分配
  173.     ret = mmap_alloc(&g_mmap_buff, g_mmap_buff_size);
  174.     dprintk("ret = %d\n", ret);
  175.    
  176.     if(NULL == g_mmap_buff)
  177.     {
  178.         eprintk("g_mmap_buff => NULL");
  179.         return 0;
  180.     }
  181.     ret = device_create_file(misc.this_device,&dev_attr_rng_current);
  182.     return ret;
  183. }

  184. static void __exit dev_exit(void)
  185. {
  186.     dprintk();
  187.     //注銷設備
  188.     misc_deregister(&misc);
  189.    
  190.     mmap_free(g_mmap_buff, g_mmap_buff_size);
  191. }

  192. module_init(dev_init);
  193. module_exit(dev_exit);
  194. MODULE_LICENSE("GPL");

  195. 應用:
  196. #include <unistd.h>
  197. #include <stdio.h>
  198. #include <stdlib.h>
  199. #include <string.h>
  200. #include <fcntl.h>
  201. #include <linux/fb.h>
  202. #include <sys/mman.h>
  203. #include <sys/ioctl.h>
  204. #define PAGE_SIZE 4096 * 2

  205. int main(int argc , char *argv[])
  206. {
  207.     int fd;
  208.     int i;
  209.     unsigned char *p_map;
  210.     //打開設備
  211.     fd = open("/dev/mymap",O_RDWR);
  212.     if(fd < 0)
  213.     {
  214.         printf("open fail\n");
  215.         exit(1);
  216.     }
  217.     //內存映射
  218.     p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
  219.     if(p_map == MAP_FAILED)
  220.     {
  221.         printf("mmap fail\n");
  222.         goto here;
  223.     }
  224.      
  225.     //打印映射后的內存中的前10個字節內容
  226.     for(i=0; i<10; i++)
  227.     {
  228.         printf("%d\n",p_map[i]);
  229.         p_map[i] = i + 1;
  230.     }
  231.    
  232.     strcpy(p_map, "adcdefghij");

  233. here:
  234.     munmap(p_map, PAGE_SIZE);

  235.     return 0;
  236. }  
復制代碼



回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表