pamięć mapowania zarezerwowana przez parametr parowania jądra mmap w przestrzeni użytkownika

Jak omówiono wto pytanie, rezerwuję fragment pamięci w czasie rozruchu za pomocą parametru startowego jądramemmap=8G$64G

Napisałem asterownik znaków moduł jądra, którypodczas inicjalizacji wykonuje ioremap tej zarezerwowanej porcji pamięci. Jak wyjaśnionotutaj w moim kierowcymmap wszystko, co muszę zrobić, toremap_pfn_range dla tego wskaźnika fragmentu pamięci zwróconego przezioremap.

Używam tego3.0 jądro linux. Moja aplikacja przestrzeni użytkownika otwiera tę część pamięci jako urządzenie zamontowane przez sterownik. Kiedy robięmmap z aplikacji przestrzeni kosmicznej widzęzawiesić system. mójdmesg nie dostarczaj mi wielu informacji.

Jakieś dane wejściowe?

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;
   }

tutajmyDev.startOffset jest zainicjowany do#defined 64 GB imyDev.memSize do 8 GB.

 //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;
 }

Immap jest całkiem prosty.

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;
}

z mojej aplikacji przestrzeni użytkownika wykonuję następujące czynności:

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);

Obserwacja:

Nie widzę, by rozmiar odbijał się w(vma->vm_end - vma->vm_start) który z jakiegoś powodu jestZAWSZE 4K.

questionAnswers(2)

yourAnswerToTheQuestion