在Linux 6.0中注册设备时如何初始化设备类。

huangapple go评论64阅读模式
英文:

How to initialize device's class when register device in linux-6.0

问题

The error you're encountering, "don't try to register things with the same name in the same directory," suggests that there might be a naming conflict when registering your bus and driver. To resolve this issue, you can try the following suggestions:

  1. Change the Names: Make sure that the names you are using for your bus and driver are unique and do not conflict with any existing names in the /sys/class or /sys/devices directories.

  2. Use Different Names: Instead of using "bus-test" for your bus and "driver_test" for your driver, try using more distinct and unique names to avoid naming conflicts.

  3. Check Dependencies: Ensure that any dependencies your module relies on are properly initialized before your module is loaded. In your case, make sure that the bus you are trying to register is initialized before registering the driver.

  4. Review Documentation: Check the Linux kernel documentation and relevant headers for the functions and structures you are using. Sometimes, there may be specific requirements or constraints not immediately apparent from the code.

  5. Consider Using class_create and device_create: As you mentioned, using class_create and device_create functions can simplify device registration. You can try this approach and ensure that you set up the class and device hierarchy correctly.

  6. Check for Other Errors: Look for any other potential issues in your code, such as typos, missing includes, or incorrect usage of kernel APIs.

  7. Debugging: Use kernel debugging tools and techniques to gain more insight into the specific cause of the error. Kernel logs, printk statements, and tools like dmesg can be helpful in diagnosing kernel module issues.

By carefully reviewing your code and considering these suggestions, you should be able to resolve the error and successfully load your kernel module.

英文:

I register bus, driver and device, and I want to register a class, then I initialize device's class before register device, that emit a error: "don't try to register things with the same name in the same directory". I think the code is OK, and if I not to initialize device's class, that is OK, and it works well. But now I want to create a class to go for it.
Can you give me some suggestions?

The code is this:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>           
#include <linux/device.h>
#include <linux/device/driver.h>
#include <linux/kobject.h>  
#include <linux/sysfs.h>   

static struct class test_class = {
    .name = "mytest_class",
    .owner = THIS_MODULE,
};


static int bus_match(struct device *dev, struct device_driver *drv)
{
    printk(KERN_INFO"In %s \n", __func__);
    //match by driver name and device name
    return (strcmp(dev_name(dev), drv->name) == 0);
}

static int bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    int ret=1;
    printk(KERN_INFO "%s hotplug\n", dev_name(dev));
    ret = add_uevent_var(env, "THIS_TEST=%s", dev_name(dev));
    if(ret)
    {
        return ret;
    }
    return add_uevent_var(env, "EVENT=%s", "change");
}

static int bus_probe(struct device *dev)
{
    return dev->driver->probe(dev);
    return 0;
}

static void bus_remove(struct device *dev)
{
    dev->driver->remove(dev);
}

struct bus_type bus_test =
{
    .name  = "bus-test",
    .match = bus_match,
    .uevent= bus_uevent,
    .probe = bus_probe,
    .remove= bus_remove,
};
EXPORT_SYMBOL(bus_test);

static int driver_probe(struct device *dev)
{
    printk(KERN_INFO "driver probe!\n");
    return 0;
}

static int driver_remove(struct device *dev)
{
    printk(KERN_INFO "driver remove!\n");
    return 0;
}

static struct device_driver driver_test=
{
    .name = "driver_test",
    .bus  = &bus_test,
    .probe = driver_probe,
    .remove = driver_remove,
};

static void dev_test_release(struct device *dev)
{
    printk(KERN_INFO "device release!\n");
}

static struct device dev_test = {
    .init_name  = "driver_test",
    .bus        = &bus_test,
    .release    = dev_test_release,
};

static int __init init_driver_test(void)
{
    int ret = 0;
    printk(KERN_INFO "init module!\n");
    ret = bus_register(&bus_test);
    if (ret) {
        printk(KERN_ERR "bus register error!\n");
        return ret;
    }
    ret = class_register(&test_class);
    if (ret) {
        printk(KERN_ERR "class register error!\n");
        return ret;
    }
    dev_test.class      = &test_class,
    dev_test.devt=MKDEV(100, 1);
    ret = device_register(&dev_test);
    if(ret)
    {
        printk(KERN_ERR "device register error!\n");
        return ret;       
    }
    ret = driver_register(&driver_test);
    if (ret) {
        printk(KERN_ERR "driver register error!\n");
        return ret;
    }
    return ret;
}

static void __exit exit_driver_test(void)
{
    driver_unregister(&driver_test);
    device_unregister(&dev_test);
    class_unregister(&test_class);
    bus_unregister(&bus_test);
    printk(KERN_INFO "exit module!\n");
}
module_init(init_driver_test);
module_exit(exit_driver_test);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NoError");
MODULE_DESCRIPTION("driver test");

I built it as module, and insmod it, it's falied, the error is:

# insmod driver_test.ko
[   48.663393] driver_test: loading out-of-tree module taints kernel.
[   48.669891] driver_test: module verification failed: signature and/or required key missing - tainting kernel
[   48.680389] init module!
[   48.683167] Driver 'driver_test' needs updating - please use bus_type methods
[   48.690549] sysfs: cannot create duplicate filename '/devices/virtual/rapidio_port/driver_test/subsystem'
[   48.700176] CPU: 3 PID: 326 Comm: insmod Tainted: G           OE      6.0.11 #3
[   48.707511] Hardware name: OrangePi Zero2 (DT)
[   48.711961] Call trace:
[   48.714412]  dump_backtrace+0xd8/0x120
[   48.718192]  show_stack+0x18/0x50
[   48.721524]  dump_stack_lvl+0x68/0x84
[   48.725201]  dump_stack+0x18/0x34
[   48.728526]  sysfs_warn_dup+0x60/0x80
[   48.732207]  sysfs_do_create_link_sd+0x138/0x140
[   48.736839]  sysfs_create_link+0x30/0x50
[   48.740777]  bus_add_device+0xf0/0x140
[   48.744542]  device_add+0x33c/0x8b0
[   48.748043]  device_register+0x20/0x30
[   48.751804]  init_driver_test+0x98/0x1000 [mdev_hotplug]
[   48.757143]  do_one_initcall+0x50/0x1c0
[   48.760990]  do_init_module+0x44/0x1d0
[   48.764757]  load_module+0x194c/0x1d50
[   48.768521]  __do_sys_finit_module+0xac/0x130
[   48.772893]  __arm64_sys_finit_module+0x20/0x30
[   48.777439]  invoke_syscall+0x48/0x120
[   48.781203]  el0_svc_common.constprop.0+0x44/0x100
[   48.786008]  do_el0_svc+0x30/0xd0
[   48.789336]  el0_svc+0x2c/0x90
[   48.792408]  el0t_64_sync_handler+0xbc/0x140
[   48.796695]  el0t_64_sync+0x18c/0x190
[   48.800461] driver_test hotplug
[   48.803709] device register error!
[   48.838788] init module!
[   48.841389] sysfs: cannot create duplicate filename '/bus/bus-test'
[   48.847754] CPU: 3 PID: 326 Comm: insmod Tainted: G           OE      6.0.11 #3
[   48.855077] Hardware name: OrangePi Zero2 (DT)
[   48.859524] Call trace:
[   48.861974]  dump_backtrace+0xd8/0x120
[   48.865753]  show_stack+0x18/0x50
[   48.869083]  dump_stack_lvl+0x68/0x84
[   48.872760]  dump_stack+0x18/0x34
[   48.876085]  sysfs_warn_dup+0x60/0x80
[   48.879765]  sysfs_create_dir_ns+0xec/0x110
[   48.883963]  kobject_add_internal+0xbc/0x3a0
[   48.888251]  kset_register+0x58/0x90
[   48.891840]  bus_register+0xc4/0x320
[   48.895432]  init_driver_test+0x2c/0x1000 [mdev_hotplug]
[   48.900769]  do_one_initcall+0x50/0x1c0
[   48.904616]  do_init_module+0x44/0x1d0
[   48.908382]  load_module+0x194c/0x1d50
[   48.912147]  __do_sys_init_module+0x20c/0x250
[   48.916519]  __arm64_sys_init_module+0x1c/0x30
[   48.920977]  invoke_syscall+0x48/0x120
[   48.924742]  el0_svc_common.constprop.0+0x44/0x100
[   48.929546]  do_el0_svc+0x30/0xd0
[   48.932874]  el0_svc+0x2c/0x90
[   48.935946]  el0t_64_sync_handler+0xbc/0x140
[   48.940232]  el0t_64_sync+0x18c/0x190
[   48.943965] kobject_add_internal failed for bus-test with -EEXIST, don't try to register things with the same name in the same directory.
[   48.956343] bus register error!
#

I think the code is ok, and it will create symlink in /sys/class for /sys/devices. But it's failed.
I looked at some source code in linux kernel, but that is all using class_create and device_create, I had tried it and it's ok, but the device_create is not initializing device bus, so, the device will not match the driver.

答案1

得分: 2

这是一个不错的顶部,该类别是顶级的,而类别就像一个包含所有相同类型设备的盒子。

英文:

This is a good top, the class is top level, and class is like a box which contains all device that are same kind.
在Linux 6.0中注册设备时如何初始化设备类。

答案2

得分: 0

好问题,真正的原因是公交车是一个设备,设备不能同时是公交车设备和类设备。所以,你必须注册一个新的设备,它是公交车设备的子设备,然后子设备将匹配驱动程序。

英文:

good question, the real reason is that the bus is a device, and the device can't be both a bus device and a class device. so, you must register a new device which is child of the bus device, then the child device will be match the driver.

huangapple
  • 本文由 发表于 2023年5月22日 09:51:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76302629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定