int scull_init_module(void) { int result, i; dev_t dev = 0; /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. */ if (scull_major) { dev = MKDEV(scull_major, scull_minor); result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { 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; } /* * 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)); /* Initialize each device. */ for (i = 0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; #ifndef init_MUTE sema_init(&scull_devices[i].sem, 1); #else init_MUTEX(&scull_devices[i].sem); #endif scull_setup_cdev(&scull_devices[i], i); } /* 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; }
int init_module(void) { int result, i; /* * Register your major, and accept a dynamic number */ result = register_chrdev(scull_major, "scull", &scull_fops); if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n",scull_major); return result; } if (scull_major == 0) scull_major = result; /* dynamic */ /* * 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 (Scull_Dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; goto fail_malloc; } memset(scull_devices, 0, scull_nr_devs * sizeof (Scull_Dev)); for (i=0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; } /* At this point call the init function for any friend device */ if ( (result = scull_p_init()) ) goto fail_pipe; if ( (result = scull_access_init()) ) goto fail_access; /* ... */ #ifndef SCULL_DEBUG REGISTER_SYMTAB(NULL); /* otherwise, leave global symbols visible */ #endif #ifdef SCULL_USE_PROC /* only when available */ /* this is the last line in init_module */ proc_register_dynamic(&proc_root, &scull_proc_entry); #endif return 0; /* succeed */ fail_access: scull_p_cleanup(); fail_pipe: kfree(scull_devices); fail_malloc: unregister_chrdev(scull_major, "scull"); return result; }
int scull_init_module(void) { int result, i; #ifdef CONFIG_DEVFS_FS /* If we have devfs, create /dev/scull to put files in there */ scull_devfs_dir = devfs_mk_dir(NULL, "scull", NULL); if (!scull_devfs_dir) return -EBUSY; /* problem */ #else /* no devfs, do it the "classic" way */ /* * Register your major, and accept a dynamic number. This is the * first thing to do, in order to avoid releasing other module's * fops in scull_cleanup_module() */ result = register_chrdev(scull_major, "scull", &scull_fops); if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n",scull_major); return result; } if (scull_major == 0) scull_major = result; /* dynamic */ #endif /* CONFIG_DEVFS_FS */ /* * 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(Scull_Dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; goto fail; } memset(scull_devices, 0, scull_nr_devs * sizeof(Scull_Dev)); for (i=0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; sema_init(&scull_devices[i].sem, 1); #ifdef CONFIG_DEVFS_FS sprintf(devname, "%i", i); devfs_register(scull_devfs_dir, devname, DEVFS_FL_AUTO_DEVNUM, 0, 0, S_IFCHR | S_IRUGO | S_IWUGO, &scull_fops, scull_devices+i); #endif } /* At this point call the init function for any friend device */ if ( (result = scull_p_init()) ) goto fail; if ( (result = scull_access_init()) ) goto fail; /* ... */ #ifndef SCULL_DEBUG EXPORT_NO_SYMBOLS; /* otherwise, leave global symbols visible */ #endif #ifdef SCULL_DEBUG /* only when debugging */ scull_create_proc(); #endif return 0; /* succeed */ fail: scull_cleanup_module(); return result; }
int scull_init_module(void) { int result, i; dev_t dev = 0; /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. * 根据scull_major的值是否为0,分别采用静态分配或动态分配 * scull_major为主设备编号,在scull中初始定义为 #define SCULL_MAJOR 0,如果用户通过命令行参数给major赋 >0 的值,则采取静态分配 * scull_minor为从设备编号 */ printk(KERN_ALERT "Debug by andrea:scull_init_module()/n"); if (scull_major) { dev = MKDEV(scull_major, scull_minor); /* * 静态分配设备编号 */ result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { /* * 动态分配设备编号 */ 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; } /* * allocate the devices -- we can't have them static, as the number * can be specified at load time */ /* * 为每一个设备分配内存空间 * scull_nr_devs 默认为4 ,即默认创建4个scull设备, 在scull.h 定义 define SCULL_NR_DEVS 4 */ scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL); if (!scull_devices) { result = -ENOMEM; goto fail; /* Make this more graceful */ } /* * 将scull_devices分配的内存清零 */ memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev)); /* Initialize each device. */ /* * 初始化 scull_nr_dev个 scull_dev结构体, 即scull_nr_dev个scull_dev设备 * scull_devices[i].qset代表当前scull设备中每一个qset的data域指向的数组有SCULL_QSET(默认1000)个指针 * scull_devices[i].quantum代表当前scull设备中每一个qset中上面的数组指向的量子有SCULL_QUANTUM(默认4000)个字节 */ for (i = 0; i < scull_nr_devs; i++) { scull_devices[i].quantum = scull_quantum; scull_devices[i].qset = scull_qset; /* init_MUTEX(&scull_devices[i].sem);*/ sema_init(&scull_devices[i].sem,1); /* * 调用了scull_setup_cdev函数对相应scull设备进行设置 */ scull_setup_cdev(&scull_devices[i], i); } /* 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; }
/*[Tag000] * 当模块加载时,调用;但是为什么要放在最后来实现他呢,看到Tag002时,你应该就明白了; */ int scull_init_module(void) { int result, i; dev_t dev = 0; /* [Tag001] */ /* [1]分配设备编号 */ /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. */ 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; }