platform_device_register触发kobject重复初始化错误排查
Platform设备模块kobject重复初始化错误分析
问题背景
作为Linux驱动学习新手,在编写Platform设备测试模块时,模块能正常加载卸载,但dmesg中出现kobject重复初始化的错误日志。
测试代码
#include "platform.h" struct platform_device *plat_device1; struct device_platform_data *device1_info; static int __init platform_device_init(void) { plat_device1 = platform_device_alloc("test_char_device", -1); pr_info("Platform Device Name is %s", plat_device1->name); pr_info("Platform Device ID is %d", plat_device1->id); device1_info = devm_kzalloc(&plat_device1->dev, sizeof(struct device_platform_data), GFP_KERNEL); device1_info->size = 512; device1_info->perm = RDWR; device1_info->serial_number = "PCDEVA1"; plat_device1->dev.platform_data = device1_info; plat_device1->dev.release = pcdev_release; pr_info("Modules Loaded\n"); platform_device_register(plat_device1); return 0; } void pcdev_release(struct device *dev) { struct device_platform_data *pdata = dev_get_platdata(dev); pr_info("Device Released: size=%d, serial=%s\n", pdata->size, pdata->serial_number); } static void __exit platform_device_exit(void) { platform_device_unregister(plat_device1); pr_info("Modules Unloaded\n"); } module_init(platform_device_init); module_exit(platform_device_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("noone"); MODULE_DESCRIPTION("code test");
错误日志
kobject: kobject (00000000b9d46629): tried to init an initialized object, something is seriously wrong. [ +0.000004] CPU: 5 UID: 0 PID: 12617 Comm: insmod Tainted: G OE 6.11.0-19-generic #19~24.04.1-Ubuntu [ +0.000002] Call Trace: ... [ +0.000005] kobject_init+0x71/0xb0 [ +0.000004] device_initialize+0x24/0x120 [ +0.000004] platform_device_register+0x16/0x90 [ +0.000003] ? __pfx_platform_device_init+0x10/0x10 [platform_device] [ +0.000003] platform_device_init+0xad/0xff0 [platform_device] ... [ +0.000003] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8b bb 0d 00 f7 d8 64 89 01 48 [ +0.000002] RSP: 002b:00007fffa90e2658 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ +0.000004] RAX: ffffffffffffffda RBX: 0000558205f91720 RCX: 00007cdc3352725d [ +0.000002] RDX: 0000000000000000 RSI: 00005581e9e99e52 RDI: 0000000000000003 [ +0.000002] RBP: 00007fffa90e2710 R08: 0000000000000040 R09: 00005581e9e9a0b0 [ +0.000001] R10: 00007cdc33603b20 R11: 0000000000000246 R12: 00005581e9e99e52 [ +0.000002] R13: 0000000000000000 R14: 0000558205f95700 R15: 0000000000000000
错误原因
- 重复初始化kobject:
platform_device_alloc()函数内部已经调用device_initialize()完成了设备对象(包括其内部的kobject)的初始化,并且默认设置了release函数。而你在代码中修改plat_device1->dev.release后,又调用了platform_device_register(),该函数内部会再次执行device_initialize(),导致同一个kobject被初始化两次,触发内核的错误检查日志。 - 模块仍能正常加载卸载的原因:这个错误属于内核的警告级异常,内核并没有终止模块的加载流程,后续的设备注册逻辑依然完成;卸载时
platform_device_unregister()也能正常触发release函数并清理资源,所以模块的基本功能不受影响,但这种操作违反了内核设备模型的规范,在复杂场景下可能引发内存泄漏或其他不可预期的问题。
修复方案
将代码中的platform_device_register(plat_device1);替换为platform_device_add(plat_device1);,因为platform_device_add()不会重复执行设备初始化操作,而是直接完成设备的总线注册流程:
修改后的初始化函数片段:
pr_info("Modules Loaded\n"); // 替换原有的platform_device_register调用 platform_device_add(plat_device1); return 0;
同时,卸载函数保持platform_device_unregister()即可,它会正确处理platform_device_add()注册的设备。
内容的提问来源于stack exchange,提问作者user9154867
相关产品推荐
相关产品推荐

