2016-03-22 6 views
0

Ich versuche ein einfaches Programm zu machen. der Quellcode ist unten. Ich versuche, etwas Speicher zu füllen, wenn das Modul einfügt. Dann freien Speicher, wenn Modul entfernen. Aber ich benutze Befehl frei und festgestellt, dass es keinen Speicher freigibt, wenn Modul entfernen.Warum funktioniert kfree im Linux-Treiber nicht, wenn der Datenzeiger in der Funktion übergeben wird?

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/proc_fs.h> 
#include <linux/fs.h> 
#include <linux/mm.h> 
#include <linux/vmalloc.h> 

#define FILE_NAME  "test" 

typedef struct info 
{ 
    char data[1048576]; 
}sInfo; 

static sInfo* Info; 

int mmap_alloc2(void* buf, int require_buf_size) 
{ 
    struct page *page; 
    void* mmap_buf; 

    unsigned long mmap_size = PAGE_ALIGN(require_buf_size); 
    printk("size=%lu\n",mmap_size); 
    buf = kzalloc(mmap_size, GFP_KERNEL); 
    if (!buf) { 
     return -1; 
    } 
    mmap_buf = buf; 
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) { 
     SetPageReserved(page); 
    } 

    return 0; 
} 

void mmap_free2(void* buf, int require_buf_size) 
{ 
    struct page *page; 
    void *mmap_buf = buf; 

    unsigned long mmap_size = PAGE_ALIGN(require_buf_size); 
    printk("size=%lu\n",mmap_size); 
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) { 
     ClearPageReserved(page); 
    } 
    kfree((sInfo*)buf); 
    mmap_buf = NULL; 
} 

static int mmap_example_init(void) 
{ 
    struct proc_dir_entry *pEntry = NULL; 
    printk("mmap example init\n"); 

    if(!(pEntry = create_proc_entry(FILE_NAME, 0666, NULL))) 
    { 
     printk("create proc entry fail\n"); 
     return -EFAULT; 
    } 

    mmap_alloc2(Info, sizeof(sInfo)); 
    return 0; 
} 

static void mmap_example_exit(void) 
{ 
    printk("mmap example exit\n"); 
    mmap_free2(Info, sizeof(sInfo)); 
    remove_proc_entry(FILE_NAME,NULL); 
} 

module_init(mmap_example_init); 
module_exit(mmap_example_exit); 

Aber wenn ich Datenzeiger von Funktion zu globalen Bereich ändern, funktioniert kfree. Code ist unten.

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/proc_fs.h> 
#include <linux/fs.h> 
#include <linux/mm.h> 
#include <linux/vmalloc.h> 


#define FILE_NAME  "test" 

static void* mmap_buf; 
typedef struct info 
{ 
    char data[1048576]; 
}sInfo; 

static sInfo* Info; 

int mmap_alloc1(int require_buf_size) 
{ 
    struct page *page; 

    int mmap_size = PAGE_ALIGN(require_buf_size); 
    mmap_buf = kzalloc(mmap_size, GFP_KERNEL); 
    if (!mmap_buf) { 
     return -1; 
    } 
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) { 
     SetPageReserved(page); 
    } 

    return 0; 
} 

void mmap_free1(int require_buf_size) 
{ 
    struct page *page; 
    unsigned long mmap_size = PAGE_ALIGN(require_buf_size); 
    for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) { 
     ClearPageReserved(page); 
    } 
    kfree(mmap_buf); 
    mmap_buf = NULL; 
} 


static int mmap_example_init(void) 
{ 
    struct proc_dir_entry *pEntry = NULL; 
    printk("mmap example init\n"); 

    if(!(pEntry = create_proc_entry(FILE_NAME, 0666, NULL))) 
    { 
     printk("create proc entry fail\n"); 
     return -EFAULT; 
    } 
    mmap_alloc1(sizeof(sInfo)); 
    return 0; 
} 

static void mmap_example_exit(void) 
{ 
    printk("mmap example exit\n"); 
    mmap_free1(sizeof(sInfo)); 
    remove_proc_entry(FILE_NAME,NULL); 
} 

module_init(mmap_example_init); 
module_exit(mmap_example_exit); 

also was ist der Unterschied in diesen beiden Code? und wie man Sample1 ändert, um kfree zu arbeiten?

Antwort

0

Im ersten Codebeispiel ordnen Sie den Speicher zu, aber Sie weisen die Adresse nicht wirklich der Zeigervariablen Info zu. Und dein mmap_buf ist eine lokale Variable, die im ersten Fall nichts wirklich macht. Sie versuchen also, eine zufällige Adresse freizugeben. Das kann oder kann nicht funktionieren. In der Regel ist es nicht und definitiv nicht das, was Sie versuchen zu befreien.

können Sie entweder machen mmap_alloc2() gibt den Zeiger und weisen Sie auf Info, wie Info = mmap_alloc2(sizeof(sInfo)); oder die Adresse Info an die Funktion übergeben, wie, int mmap_alloc2(void **buf, int require_buf_size) und *buf = kzalloc(mmap_size, GFP_KERNEL);. Nennen Sie es mit mmap_alloc2(&Info, sizeof(sInfo));

+0

danke für die Hilfe. Es lösen. –