LDD3笔记——scull模块加载与卸载函数

    技术2025-10-02  13

        在字符设备驱动模块加载函数中应实现设备号的申请和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

    最新回复(0)