在字符设备驱动模块加载函数中应实现设备号的申请和cdev的注册,而在卸载函数中应实现设备号的释放和cdev的注销。
int scull_init_module(void){ int result, i; dev_t dev = 0;
/* [1]分配设备编号 */ if (scull_major) { /* 预先自己指定了主设备号 */ dev = MKDEV(scull_major, scull_minor); /* 利用主设备号,找到设备编号给方法1用 */ result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { /* 动态自己生成设备编号,然后再利用设备编号得到主设备号; 记住如果用这个方法那么就要后建设备文件了,因为不能提前知道主号 当然也可以利用ldd3书中提供的脚本,巨方便&&通用 */ result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull"); scull_major = MAJOR(dev); } if (result < 0) { printk(KERN_WARNING "scull: can't get major %d/n", scull_major); return result; }
/*[2]设备对象实例化*/ /* * allocate the devices -- we can't have them static, as the number * can be specified at load time */ scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; goto fail; /* Make this more graceful */ } memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
/* [3]在这里初始化设备用了2.6的新方法,在scull_setup_cdev里完成 */ /* Initialize each device. */ for (i = 0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; /* 可以根据自己insmod时传参 来自己改变量子和量子集(指针数组)的大小 */ scull_devices[i].qset = scull_qset; init_MUTEX(&scull_devices[i].sem); scull_setup_cdev(&scull_devices[i], i); /* 在分别完主设备编号后goto Tag002 设备注册 */ }
/* At this point call the init function for any friend device */ dev = MKDEV(scull_major, scull_minor + scull_nr_devs); dev += scull_p_init(dev); dev += scull_access_init(dev);
#ifdef SCULL_DEBUG /* only when debugging */ scull_create_proc();#endif
return 0; /* succeed */
fail: scull_cleanup_module(); return result;}
module_init(scull_init_module); //insmod module_exit(scull_cleanup_module); //rmmod

