2015-08-10 3 views
1

Я пытаюсь отобразить буфер ядра в пространстве пользователя с помощью метода mmap в linux 3.10.10. Но он возвращает MAP_FAILED. Почему он не отображает буфер.Почему mmap, определенный в модуле ядра Linux, возвращает MAP_FAILED?

модуль ядра

#include <linux/module.h> /* Needed by all modules */ 
#include <linux/kernel.h> /* Needed for KERN_ALERT */ 
#include <linux/init.h>   /* Needed for the macros */ 
#include <linux/proc_fs.h> 
#include <asm/uaccess.h> 
#include <linux/interrupt.h> 
#include <linux/io.h> 
#include <linux/init.h> 
#include <linux/pci.h> 
#include <linux/slab.h> 
#include <sound/core.h> 
#include <sound/initval.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/proc_fs.h> 
#include <asm/uaccess.h> 
#include <linux/interrupt.h> 
#include <linux/io.h> 
//#include <linux/malloc.h> 

#include <linux/mm.h> /* mmap related stuff */ 

long long *buf1; 
long long* buf; 


static int driver_mmap(struct file *file, struct vm_area_struct *vma) 
{ 
    vma->vm_flags |= VM_LOCKED|VM_SHARED; 

    int i = remap_pfn_range(vma, vma->vm_start, 
      virt_to_phys(buf) >> PAGE_SHIFT, 
      vma->vm_end-vma->vm_start, vma->vm_page_prot); 

    SetPageReserved(virt_to_page(buf)); 
    printk("MMAP \n"); 
    return 0; 
} 


struct file_operations proc_fops = 
{ 
    mmap:driver_mmap, 
}; 
int init_module_test(void) 
{ 
    int i; 
    buf1 = kmalloc(4096, __GFP_COLD|GFP_DMA); 

    buf = ((int)buf1 + PAGE_SIZE -1) & PAGE_MASK; 
    printk("<1>Hello world1\n"); 
    for (i = 0; i < 512; i++) 
    { 
    buf[i] = (long long) i + 1; 
    } 
    proc_create ("mmap_example",0,NULL, &proc_fops); 
    printk("<1>Hello world3\n"); 
    printk("<1>BUF1 = 0x%08x\n BUF = 0x%08x\n", buf1,buf); 
    return 0; 
} 


void cleanup_module_test(void) 
{ 
    remove_proc_entry ("mmap_example", NULL); 
    kfree(buf1); 
    printk("Goodbye world\n"); 
} 



module_init(init_module_test); 
module_exit(cleanup_module_test); 

Код приложения

#include<stdio.h> 
#include<stdlib.h> 
#include<sys/mman.h> 

int main(void) 
{ 
    int fd, i; 
    long long *msg = NULL; 

    if ((fd = fopen("/proc/mmap_example", "r")) < 0) 
    { 
    printf("File not opened"); 
    } 
    msg = mmap(NULL, 4096, PROT_READ, MAP_SHARED, fd, 0); 
    if (msg == MAP_FAILED) 
    { 
    printf("MAP failed"); 
    return 0; 
    } 
    for (i = 0; i < 512; i++) 
    printf("0x%llx,", msg[i]); 

    fclose(fd); 
    return 0; 
} 

Я всегда в конечном итоге Seing "MAP failed". Что-то не так с моим кодом?

+1

не должно быть 'mmap: driver_mmap,' в инициализации структуры '.mmap = driver_mmap'? – mch

+0

Я думаю, не имеет значения. –

+0

@mch, вы предложили унаследованный способ инициализации полей структуры. На современном C мы используем шаблон '.field = value,'. – 0andriy

ответ

2

Первая проблема заключается в том, что вы пытаетесь использовать fopen, чтобы открыть файл и поместить возвращаемое значение в целое число, но fopen не возвращает целое число. Он возвращает FILE *. Это говорит о том, что вы игнорируете предупреждения и ошибки компилятора. Это плохая идея: они созданы не просто так.

Вторая проблема заключается в том, что вам действительно нужен дескриптор целочисленного файла, чтобы предоставить его в качестве аргумента для mmap(2). Для этого вам следует позвонить open(2) (неfopen(3)).

Возможно, возникли дополнительные проблемы с этим кодом, но это начало.

+0

спасибо, что сделал трюк для меня .. –

1

хорошо, я не могу комментировать, так что я отправить ответ, что это не один, но я надеюсь, что это будет по-прежнему полезно:

я не уверен, о водителе, но вы можете использовать метод Errno (http://man7.org/linux/man-pages/man3/errno.3.html) на ттар, чтобы иметь лучший ответ на то, почему он терпит неудачу:

добавить в код приложения в нужном месте:

#include <errno.h> 
printf("%i",errno); 

или вы могли бы, возможно, использовать следующее, если вы не хотите напечатать errno:

cpp -dM /usr/include/errno.h | grep 'define E' | sort -n -k 3 

из How to know what the 'errno' means?

+0

Я получаю Bad дескриптор файла в errno –

+0

Пока вы сказали, что этот ответ не один, он точно приводит к ответу на вопрос :-) Плохой дескриптор файла ---> fopen не работает. – Damon

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