As discussed in this question, i am reserving a memory chunk at the boot time using a kernel boot parameter
memmap=8G$64G
I have written a character driver kernel module which , during initialization does a ioremap of this reserved memory chunk. As explained here , in my driver
mmap
all i need to do is remap_pfn_range
for this memory chunk pointer returned by the ioremap
.I am running this on 3.0 linux kernel. My user space application opens this memory chunk as a device mounted by the driver. When i do
mmap
from the use space application i see a system hang. mydmesg
don't provide me much information.Any inputs ?
static int __init myDev_module_init(void)
{
int retval;
myDev_major = register_chrdev(0, DEVICE_NAME, &myDevfops);
if (myDev_major < 0)
{
err("failed to register device: error %d\n", myDev_major);
retval = myDev_major;
goto FAILED_CHRDEVREG;
}
myDev_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(myDev_class))
{
err("failed to register device class '%s'\n", CLASS_NAME);
retval = PTR_ERR(myDev_class);
goto FAILED_CLASSREG;
}
myDev_device = device_create(myDev_class, NULL, MKDEV(myDev_major, 0), NULL, CLASS_NAME "_" DEVICE_NAME);
if (IS_ERR(myDev_device))
{
err("failed to create device '%s_%s'\n", CLASS_NAME, DEVICE_NAME);
retval = PTR_ERR(myDev_device);
goto FAILED_DEVREG;
}
here the
myDev.startOffset
is initialized to #define
d 64GB and myDev.memSize
to 8GB. //myDev.startAddr = ioremap(myDev.startOffset,myDev.memSize);
//memset_io(myDev.startAddr, 0, myDev.memSize);
return 0;
FAILED_DEVREG:
class_unregister(myDev_class);
class_destroy(myDev_class);
FAILED_CLASSREG:
unregister_chrdev(myDev_major, DEVICE_NAME);
FAILED_CHRDEVREG:
return -1;
}
static int myDev_device_open(struct inode* inode, struct file* filp)
{
dbg("");
if ( ((filp->f_flags & O_ACCMODE) == O_WRONLY) || ((filp->f_flags & O_ACCMODE) == O_RDWR) )
{
warn(" Opening the device with write access\n");
//return -EACCES;
}
info(" device Open is called\n");
filp->private_data = &myDev;
return 0;
}
And the
mmap
is pretty straight forward.static int myDev_device_mmap(struct file * f, struct vm_area_struct * vma)
{
int retval = 0;
struct myDevDev * pDev = (struct myDevDev *)(f->private_data);
dbg("");
if(vma)
{
if(f)
{
if(f->private_data)
warn("mmap: f->private_data : %p\n", f->private_data);
else
warn(" mmap :f->private_data : NULL \n");
}
else
{
warn("mmap: f :NULL\n");
}
warn(": mmap: vm start : %lu\n", vma->vm_start);
warn(" mmap: vm end : %lu\n", vma->vm_end);
warn(" mmap: vm pg offset : %lu\n", vma->vm_pgoff);
//retval = remap_pfn_range(vma, vma->vm_start, pDev->startOffset >> PAGE_SHIFT, pDev->memSize, PAGE_SHARED) ;
// retval = remap_pfn_range(vma, vma->vm_start, pDev->startAddr >> PAGE_SHIFT, pDev->memSize, PAGE_SHARED) ;
//retval = remap_pfn_range(vma,pDev->startAddr ,pDev->startOffset >> PAGE_SHIFT, pDev->memSize, PAGE_SHARED);
retval = remap_pfn_range(vma,vma->vm_start ,pDev->startOffset >> PAGE_SHIFT, pDev->memSize, PAGE_SHARED);
if(retval <0)
{
warn(" ERROR : in mapping kernel virtual space to user space return value : %d \n",retval);
return -EINVAL;
}
//if(0)
{
vma->vm_flags |=VM_LOCKED;
vma->vm_ops = &myRemapVMOps;
vma->vm_flags |= VM_RESERVED;
vma->vm_private_data = f->private_data;
myDevice_VMA_Open(vma);
}
}
else
{
warn ("vma is NULL");
}
dbg(" Done ");
warn("mmpaing done : \n");
return 0;
}
from my user space application i am doing the following :
int err, i=0;
void * mptr = NULL;
printf(" Access the reserved memory chunk \n ");
int fd = open("/dev/myDevice", O_RDWR | O_SYNC);
if(fd <=0)
{
printf("ERROR: my device driver is not loaded \n");
return 1;
}
printf("\n mmaping mem chunk size :%llu pagesize :%lu input mptr :%p\n", sz,getpagesize (), mptr);
mptr = mmap(0, sz , PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0);
if(mptr == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
printf("\nmmapped mem address %p\n",mptr);
exit(1);
}
printf("\nmmapped mem address %p\n",mptr);
//char * ptr = (char *)mptr;
//*ptr = 'a';
//int * pInt = (int *) (((char *) mptr)+1);
//for(;i<10000; ++i)
{
// pInt[i] = 2*i;
}
/* free the mmapped memory
*/
if (munmap(mptr, sz) == -1)
{
perror("Error un-mmapping the file");
}
close(fd);
Answers;-
You can use standard phram driver in steps to access your memory from userspace. No coding is needed. Kernel recompilation at maximum.
Do You really have more then 64Gb of RAM? Does Your hardware really support it?
0 comments:
Post a Comment