我的mmap只有能映射16k内存空间,帮我看一下
本帖最后由 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={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);
printf("4100 2 = %d !\n",fb_mem);
printf("4100 3 = %d !\n",fb_mem);
printf("4100 4 = %d !\n",fb_mem);
}
if (i==2*4096+10)
{
printf("4200 1 = %d !\n",fb_mem);
printf("4200 2 = %d !\n",fb_mem);
printf("4200 3 = %d !\n",fb_mem);
printf("4200 4 = %d !\n",fb_mem);
}
if (i==3*4096+10)
{
printf("4300 1 = %d !\n",fb_mem);
printf("4300 2 = %d !\n",fb_mem);
printf("4300 3 = %d !\n",fb_mem);
printf("4300 4 = %d !\n",fb_mem);
}
if (i==4*4096+2) //这里用+2,而不是+10,可以看得更仔细。
{
printf("4400 1 = %d !\n",fb_mem);
printf("4400 2 = %d !\n",fb_mem);
printf("4400 3 = %d !\n",fb_mem);
printf("4400 4 = %d !\n",fb_mem);
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的 以上才是66;,但进行赋值的时候,会把fb_mem-由原来的11,变为66了。
由于是(i==4*4096+2),因此fb_mem还是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);
}
-----------------------------------------------------------------------------------
谢谢,
实在话,这段代码有点晕,确认是对的? 问题找到了,对于6410来说,它的dram地址从0x5000_0000开始。
因此需要将offset = offset + mem_start * 1024 * 1024;
改为offset = offset + 0x5000_0000+120 * 1024 * 1024;就工作正常了。
页:
[1]