将驱动编译到内核注意一个小问题

这几天同事测试LIRC驱动发现,如果把LIRC驱动编译成模块,然后使用insmod命令将驱动load到内核,驱动使用起来没有任何问题,但是如果把驱动直接编译到内核,启动内核以后发现驱动无法使用。

 

刚开始我怀疑可能是devfs的问题,但是查看代码跟这个没有任何关系。 然后查看了编译成模块时load模块的log, 与编译到内核,内核启动时的log,发现了问题。

 

原来lirc_dev.c文件有这么一段代码:

 

#ifdef MODULE static int __init lirc_dev_init(void) { if (register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) { printk(KERN_ERR "lirc_dev: register_chrdev failed/n"); goto out; } lirc_class = class_create(THIS_MODULE, "lirc"); if (IS_ERR(lirc_class)) { printk(KERN_ERR "lirc_dev: class_create failed/n"); goto out_unregister; } printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, " "major %d /n", IRCTL_DEV_MAJOR); return 0; out_unregister: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) if (unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME)) printk(KERN_ERR "lirc_dev: unregister_chrdev failed!/n"); #else /* unregister_chrdev returns void now */ unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); #endif out: return -1; } static void __exit lirc_dev_exit(void) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) int ret; ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); class_destroy(lirc_class); if (ret) printk(KERN_ERR "lirc_dev: error in " "module_unregister_chrdev: %d/n", ret); else dprintk("lirc_dev: module successfully unloaded/n"); #else /* unregister_chrdev returns void now */ unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); class_destroy(lirc_class); dprintk("lirc_dev: module unloaded/n"); #endif } module_init(lirc_dev_init); module_exit(lirc_dev_exit); MODULE_DESCRIPTION("LIRC base driver module"); MODULE_AUTHOR("Artur Lipowski"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(IRCTL_DEV_MAJOR); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Enable debugging messages"); #endif /* MODULE */

 

把MODULE宏去掉以后,log一致了,但是使用的时候还要注意一点。

 

因为除了lirc_dev这个驱动之外,LIRC还需要开发者提供建议在lirc_dev基础上另外一个驱动,例如lirc_it87驱动,这个驱动的打开和关闭操作如下:

static int lirc_open(struct inode *inode, struct file *file) { spin_lock(&dev_lock); if (MOD_IN_USE) { spin_unlock(&dev_lock); return -EBUSY; } MOD_INC_USE_COUNT; spin_unlock(&dev_lock); return 0; } static int lirc_close(struct inode *inode, struct file *file) { MOD_DEC_USE_COUNT; return 0; }

 

 需要将其改写成下面的代码,因为MOD_IN_USE, MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT这些宏只有驱动被编译成模块时才支持。

 

static int lirc_open(struct inode *inode, struct file *file) { spin_lock(&dev_lock); #ifdef MODULE if (MOD_IN_USE) { spin_unlock(&dev_lock); return -EBUSY; } MOD_INC_USE_COUNT; #endif spin_unlock(&dev_lock); return 0; } static int lirc_close(struct inode *inode, struct file *file) { #ifdef MODULE MOD_DEC_USE_COUNT; #endif return 0; }

 

你可能感兴趣的:(将驱动编译到内核注意一个小问题)