2016-06-20 10 views
0

Я пытаюсь отобразить зарезервированную память (30M со смещением 2G) во время загрузки (параметры загрузочного ядра mem = 2G memmap = 30M $ 2G) в пользовательское пространство, используя remap_pfn_range, ниже мой код драйвера:map reserver memory при загрузке в пользовательское пространство с помощью remap_pfn_range

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/init.h> 
#include <linux/fs.h> 
#include <linux/mm.h> 
#include <asm/uaccess.h> 
// #include <asm/error.h> 

#define MAP_MAJOR 150 

#define RAW_DATA_SIZE 0x1E00000 // 30 Mo 
#define RAW_DATA_OFFSET 0x80000000 //2G 

int results; 
static void *rawdataStart = NULL; 

static int map_mmap(struct file *filp, struct vm_area_struct *vma); 

struct file_operations map_fops = { 
     .open = nonseekable_open, 
     .mmap = map_mmap 
}; 

static int map_mmap(struct file *filp, struct vm_area_struct *vma) { 
    if (rawdataStart == NULL) { 
     printk(KERN_ERR "Memory not mapped!\n"); 
     return -EAGAIN; 
    } 
    if ((vma->vm_end - vma->vm_start) != RAW_DATA_SIZE) { 
     printk(KERN_ERR "Error: sizes don't match (buffer size = %d, requested size = %lu)\n", RAW_DATA_SIZE, vma->vm_end - vma->vm_start); 
     return -EAGAIN; 
    } 
    results = remap_pfn_range(vma, vma->vm_start, RAW_DATA_OFFSET >> PAGE_SHIFT, RAW_DATA_SIZE, PAGE_SHARED); 
    if (results != 0) { 
     printk(KERN_ERR "Error in calling remap_pfn_range: returned %d\n", results); 
     return -EAGAIN; 
    } 

    return 0; 
} 

static int __init map_init(void) 
{ 

    printk("init map module\n"); 

    if (register_chrdev(MAP_MAJOR,"mapReserved", &map_fops) <0) 
    { 
     printk("unable to get major for map module\n"); 
     return -EBUSY; 
    } 


    rawdataStart = ioremap(RAW_DATA_OFFSET, RAW_DATA_SIZE); 
    if (rawdataStart == NULL) { 
     printk(KERN_ERR "Unable to remap memory\n"); 
     return 1; 
    } 
    printk(KERN_INFO "ioremap returned %p\n", rawdataStart); 

    return 0; 
} 

void __exit map_cleanup(void) 
{ 
    printk("exit map module\n"); 
    unregister_chrdev(MAP_MAJOR,"mapReserved"); 
    if (rawdataStart != NULL) { 
     printk(KERN_INFO "Unmapping memory at %p\n", rawdataStart); 
     iounmap(rawdataStart); 
    } else { 
     printk(KERN_WARNING "No memory to unmap!\n"); 
    } 

    return; 
} 

MODULE_LICENSE("GPL"); 

module_init(map_init); 
module_exit(map_cleanup); 

и мое пользовательское пространство приложение ниже

#include <sys/mman.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdio.h> 

#define RAW_DATA_SIZE 0x1E00000 


int main(void) 
{ 
    void * data; 
    int fd = open("/dev/mapReserved", O_RDWR); 
    if (fd == -1) { 
     perror("open error...\n"); 
     return -1; 
    } 
    data = mmap(NULL, RAW_DATA_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 4096); 
    close(fd); 
    return 0; 
} 

, когда я вставить модуль это вернуть

[ 873.621763] init map module 
[ 873.623175] ioremap returned fb580000 

но когда я уверен, выполнение пространства приложения пользователя это ошибка возврата

open error... 

ответ

0

Я решил эту проблему, после этих ссылок:

1- Reserve memory in Linux driver module and share it using driver mmap

2- mmap of several GB of reserved memory using

в в моем случае я резервирую 30M со смещения 2G и внизу - код

модуль:

