我写了一个简单的字符驱动程序,现在想在udev中使用类自动注册它。 我的代码由驱动程序加载时调用的init
函数和驱动程序加载其设备时调用的probe
函数组成(当然还有它们的等价的exit
和remove
)。 问题:一旦添加新设备,执行device_create
命令时,我的probe
function失败。 现在我想知道为什么:
我怎么能得到更多的信息,为什么这个命令失败(除了失败)? 缺less任何参数(比如我的全局声明fooClass
是否存在问题,是否应该将其移至probe
函数,而不是在我眼中做出反应,但在许多示例中显示)? 还是其他监督错误?
我的代码我剥离了大多数返回validation(如IS_ERR()
)和清理function的可读性。 这两个variables是全局定义的:
static int foo_majNbr; static struct class *fooClass;
init
函数:
static int __init foo_init(void) { int rv; dev_t devNbr; /* Registering driver */ rv = pci_register_driver(&foo_driver); /* ----> see answer below for correct order <---- */ /* Create device class */ fooClass = class_create(THIS_MODULE, CLASS_NAME); /* Allocate device number, just one device for the moment */ rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME); foo_majNbr = MAJOR(devNbr); ... }
和probe
function:
static int __devinit foo_probe(struct pci_dev *dev, const struct pci_device_id *devId) { struct foo_dev *foo_dev = 0; int rv = 0; /* Allocate memory in Kernel (for parameters) */ foo_dev = kzalloc(sizeof(*foo_dev), GFP_KERNEL); foo_dev->pci_dev = dev; pci_set_drvdata(dev, foo_dev); foo_dev->devNbr = MKDEV(foo_majNbr, 1); /* Add class to device */ foo_dev->dev = device_create(fooClass, NULL, foo_dev->devNbr, foo_dev, DEVICE_NAME); if (IS_ERR(foo_dev->dev)) { /* ----> INDICATES FAILURE HERE <---- */ } /* Add char device */ cdev_init(&foo_dev->cdev, &foo_fops); rv = cdev_add(&foo_dev->cdev, foo_dev->devNbr, 1); /* Enabling device */ rv = pci_enable_device(dev); ... }
你至少应该打印错误号码来知道原因。
pr_err("%s:%d error code %d\n", __func__, __LINE__, PTR_ERR(foo_dev->dev));
NULL
在Linux / include / uapi / asm-generic / errno-base.h文件中,您可以找到最常见的错误。 如果这个错误代码不能帮助你,你可以去device_create()的源代码找出你的错误产生的地方,并理解为什么。
在调用之前也许还要打印device_create()
的device_create()
。
我知道,这不是那种神奇地解决你的问题的答案:)但是这是一种进行和找出原因的方法。
问题要求提供关于调试的信息,在前面的答案中已经很好地解释了。 为了完整起见,我想分享为什么device_create()
失败的背后的实际问题的解决方案:
查看dmesg
日志,加载模块后将显示以下通话历史记录:
[ 2646.982482] [foo_init:246] CALL | Function called. [ 2646.982499] [foo_probe:121] CALL | Function called. [ 2646.982503] [foo_probe:147] ERR -19 | Failed to add device to class. [ 2646.982535] [foo_init:279] OK | Driver loaded, Major number: 235.
可以看到, init()
函数在调用probe()
之前没有完成它的例程。 因此,当probe()
想将其添加到设备时,不存在类。 在init()
调用的命令的顺序是一个问题:在完成例程之前,驱动程序已经将自己注册到内核。 pci_register_driver()
只能在最后被调用。 这里更新的代码:
static int __init foo_init(void) { int rv; dev_t devNbr; /* Create device class */ fooClass = class_create(THIS_MODULE, CLASS_NAME); /* Allocate device number, just one device for the moment */ rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME); foo_majNbr = MAJOR(devNbr); ... /* Registering driver */ rv = pci_register_driver(&foo_driver); /* ----> has to be called at the very end! <---- */ }
exit()
函数的正确顺序也计算在内(正如我在遇到导致Oops的另一个错误后发现的那样):首先取消注册驱动程序以取消注册设备,然后才销毁该类。 代码如下:
static void __exit foo_exit(void) { pci_unregister_driver(&foo_driver); class_destroy(fooClass); }