免费注册 查看新帖 |

Chinaunix

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

[内存管理] 我的mmap只有能映射16k内存空间,帮我看一下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-20 13:27 |只看该作者 |倒序浏览
本帖最后由 pricechen 于 2014-08-20 13:32 编辑

背景:通过s3c6410硬件加速功能实现图像旋转,
          6410旋转寄存器需要源地址和目标地址,必须是连续的物理地址。

方法:
         外面ram128M,通过uboot参数传递mem=120M,开辟了一个连续的物理地址块8M。
         在驱动中ioremap(0x7800000, 0x800000);就可以对该ram进行操作了。
         然后为了映射给应用程序。 在驱动的 dev_fops中添加.mmap= chen_mmap
       在应用程序中,调用
unsigned char* fb_mem;
fd = open("/dev/wrtc", O_RDWR);
fb_mem = mmap (NULL, 500*4096, PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
这样应用程序就可以把源图片存放在fb_mem中,我在驱动中对这个物理地址开始的图片进行选择。


但是我通过对fb_mem赋值,发现只有前面16k映射是有效的,只要大于16k,就会把前面相应的数据覆盖掉。
----------测试程序----------------------------------------------------------------------
unsigned char tmp_fb[4*800*600]={0};
memset (tmp_fb, 66, 5*4096);
memset (tmp_fb, 44, 4*4096);
memset (tmp_fb, 33, 3*4096);
memset (tmp_fb, 22, 2*4096);
memset (tmp_fb, 11, 4096);
fd = open("/dev/wrtc", O_RDWR);
//4*800*600=1920000;500*4096=2048000
fb_mem = mmap (NULL, 500*4096, PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

int i;
for (i=0;i<1920000;i++)
{
  fb_mem=tmp_fb;
  if (i==1*4096+10)
{
    printf("4100 1 = %d !\n",fb_mem[0]);
    printf("4100 2 = %d !\n",fb_mem[1]);
    printf("4100 3 = %d !\n",fb_mem[2]);
    printf("4100 4 = %d !\n",fb_mem[3]);
}
  if (i==2*4096+10)
  {
    printf("4200 1 = %d !\n",fb_mem[0]);
    printf("4200 2 = %d !\n",fb_mem[1]);
    printf("4200 3 = %d !\n",fb_mem[2]);
    printf("4200 4 = %d !\n",fb_mem[3]);
  }

  if (i==3*4096+10)
{
    printf("4300 1 = %d !\n",fb_mem[0]);
    printf("4300 2 = %d !\n",fb_mem[1]);
    printf("4300 3 = %d !\n",fb_mem[2]);
    printf("4300 4 = %d !\n",fb_mem[3]);
  }
  if (i==4*4096+2)    //这里用+2,而不是+10,可以看得更仔细。
  {
    printf("4400 1 = %d !\n",fb_mem[0]);
    printf("4400 2 = %d !\n",fb_mem[1]);
    printf("4400 3 = %d !\n",fb_mem[2]);
    printf("4400 4 = %d !\n",fb_mem[3]);
  sleep(1);
  }
}
打印信息:只要大于4*4096以后,就开始覆盖了。
4100 1 = 11 !
4100 2 = 11 !
4100 3 = 11 !
4100 4 = 11 !
4200 1 = 11 !
4200 2 = 11 !
4200 3 = 11 !
4200 4 = 11 !
4300 1 = 11 !
4300 2 = 11 !
4300 3 = 11 !
4300 4 = 11 !
4400 1 = 66 !
4400 2 = 66 !
4400 3 = 66 !
4400 4 = 11 !
如上,tmp_fb的 [4*4096]以上才是66;,但进行赋值的时候,会把fb_mem[0]-[2]由原来的11,变为66了。
由于是(i==4*4096+2),因此fb_mem[3]还是11
请帮我看一下,是什么原因?
应该用什么方法解决。



----------驱动中----------------------------------------------------------------------
int chen_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;
if (size > 8 *1024 * 1024)
{
printk("size too big\n");
return ( - ENXIO);
}
offset = offset + mem_start * 1024 * 1024;    //mem_start=120
/* we do not want to have this area swapped out, lock it */
vma->vm_flags |= VM_LOCKED;
        vma->vm_flags |= VM_IO;
        vma->vm_flags |= VM_RESERVED;
if (remap_pfn_range(vma, vma->vm_start, offset>> PAGE_SHIFT, size, PAGE_SHARED))
{
printk("remap page range failed\n");
return - ENXIO;
}
return (0);
}
-----------------------------------------------------------------------------------
谢谢,            






论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-08-20 23:14 |只看该作者
实在话,这段代码有点晕,确认是对的?

论坛徽章:
0
3 [报告]
发表于 2014-08-21 13:34 |只看该作者
问题找到了,对于6410来说,它的dram地址从0x5000_0000开始。
因此需要将offset = offset + mem_start * 1024 * 1024;
改为offset = offset + 0x5000_0000+120 * 1024 * 1024;就工作正常了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP