我试图让链接列表为我的模块工作,我没有使用内置内核链表(我不知道在我开始制作模块的那一刻存在的东西)。 这是我的结构
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时,会发生错误。内核向终端打印一些跟踪内容。 我想要做的是将消息复制到我的链表中,但作为一个单独的副本,不只是复制指向地址的指针。我已经阅读了一些例子,当复制两个结构时,它们实际上使用相同的地址,当改变其中一个时,它们都被改变了。我不想要那种副本,我想要一份带有自己地址的单独副本。
我猜我复制这两个结构的方式不对,也许我的链表也不对,有人可以帮帮我吗?
答案 0 :(得分:1)
您的示例中有许多地方在分配内存,然后通过覆盖它立即泄漏指针:
head = (struct data *)kmalloc(sizeof(struct data),GFP_KERNEL);
head = newData;
这没有意义。您的函数应该在它应该添加的链接列表条目的内容中传递(例如,msg
和len
),或者它应该处理{的值{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。你真的运行这个代码还是这个错误只是在这篇文章中?