You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:34:55