免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1239 | 回复: 2
打印 上一主题 下一主题

[学习分享] mmap疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-23 09:40 |只看该作者 |倒序浏览
在学习mmap,找了个网上的示例,修改了下。
驱动如下:
  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. #define DEVICE_NAME "mymap"
  20. static unsigned char *buffer;
  21. static int my_open(struct inode *inode, struct file *file)
  22. {
  23.      return 0;
  24. }


  25. static int my_map(struct file *filp, struct vm_area_struct *vma)
  26. {   
  27.      unsigned long page;
  28.      unsigned char i;
  29.      unsigned long start = (unsigned long)vma->vm_start;
  30.      //unsigned long end =  (unsigned long)vma->vm_end;
  31.      unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);

  32.      page = virt_to_phys(buffer);
  33.      if(remap_pfn_range(vma,start,page>>PAGE_SHIFT,size,PAGE_SHARED))
  34.          return -1;
  35.      for(i=0;i<1000;i++)
  36.          buffer[i] = i;
  37.      
  38.      return 0;
  39. }


  40. static struct file_operations dev_fops = {
  41.      .owner    = THIS_MODULE,
  42.      .open    = my_open,
  43.      .mmap   = my_map,
  44. };

  45. static struct miscdevice misc = {
  46.      .minor = MISC_DYNAMIC_MINOR,
  47.      .name = DEVICE_NAME,
  48.      .fops = &dev_fops,
  49. };


  50. static int __init dev_init(void)
  51. {
  52.      int ret;
  53.      ret = misc_register(&misc);
  54.      buffer = (unsigned char *)kmalloc(16*PAGE_SIZE,GFP_KERNEL);
  55.      //将该段内存设置为保留
  56.      SetPageReserved(virt_to_page(buffer));

  57.      return ret;
  58. }


  59. static void __exit dev_exit(void)
  60. {
  61.      //注销设备
  62.      misc_deregister(&misc);
  63.      //清除保留
  64.      ClearPageReserved(virt_to_page(buffer));
  65.      //释放内存
  66.      kfree(buffer);
  67. }


  68. module_init(dev_init);
  69. module_exit(dev_exit);
  70. MODULE_LICENSE("GPL");
  71. MODULE_AUTHOR("somebody");
复制代码
用于测试的代码如下:
  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. #define PAGE_SIZE 4096
  10. int main(int argc , char *argv[])
  11. {
  12.      int fd;
  13.      int i;
  14.      unsigned char *p_map;
  15.      
  16.      //打开设备
  17.      fd = open("/dev/mymap",O_RDWR);
  18.      if(fd < 0)
  19.      {
  20.          printf("open fail\n");
  21.          exit(1);
  22.      }

  23.      //内存映射
  24.      p_map = (unsigned char *)mmap(0, 16*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
  25.      if(p_map == MAP_FAILED)
  26.      {
  27.          printf("mmap fail\n");
  28.          goto here;
  29.      }

  30.      for(i=0;i<1000;i++)
  31.          printf("%d\n",p_map[i]);
  32.      

  33. here:
  34.      munmap(p_map,16*PAGE_SIZE);
  35.      return 0;
  36. }
复制代码
当我把那个i修改到200还是可以的,能够正确打印出数值,但改为1000就不行了,串口控制终端得不到响应,过了30秒左右,开发板重启了。重启是看门狗的作用,看门狗驱动里面设置的是30s。
求问这个mmap的问题出在哪里,如何才能映射成功1000个甚至10000个数值呢?

论坛徽章:
0
2 [报告]
发表于 2012-11-01 09:06 |只看该作者
我不太懂,我在Linux设备驱动程序书上看到这么一句话,remap_pfn_range不允许重新映射常规地址,这包括get_free_page函数所获得的地址,我想你用kmalloc分配的地址应该是这个常规地址,这个是不允许重新映射的吧,不知道是不是这样...

论坛徽章:
0
3 [报告]
发表于 2012-11-01 13:59 |只看该作者
我错了,试了一下应该是可以的。估计是这一句buffer[i] = i有问题,buffer是一个char数组,最大应该只能到255.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP