我正在尝试实现内核系统调用以从队列中删除第一个元素。在 gdb 中调试时,我得到一个 SEGKILL,内核日志中有一行:BUG:无法处理内核分页请求...。
我的队列结构如下:
typedef struct msgQueue
{
long len;
void *data;
struct list_head queue;
} msgQueue;
如您所见,它包含指向数据块的指针、该数据的字节长度以及来自 list.h 的 list_head 结构对象。
我用这些行初始化了一个 msgQueue(above) 类型的对象:
myQueue = (struct msgQueue *) kmalloc(sizeof(struct msgQueue), GFP_KERNEL);
INIT_LIST_HEAD(&myQueue->queue);
我实现了一个正确工作的写入函数。当我尝试从中删除时,队列不为空。这是我正在添加的新队列的初始化以及添加它的行:
函数头:
asmlinkage long sys_writeMsgQueue(const void __user *data, long len)
其他线路:
tempQueue = (struct msgQueue *)kmalloc(sizeof(struct list_head), GFP_KERNEL);
tempQueue->data = kmalloc((size_t)len, GFP_KERNEL);
tempQueue->len = len;
uncopiedBytes = __copy_from_user(tempQueue->data, data, len);
list_add_tail(&(tempQueue->queue), &(myQueue->queue));
我无法粘贴所有内容,甚至只是我的阅读功能,因为这是我正在接受的课程。但这是我希望的相关部分:
asmlinkage long sys_readMsgQueue(void __user *data, long len)
{
long uncopiedBytes;
uncopiedBytes = __copy_to_user(myQueue, data, len);
printk("REMOVING FROM QUEUE AND FREEING\n\n\n");
list_del(&(myQueue->queue));
}
当我在 Eclipse 中的自包含 c 程序中实现此基本功能以尝试调试它时,它运行良好。当然,我必须针对用户空间代码对其进行调整,以便删除/更改所有内核特定的东西(malloc 而不是 kmalloc,没有特定于系统调用的语法等)。我包含了我下载的 list.h,所以我使用了所有相同的功能,例如 list.h。
有没有什么突出的东西会导致我的内核日志中出现内核分页错误?