This is my first post so please let me know if there is any mistake from .
My aim is to get approx 150MBytes of data transfer from KERNEL to user space. [This is because i am building an driver for DMA device on OMAP l138 to transfer and receive data between DMA DEVICE and FPGA]
- Now in LINUX KERNEL i am allocating BUFFER of VARIABLE size using dma_alloc_coherent
- Then the PHYSICAL address of this buffer i am passing to user space to be user as OFFSET parameter to be used for mmap call from user space .
- Then from data is copied and read back to and from from user space to kernel
This logic work fine till size of buffer is 4096. Above 4k the mmap fails and return "MAP_FAILED"
static int driver_mmap(struct file *f, struct vm_area_struct *vma)
{
u32bit ret;
u32bit size = (vma->vm_end)-(vma->vm_start);
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (size > (NUM_PAGE*PAGE_SIZE)){
return(-1);
}
if ((ret = remap_pfn_range(vma,vma->vm_start,
(virt_to_phys((void *)krnl_area) >> PAGE_SHIFT),
size,vma->vm_page_prot)) < 0)
{
return ret;
}
printk("\nDVR:The MMAP returned %x to USER SAPCE \n",ret);
return 0;
}
//MMAP STEP 1
dmasrc_ptr = dma_alloc_coherent( NULL ,GLOBAL_BUFFER_SIZE , &dmasrc ,0);
if( !dmasrc_ptr ) {
printk(KERN_INFO "DMA_ALLOC_FAILED for the source buffer ...\n");
return -ENOMEM;
}else{
printk( "\n--->The address of SRC is %x..\n",dmasrc_ptr);
}
temp_source=dmasrc_ptr;
//MMAP STEP 2
// Round the allocated KERNEL MEMORY to the page bondary
krnl_area=(int *)((((unsigned long)dmasrc_ptr) + PAGE_SIZE - 1)&PAGE_MASK);
printk(KERN_CRIT "DVR:The KERNEL VIRTUAL ADDRS is %x..\n",krnl_area);
//MMAP STEP 3
// Marking the PAGES as RESERVED
for (i = 0; i < (NUM_PAGE * PAGE_SIZE); i+= PAGE_SIZE) {
SetPageReserved(virt_to_page(((unsigned long)krnl_area) + i));
//Application code part
while(1){
fflush(stdin);
fflush(stdout);
printf("\n\n\n----------------------------------------------------\n");
printf("USR:Please enter your requirement ");
printf("\n----------------------------------------------------\n");
printf("\t1----->GET_UPP_OFFSET\n");
printf("\t2----->UPP_MMAP_CALL\n");
printf("\t3----->IOCTL_UPP_WRITE\n");
printf("\t4----->IOCTL_UPP_READ\n");
printf("\n");
scanf("%d",&option);
printf("\nThe OPTION is %d..\n",option);
printf("\n");
switch(option){
case 1 :
{
offset=0;
ret = ioctl(dev_FD ,IOCTL_UPP_START, &info);
if (ret < 0) {
printf("dma buffer info ioctl failed\n");
}
offset = info.var;
printf("THE ADDRESS WE GOT IS %X..\n",offset);
}
break;
case 2 :
{
printf("THE OFFSET is %X..\n",offset);
mmap_Ptr= mmap(0,BUFFER_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, dev_FD, 0);
if (mmap_Ptr == MAP_FAILED){
printf("USR[UPP] :MMAP FAiled \n\n");
close(dev_FD);
exit(-1);
}
printf("THE MMAP address is %X..\n",mmap_Ptr);
}
break;
case 3:
{
struct upp_struct user_local_struct;
printf("\n***************************************************\n");
for (i = 0; i <(1024);i++) {
*(mmap_Ptr+i)=test_var;
printf("WR:%X ",*(mmap_Ptr+i));
//test_var++;
}
ioctl(dev_FD , IOCTL_UPP_WRITE ,&user_local_struct);
printf("\n***************************************************\n\n\n");
for(i=0;i<20402;i++){
//NOP
}
//test_var=0x00;
}
break;
case 4:
{
struct upp_struct user_local_struct;
ioctl(dev_FD , IOCTL_UPP_READ,&user_local_struct);
for(i=0;i<20402;i++){
//NOP
}
printf("\n***************************************************\n");
for (i = 0; i <(1024);i++) {
printf("RD:%X",*(mmap_Ptr+i));
}
printf("\n***************************************************\n\n\n");
}
break;
default:
{
printf("USR:You have entered an wrong option \n");
printf("\nUSR:CLosing the FILE ENTERIES ...\n");
munmap(mmap_Ptr,BUFFER_SIZE);
free(source_ptr);
free(dest_ptr);
close(dev_FD);
exit(0);
}
break;
} //END OF SWITCH LOOP
} //END OF WHILE LOOP
errno
? – Heath HunnicuttNUM_PAGE
1 by any chance? are you reaching driver_mmap? – Hasturkun