Linux内核模块创建双sysfs设备时insmod提示操作不允许
问题描述
我是内核模块开发新手,作业要求创建两个sysfs设备,路径分别为/sys/class/A/B/B_attr和/sys/class/A/C/C_attr。以下是我编写的初始化函数代码:
static int __init sysfs_example_init(void) { // create char device major_number = register_chrdev(0, "A", &fops); if (major_number < 0) return -1; // create sysfs class sysfs_class = class_create(THIS_MODULE, "A"); if (IS_ERR(sysfs_class)) { unregister_chrdev(major_number, "A"); return -1; } // create sysfs device sysfs_device = device_create(sysfs_class, NULL, MKDEV(major_number, 0), NULL, "B"); if (IS_ERR(sysfs_device)) { class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; } // create sysfs file attributes if (device_create_file(sysfs_device, (const struct device_attribute *)&dev_attr_B.attr)) { device_destroy(sysfs_class, MKDEV(major_number, 0)); class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; } // create sysfs device sysfs_device_rules = device_create(sysfs_class, NULL, MKDEV(major_number, 0), NULL, "C"); if (IS_ERR(sysfs_device_rules)) { class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; } if (device_create_file(sysfs_device_rules, (const struct device_attribute *)&dev_attr_C.attr)) { device_destroy(sysfs_class, MKDEV(major_number, 0)); class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; } return 0; }
执行insmod example.ko时出现错误:
insmod: ERROR: could not insert module example.ko: Operation not permitted
请问该如何解决这个问题?
解决方法
1. 使用root权限执行加载命令
普通用户无内核模块加载权限,必须以root身份操作:
sudo insmod example.ko
2. 关闭Secure Boot(若开启)
开启Secure Boot的系统会阻止未签名内核模块加载。进入BIOS/UEFI设置,找到Secure Boot选项关闭,重启后再尝试加载。
3. 修复代码中的设备号冲突
你创建两个设备时使用了同一个设备号MKDEV(major_number, 0),这会导致设备创建失败,内核返回的错误被包装成Operation not permitted提示。修改为不同的次设备号:
// 创建B设备,次设备号用0 sysfs_device = device_create(sysfs_class, NULL, MKDEV(major_number, 0), NULL, "B"); // 创建C设备,次设备号用1 sysfs_device_rules = device_create(sysfs_class, NULL, MKDEV(major_number, 1), NULL, "C");
同时修正错误处理逻辑,销毁设备时使用对应设备号:
if (IS_ERR(sysfs_device_rules)) { device_destroy(sysfs_class, MKDEV(major_number, 0)); class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; } if (device_create_file(sysfs_device_rules, (const struct device_attribute *)&dev_attr_C.attr)) { device_destroy(sysfs_class, MKDEV(major_number, 1)); device_destroy(sysfs_class, MKDEV(major_number, 0)); class_destroy(sysfs_class); unregister_chrdev(major_number, "A"); return -1; }
4. 确保内核版本匹配
编译模块时必须使用当前运行系统的内核头文件。用uname -r查看当前内核版本,确认编译环境的内核头文件版本与之一致。
5. 查看内核日志定位具体错误
加载失败后,执行以下命令查看内核日志,获取更详细的错误原因:
dmesg | tail -20
内容的提问来源于stack exchange,提问作者Its me
相关产品推荐
相关产品推荐