// #include <linux/config.h> 
#include <linux/module.h> 
#include <linux/moduleparam.h> 
#include <linux/init.h> 
#include <linux/debugfs.h> 
#include <linux/kernel.h> /* printk() */ 
#include <linux/slab.h> /* kmalloc() */ 
#include <linux/fs.h>  /* everything... */ 
#include <linux/errno.h> /* error codes */ 
#include <linux/types.h> /* size_t */ 
#include <linux/mm.h> 
#include <linux/kdev_t.h> 
#include <asm/page.h> 
#include <linux/cdev.h> 

#include <linux/device.h> 

#ifndef VM_RESERVED 
# define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP) 
#endif 

#define RAW_DATA_SIZE 31457280 
#define RAW_DATA_OFFSET 0x80000000UL 

void *rawdataStart; 

struct dentry *file; 



/* 
* Open the device; in fact, there's nothing to do here. 
*/ 
int simple_open (struct inode *inode, struct file *filp) 
{ 
    return 0; 
} 


/* 
* Closing is just as simpler. 
*/ 
static int simple_release(struct inode *inode, struct file *filp) 
{ 
    return 0; 
} 



static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma) 
{ 

    int ret; 
     unsigned long mapoffset; 
     mapoffset = RAW_DATA_OFFSET + (vma->vm_pgoff << PAGE_SHIFT); 
     ret = remap_pfn_range(vma, vma->vm_start, mapoffset >> PAGE_SHIFT, 
           vma->vm_end - vma->vm_start, PAGE_SHARED); 

     if (ret != 0) { 
      printk("Error remap_pfn_range. \n"); 
      return -EAGAIN; 
     } 
     return 0; 
} 

/* Device uses remap_pfn_range */ 
static struct file_operations simple_remap_ops = { 
    .owner = THIS_MODULE, 
    .open = simple_open, 
    .release = simple_release, 
    .mmap = simple_remap_mmap, 
}; 

/* 
* Module housekeeping. 
*/ 
static int simple_init(void) 
{ 
    file = debugfs_create_file("mmap_example", 0644, NULL, NULL, &simple_remap_ops); 
    rawdataStart = ioremap(RAW_DATA_OFFSET, RAW_DATA_SIZE); 
    if (rawdataStart!=NULL){ 
     printk("rawdataStart at:%p \n", rawdataStart); 
     memset(rawdataStart, 'c', 20971520); 
     memset(rawdataStart+20971520, '$', 100); 

    }else{ 
     printk("rawdataStart is NULL \n"); 
     return -1; 
    } 



    return 0; 
} 


static void simple_cleanup(void) 
{ 
    debugfs_remove(file); 
    if (rawdataStart != NULL) { 
      printk(KERN_INFO "Unmapping memory at %p\n", rawdataStart); 
      iounmap(rawdataStart); 
     } else { 
      printk(KERN_WARNING "No memory to unmap!\n"); 
     } 
} 


module_init(simple_init); 
module_exit(simple_cleanup); 
MODULE_AUTHOR("Jonathan Corbet"); 
MODULE_LICENSE("Dual BSD/GPL"); 

и пространство пользователя Приложение:

#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/mman.h> 

#define RAW_DATA_SIZE 31457280 

int main(int argc, char **argv) { 
    int configfd; 
    char * address = NULL; 
    unsigned long chkSum; 
    FILE *fp = fopen("results.log", "w+"); 

    configfd = open("/sys/kernel/debug/mmap_example", O_RDWR); 
    if (configfd < 0) { 
     perror("Open call failed"); 
     return -1; 
    } 

    address = (unsigned char*) mmap(NULL, RAW_DATA_SIZE, PROT_WRITE, 
      MAP_PRIVATE, configfd, 0); 
    if (address == MAP_FAILED) { 
     perror("mmap operation failed"); 
     return -1; 
    } 

    fputs(address, fp); 
    fclose(fp); 

    close(configfd); 
    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^