seven_007 *nix forums beginner
Joined: 30 Sep 2006
Posts: 2
|
Posted: Sat Sep 30, 2006 3:10 am Post subject:
Linux2.6 mmap problem, pls help me
|
|
|
Intention:
application need share large number data with driver code. ioctl() function need some time for copy from user mode to kernel mode, so now i want to use mmap() function
Problem:
application mmap() a buf of kernel, return success, but cannt read the data in this buf(it is initialize as 0x89, but app read the data is 0),when application change the value of this buf, driver access the buf and get the old data(still 0x89)
please help me. thanks
Source code:
------------------------------------------driver code--------------------------------------
#define MAXNALBUFNUM 2 //Seven added for MMAP function
#define MAXNALLENGTH 0x10000 //64k
char *H264InputBuf =NULL;
static int h264_open(struct inode *inode, struct file *filp)
{
if((H264InputBuf = kmalloc(MAXNALBUFNUM*MAXNALLENGTH, GFP_KERNEL)) != NULL)
{
memset(H264InputBuf, 0x78, 512); //first initialize it as 0x78
}
else
{
printk("!!!!!!!!ERROR: H264 kmalloc failure ... \n");
return -1;
}
printk("addr = 0x%x\n",(unsigned long)H264InputBuf); //addr=0xc2f00000
return 0;
}
static int h264_mmap (struct file *file, struct vm_area_struct *vma)
{
unsigned long page,pos;
unsigned long start = (unsigned long)vma->vm_start;
unsigned long size = (unsigned long)(vma->vm_end-vma->vm_start);
printk("h264_mmap, start:%x,end:%x,size:%x\n",
vma->vm_start, vma->vm_end, size); //start:400e3000, end:40103000, size:20000
if(size > MAXNALBUFNUM*MAXNALLENGTH)
return -1;
printk("1 prot: 0x%x\n",(vma->vm_page_prot)); //prot:0x5f
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
printk("2 prot: 0x%x\n",(vma->vm_page_prot)); //prot:0x53
pos=(unsigned long) H264InputBuf;
page = virt_to_phys((void *)pos);
printk("pos addr:%x, phyaddr:%x\n",pos,page); //pos addr:c2f00000, phyaddr:32f00000
#if 0
if (remap_page_range( vma,
vma->vm_start, //Virtual addr
page, //Physical addr
vma->vm_end - vma->vm_start, //size
vma->vm_page_prot //protect
//PAGE_SHARED
) != 0)
#else
if(remap_pfn_range( vma,
vma->vm_start, //virtual addr
page>>PAGE_SHIFT, //Physical addr
vma->vm_end - vma->vm_start, //size
vma->vm_page_prot //protect
//PAGE_SHARED
)!=0)
#endif
{
return -EAGAIN;
}
#if 1
memset(H264InputBuf, 0x89, 512); //now initialize it as 0x89
printk("h264_mmap success and now the value is \n");
for(size = 0; size < 16; size ++)
printk("%x, ",H264InputBuf[size]); //89,89…
#endif
//printk("h264_mmap success\n");
return 0;
}
---------------------------------Application code---------------------
int H264Start(void)
{
int ret = 0, i=0, len = 256;
char *str = NULL;
//1, open device
if((_dev_h264_fd = open("/dev/misc/H264", O_RDONLY)) == -1)
{
DEBUGMSG(1,("Fail in open() #######%s \n", strerror(errno)));
return -1;
}
//2, mmap
str = (char *)mmap(NULL,MAXNALBUFNUM * MAXNALLENGTH,PROT_READ | PROT_WRITE, MAP_PRIVATE,_dev_h264_fd,0);
if(str == MAP_FAILED)
{
printf("mmap error = %d\n",errno);
perror("h264mmap ");
return -1;
}
printf("straddr=0x%x\n",(unsigned long)str);
…
//3, Read the map buf data
printf("Get old value=");
for(i=0;i<len;i++)
{
if(i%16==0)
printf("\n");
printf("%x, ",str[i]); //not 0x89, but 0, why?
}
for(i=0;i<10000*10;i++);
//4, wirte data to share memory and inform driver
for(i=0;i<len;i++)
str[i] = i;
msync(str,len,MS_SYNC);
…… //driver read the buf is still 0x89………,why?
//6, demmap share memroy
munmap(str,MAXNALBUFNUM * MAXNALLENGTH);
return 0;
}
void H264Exit(void)
{
DEBUGMSG(1,("H264 Release\n"));
if(_dev_h264_fd)
{
close(_dev_h264_fd);
_dev_h264_fd = 0;
}
}
int main(int argc, char *argv[])
{
H264Start();
H264Exit();
return 0;
} |
|