我创建了一个利用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 Modulen");
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 = %dn", tmp->day, tmp->month, tmp->year);
}
return 0;
}
void simple_exit(void)
{
printk(KERN_INFO "Removing Modulen");
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 buffer读取以下内容:
[ 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 ]---
将您的清理功能更改如下
void simple_exit(void)
{
printk(KERN_INFO "Removing Modulen");
list_for_each_entry(ptr, tmp, &my_bday->list, list) {
list_del(&(ptr->list));
kfree(ptr);
}
}
我刚刚结合了循环函数和输入函数
这是直接退出内核的退出函数。
void simple_exit(void)
{
printk(KERN_INFO "Removing Modulen");
list_for_each_entry_safe(ptr, tmp, &my_bday->list, list) {
list_del(&(ptr->list));
kfree(ptr);
}
}