我尝试将数据从内核空间传递到用户空间,我在控制台中看到的所有内容都被“杀死”,当我尝试查看dmesg
时,我看到:
unable to handle kernel paging request
我的内核模块初始化函数:
static int __init module_init_function(void) {
struct file_operations fops = {
.owner = THIS_MODULE
};
struct class *m_c;
struct device *dev;
DEVICE_ATTR(fw_dev, 0777, show_func, store_func);
/* Create the user interface device */
major = register_chrdev(0, "fw_status", &fops);
m_c = class_create(THIS_MODULE, "fw_class");
dev = device_create(m_c, NULL, MKDEV(major, 0), NULL, "fw_dev");
device_create_file(dev, &dev_attr_fw_dev);
return 0;
}
这是我的节目功能:
static ssize_t show_func(struct device *dev, struct device_attribute *attr, char *buf) {
return snprintf(buf,PAGE_SIZE, "%d,%d", accepted_packets, dropped_packets);
}
我做错了什么?
答案 0 :(得分:1)
DEVICE_ATTR
宏会创建device_attribute
in the scope it's called.因为它在您的初始化函数中,所以device_attribute
在模块初始化后会丢失。 (在旁注中,即使它在init函数中是静态的,它仍然会被删除。由于你的init函数有__init
,所以在模块初始化后该函数将从内存中清除)
尝试全局调用DEVICE_ATTR
。
同样适用于file_operations
,它也应该是全球性的。内核将它们存储为指针并且不会复制整个结构,以便您以后可以对其进行修改。
您可以浏览kernel source以查看其他模块的实施方式。快速搜索显示DEVICE_ATTR
始终全局使用。
此外,您可能不需要snprintf(9)
,"%d,%d"
无论如何都不会超过buf的大小。