删除linux内核模块

时间:2014-08-04 18:33:42

标签: linux-kernel linked-list kernel kernel-module

我创建了一个利用linux内核宏的模块。问题是我安装模块但我无法删除模块。我需要帮助的是删除模块。

#include <linux/init.h>  
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/random.h>

struct birthday {
    int day;
    int month;
    int year;
    struct list_head list;
};

struct birthday *my_bday, *tmp, *ptr;
struct list_head *pos;

int simple_init(void)
{
    int i, day,month,year;
    my_bday = kmalloc(sizeof(*my_bday), GFP_KERNEL);
    my_bday->day = 30;
    my_bday->month=5;
    my_bday->year=1984;

    /* set my_bday to head of list*/

    INIT_LIST_HEAD(&(my_bday->list));
    printk(KERN_INFO "Loading Module\n");
    for(i=0; i<5; ++i){
        ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);    
        //random birthday variables
    get_random_bytes(&day, 1);
    ptr->day = day % 31;
    if(ptr->day < 0)
        ptr->day = ptr->day * -1;

    get_random_bytes(&month, 1);
    ptr->month = month % 12;

    if(ptr->month < 0)
        ptr->month = ptr->month * -1;

    get_random_bytes(&year, 1);
    ptr->year = (year % 2000)+1900;

    if(ptr->year < 0)
        ptr->year = ptr->year * -1;

    list_add(&(ptr->list), &(my_bday->list));
    }

    printk(KERN_INFO "traversing the list using list_for_each()\n");
    list_for_each(pos, &(my_bday->list)){
        tmp = list_entry(pos, struct birthday, list);
        printk("day = %d month = %d year = %d\n", tmp->day, tmp->month, tmp->year);
    }
    return 0;
}

void simple_exit(void)
{
    printk(KERN_INFO "Removing Module\n");  
    list_for_each(pos, &(my_bday->list)){
        tmp = list_entry(pos, struct birthday, list);
        list_del(&tmp->list);
        kfree(tmp);
    }

}

module_init(simple_init);

module_exit(simple_exit);

dmesg缓冲区读取以下内容:

[  477.267204] birthday: module license 'unspecified' taints kernel.
[  477.267296] Disabling lock debugging due to kernel taint
[  477.317017] Loading Module
[  477.317480] traversing the list using list_for_each()
[  477.317593] day = 7 month = 2 year = 2049
[  477.317630] day = 29 month = 9 year = 2135
[  477.317637] day = 2 month = 11 year = 2070
[  477.317642] day = 14 month = 2 year = 2081
[  477.317647] day = 9 month = 7 year = 1912
[  505.151618] Removing Module
[  505.152957] BUG: unable to handle kernel paging request at 00100104
[  505.154584] IP: [<f9dd8236>] cleanup_module+0x36/0xe00 [birthday]
[  505.155878] *pdpt = 0000000009f2c001 *pde = 0000000000000000 
[  505.156251] Oops: 0002 [#1] SMP 
[  505.156802] Modules linked in: birthday(POF-) nls_utf8 isofs vmxnet(OF)    snd_ens1371   snd_ac97_codec ac97_bus gameport snd_pcm snd_page_alloc snd_seq_midi  snd_seq_midi_event vmw_balloon snd_rawmidi snd_seq serio_raw snd_seq_device vmwgfx snd_timer joydev snd ttm rfcomm bnep drm bluetooth soundcore vmw_vmci i2c_piix4 shpchp parport_pc ppdev mac_hid lp parport hid_generic psmouse pcnet32 mptspi mptscsih mii mptbase floppy vmw_pvscsi vmxnet3 usbhid hid
[  505.157903] CPU: 0 PID: 3289 Comm: rmmod Tainted: PF O 3.13.0-32-generic #57-Ubuntu
[  505.157978] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop        Reference Platform, BIOS 6.00 07/02/2012
[  505.158266] task: d0a419e0 ti: f68ac000 task.ti: f68ac000
[  505.158514] EIP: 0060:[<f9dd8236>] EFLAGS: 00010287 CPU: 0
[  505.158653] EIP is at cleanup_module+0x36/0xe00 [birthday]
[  505.158812] EAX: cd874820 EBX: f9dda000 ECX: 00200200 EDX: 00100100
[  505.158864] ESI: 00000800 EDI: 00000000 EBP: f68adf3c ESP: f68adf38
[  505.158921]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[  505.159041] CR0: 8005003b CR2: 00100104 CR3: 0d9f5000 CR4: 000007f0
[  505.159474] Stack:
[  505.159598]  f9dd9036 f68adfac c10c21e8 c008adb8 c008ad80 00000014 00000000 f9dda000
[  505.159906]  00000800 f68adf50 74726962 79616468 00000000 f690d010 c0911380 00000000
[  505.159921]  d0a419e0 d0a41ddc f68adf88 c117a75d f68adf9c c107239e 00000002 f68adfb4
[  505.160059] Call Trace:
[  505.161077]  [<c10c21e8>] SyS_delete_module+0x148/0x1e0
[  505.161190]  [<c117a75d>] ? ____fput+0xd/0x10
[  505.161219]  [<c107239e>] ? task_work_run+0x7e/0xb0
[  505.161239]  [<c165efcd>] sysenter_do_call+0x12/0x28
[  505.161368] Code: c7 04 24 36 90 dd f9 e8 ab 45 87 c7 a1 90 a1 dd f9 8b 50 0c 8d  48   0c 39 ca 89 15 80 a1 dd f9 75 07 eb 3e 66 90 8b 50 0c 8b 48 10 <89> 4a 04 89 11 c7 40   0c 00 01 10 00 c7 40 10 00 02 20 00 a1 90
[  505.161890] EIP: [<f9dd8236>] cleanup_module+0x36/0xe00 
[birthday] SS:ESP 0068:f68adf38
[  505.162043] CR2: 0000000000100104
[  505.163080] ---[ end trace 660008f657d67eb5 ]---

2 个答案:

答案 0 :(得分:0)

更改您的清理功能,如下所示

void simple_exit(void)
{
    printk(KERN_INFO "Removing Module\n");  

    list_for_each_entry(ptr, tmp, &my_bday->list, list) {
        list_del(&(ptr->list));
        kfree(ptr);
    }
}

我刚刚结合了循环函数和输入函数

答案 1 :(得分:0)

这是从内核中彻底退出的退出函数。

 void simple_exit(void)
{
    printk(KERN_INFO "Removing Module\n");  

    list_for_each_entry_safe(ptr, tmp, &my_bday->list, list) {
    list_del(&(ptr->list));
    kfree(ptr);
    }
 }