Я пытаюсь сделать проект программирования из первой главы книги «Концепции операционной системы». Задача состоит в том, чтобы написать модуль ядра Linux, который выполняет итерацию структур, используя структуру данных списка ядра. Я написал следующий код:Ядерный модуль Linux зависает во время разгрузки
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
struct birthday {
int day;
int month;
int year;
struct list_head list;
};
struct list_head birthday_list;
struct birthday *createBirthday(int day, int month, int year)
{
struct birthday *person = kmalloc(sizeof(struct birthday), GFP_KERNEL);
person->day = day;
person->month = month;
person->year = year;
return person;
}
void printInfo(char *str)
{
printk(KERN_INFO "OS Module: %s", str);
}
int simple_init(void)
{
struct birthday *person = createBirthday(13, 4, 1987);
struct birthday *ptr;
printInfo("Loading Module\n");
LIST_HEAD(birthday_list);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(14, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(15, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(16, 4, 1987);
list_add_tail(&person->list, &birthday_list);
person = createBirthday(17, 4, 1987);
list_add_tail(&person->list, &birthday_list);
list_for_each_entry(ptr, &birthday_list, list) {
printk(KERN_INFO "OS Module: Day %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
}
return 0;
}
void simple_exit(void)
{
struct birthday *tmp;
struct list_head *ptr, *next;
printInfo("Removing Module\n");
if (list_empty(&birthday_list)) {
printInfo("List is empty");
return;
}
list_for_each_safe(ptr, next, &birthday_list){
tmp = list_entry(ptr, struct birthday, list);
printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", tmp->day, tmp->month, tmp->year);
list_del(ptr);
kfree(tmp);
}
//list_for_each_entry_safe(ptr, next, &birthday_list, list) {
// printk(KERN_INFO "OS Module: Removing %d.%d.%d\n", ptr->day, ptr->month, ptr->year);
// list_del(&ptr->list);
// kfree(ptr);
//}
printInfo("Module removed\n");
}
module_init(simple_init);
module_exit(simple_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("MP");
После установки и удаления модуля я не видел сообщений об удалении модуля.
~/kernelModule $ sudo insmod simple.ko
~/kernelModule $ sudo rmmod -f simple
~/kernelModule $ dmesg | grep 'OS Module'
[ 386.590198] OS Module: Loading Module
[ 386.590201] OS Module: Day 13.4.1987
[ 386.590202] OS Module: Day 14.1.1964
[ 386.590203] OS Module: Day 2.6.1964
[ 386.590204] OS Module: Day 13.8.1986
[ 386.590204] OS Module: Day 10.6.1990
[ 396.647828] OS Module: Removing Module
~/kernelModule $ sudo rmmod -f simple
rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'simple': Device or resource busy
rmmod: ERROR: could not remove module simple: Device or resource busy
Как я понимаю, мой модуль висит во время удаления. И я не понимаю, почему. Оба освобождающих кода (прокомментированные тоже) заставляют модуль зависать.
Вы пытались добавить еще несколько трасс 'printk', чтобы выяснить точную строку кода, где находится код? –
в 'simple_init' вам нужно использовать' LIST_HEAD_INIT' вместо 'LIST_HEAD': последний * объявляет и инициализирует локальную переменную вместо инициализации глобальной. – Tsyvarev
может использовать INIT_LIST_HEAD (& birthday_list) или LIST_HEAD_INIT. –