在内核模块中创建一个链表

时间:2014-03-19 03:15:19

标签: c linux struct linux-kernel

我试图让链接列表为我的模块工作,我没有使用内置内核链表(我不知道在我开始制作模块的那一刻存在的东西)。 这是我的结构

struct data{
    struct data *next;
    struct msghdr *msg;
    size_t len;
}

我把头作为全局变量。

struct data *head = NULL;

我有一个add_to_end函数

void add_to_end(struct data *newData){
    struct data *temp1;
    if (head == NULL){
        head = (struct data *)kmalloc(sizeof(struct data),GFP_KERNEL);
        head = newData;
    } else {
        temp1 = (struct data *)kmalloc(sizeof(struct data),GFP_KERNEL);
        temp1 = head;
        while(temp1->next!=NULL) {
            temp1 = temp->next;
        }
        temp1->next = newData;
    }
}

在我的一个函数中,我像这样使用add_to_end

struct data *temp;

temp = (struct data *)kmalloc(sizeof(struct data),GFP_KERNEL);
temp->next = NULL;
temp->msg = (struct msghdr *)kmalloc(sizeof(struct msghdr),GFP_KERNEL);
temp->msg = message;
temp->len = length;
add_to_end(temp);

但是当我尝试在此链接列表中使用msg时,会发生错误。内核向终端打印一些跟踪内容。 我想要做的是将消息复制到我的链表中,但作为一个单独的副本,不只是复制指向地址的指针。我已经阅读了一些例子,当复制两个结构时,它们实际上使用相同的地址,当改变其中一个时,它们都被改变了。我不想要那种副本,我想要一份带有自己地址的单独副本。

我猜我复制这两个结构的方式不对,也许我的链表也不对,有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:1)

您的示例中有许多地方在分配内存,然后通过覆盖它立即泄漏指针:

    head = (struct data *)kmalloc(sizeof(struct data),GFP_KERNEL);
    head = newData;

这没有意义。您的函数应该在它应该添加的链接列表条目的内容中传递(例如,msglen),或者它应该处理{的值{1}}已经被分配的传入。

我强烈建议您在冒险进入内核之前,先在用户空间中使用一些示例,以便了解链接列表的使用情况。如果没有别的,那么从错误中恢复并执行调试将会更容易。

答案 1 :(得分:1)

1)您必须使用memecpy函数将内容从邮件复制到数据结构。

    temp->msg = (struct msghdr *)kmalloc(sizeof(struct msghdr),GFP_KERNEL);
    // temp->msg = message;
    memcpy(temp->msg, message, sizeof(struct msghdr));

2)如果消息指针指向用户空间中的内存缓冲区,则必须使用copy_from_user()函数而不是memcpy。此函数将处理内核空间内存副本的用户空间。

3)请不要重新发明轮子。内核已经有链接列表结构here l你可以使用它而不是重新创建它。此外,如果列表可能由不同的线程访问,则必须在访问之前通过锁保护它们。

    DEFINE_RAW_SPINLOCK(mylock);
    LIST_HEAD(vm_list);

    ....
    my_function() {
            ....
        raw_spin_lock(&kvm_lock);
        list_for_each_entry(kvm, &vm_list, vm_list)
            *val += *(u32 *)((void *)kvm + offset);
        raw_spin_unlock(&kvm_lock);

     }

答案 2 :(得分:0)

在while循环中,你在add_to_end函数中有temp而不是temp1。你真的运行这个代码还是这个错误只是在这篇文章中?