久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2104|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

學(xué)習(xí)筆記-Linux 內(nèi)存映射應(yīng)用

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:140343 發(fā)表于 2016-9-24 22:33 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
在實(shí)際應(yīng)用過(guò)程中,為了更加高效率的讓用戶層與底層進(jìn)行大量數(shù)據(jù)交換,可以采用內(nèi)存映射的方式,將物理內(nèi)存映射到進(jìn)程空間內(nèi),應(yīng)用程序可以直接對(duì)那塊內(nèi)存進(jìn)行操作從而提高效率。

貼出經(jīng)過(guò)驗(yàn)證的代碼,共后續(xù)分析原理使用。

驅(qū)動(dòng)程序
  1. /*
  2. *    Copyright (c) 2016, Lovemengx
  3. *    All rights reserved.
  4. *
  5. *    文件名稱: zhc_led.c
  6. *    摘    要: mmap 學(xué)習(xí)驅(qū)動(dòng)
  7. *
  8. *    當(dāng)前版本: 1.0
  9. *    作    者: Love 夢(mèng)想
  10. *    完成日期:
  11. *
  12. *    取代版本:
  13. *    原作者  :
  14. *    完成日期:
  15. */
  16. #define __ISDEBUG__                // 開(kāi)啟打印信息
  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. // 分配內(nèi)存
  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.     //往該內(nèi)存寫10字節(jié)數(shù)據(jù)
  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.     //注冊(cè)混雜設(shè)備
  170.     ret = misc_register(&misc);
  171.    
  172.     //內(nèi)存分配
  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.     //注銷設(shè)備
  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. 應(yīng)用:
  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.     //打開(kāi)設(shè)備
  211.     fd = open("/dev/mymap",O_RDWR);
  212.     if(fd < 0)
  213.     {
  214.         printf("open fail\n");
  215.         exit(1);
  216.     }
  217.     //內(nèi)存映射
  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.     //打印映射后的內(nèi)存中的前10個(gè)字節(jié)內(nèi)容
  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. }  
復(fù)制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 一区二区在线不卡 | 欧美黄色一区 | 美日韩精品| 国产视频2021 | 亚洲精品99| 北条麻妃国产九九九精品小说 | 国产69久久精品成人看动漫 | 日韩电影a | 五月婷婷色 | 狠狠av| 少妇一级淫片aaaaaaaaa | 午夜在线| 日韩在线免费 | 精品一区二区三区电影 | 99re6在线视频精品免费 | 国产日韩欧美精品一区二区 | 国产精品久久久久久久久久 | 亚洲激精日韩激精欧美精品 | 日韩一级免费电影 | 亚洲一区二区视频 | 国产成人精品一区二区三区四区 | 亚洲精品自在在线观看 | 九九久久国产 | 91视视频在线观看入口直接观看 | 精品自拍视频 | 七七婷婷婷婷精品国产 | 人人干人人艹 | 性一交一乱一伦视频免费观看 | 国产精品久久久久婷婷二区次 | 91精品国产美女在线观看 | 国产成人免费视频网站高清观看视频 | 欧美日韩视频 | 久久不射网 | 日韩高清中文字幕 | 一区二区三区回区在观看免费视频 | 日韩成人在线播放 | 亚洲码欧美码一区二区三区 | 成人老司机| 一级毛片免费完整视频 | 视频一区中文字幕 | 国产成人av一区二区三区 |