remap_pfn_range を使用して、ブート時に予約済みメモリ (2G のオフセットで 30M) (ブート カーネル パラメータ mem=2G memmap=30M$2G) をユーザー空間にマップしようとしています。 以下は私のドライバー コードです。
#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...