Forum Discussion
Altera_Forum
Honored Contributor
12 years agoI REALY AM STUMPPED... Any help would be GREATLY APPRECIATED!!
I added the following to mmap to my device driver: static int my_mmap(struct file * filp, struct vm_area_struct * vma) { int ret; printk( KERN_DEBUG "IN MYDRIVER MMAP\n"); long length = vma->vm_end - vma->vm_start; printk(KERN_DEBUG "length %d PageSize %d [%d]\n", length , PAGE_SIZE, MY_NPAGES*PAGE_SIZE); /* check length - do not allow larger mappings than the number of pages allocated */ if (length > MY_NPAGES * PAGE_SIZE) return -EIO; printk(KERN_DEBUG "before remap_pfn_range\n" ); /* map the whole physically contiguous area in one piece */ if ((ret = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)kmalloc_area) >> PAGE_SHIFT, length, vma->vm_page_prot)) < 0) { printk(KERN_DEBUG "ret %l [%l]\n", ret); return ret; } printk(KERN_DEBUG "return 0\n" ); return 0; } GLOBALLY I HAVE: static int *kmalloc_area; // original pointer for kmalloc'd area as returned by kmalloc static void *kmalloc_ptr; # define MY_NPAGES 16 /// 100 In the init of the device driver I have: /* allocate a memory area with kmalloc. Will be rounded up to a page boundary */ if ((kmalloc_ptr = kmalloc((MY_NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) == NULL) { ret = -ENOMEM; goto out; } /* round it up to the page bondary */ kmalloc_area = (int *)((((unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK); strcpy(kmalloc_area,"scmd_mmap test data"); for (i = 0; i < (MY_NPAGES * PAGE_SIZE / sizeof(int)); i += 2) { kmalloc_area[i] = (0xdead << 16) + i; kmalloc_area[i + 1] = (0xbeef << 16) + i; } AND IN USER SPACE I DO THE FOLLOWING: # define DevName "/dev/myDriver0" static unsigned int * mmapResult; if ((fdPlayback = open("/dev/myDriver0", O_RDWR | O_NONBLOCK | O_SYNC)) < 0) { perror("DevNameIO"); printf("error opening device %s\n", DevName); return -1; } mmapResult = (unsigned int *)mmap (0, MY_NPAGES*PAGE_SIZE, PROT_WRITE | PROT_READ , MAP_SHARED | MAP_FILE | MAP_FIXED , fdPlayback, 0 ); ///////// printf("AFTER -- mmap call [%d] MAP_FAILED {%d}\n", mmapResult, MAP_FAILED); printf("userspace waiting ---- \n"); usleep(5000000); if ( mmapResult == (unsigned int *)MAP_FAILED ) { printf("mmap error for output\n"); perror("BOH"); return -1; } When I run my tstMmu program I get: Open dev_is_open 1 INODE major 240 minor 0 IN PB9X-MMAP length 65536 PageSize 4096 [65536] before remap_pfn_range return 0 CLOSING--> dev_is_open 0 INODE major 240 minor 0 SEGV ***************************************************************************************** SO -- what is NOT HAPPY? The close of the device driver gets executed before the SEGV Do I need something else to use the memory? I read an example where they have to do a 'mknod node c driverMajor# 0' and they opened up "node." I haven't tried this but if that is what I need to do is there somewhere I can read to explain this for me?