One, in the Linux2.6 kernel, a character device is described by the CDEV structure, which is defined as follows:
1 structCdev {2 structKobject kobj;3 structModule *owner;//Owning Module4 Const structFile_operations *ops;//file operation structure, in the writing drive, the structure of the body of most functions to be implemented5 structlist_head list;6dev_t Dev;//device number, int type, high 12-bit main device number, low 20-bit secondary device number7Unsignedintcount;8};
You can use the following macro call to obtain the primary and secondary device number:
MAJOR (dev_t Dev)
MINOR (dev_t Dev)
MKDEV (int major,int minor)//through the primary and secondary device number to generate dev_t
The above macro calls are defined in the kernel source code:
1 #define minorbits 2 #define Minormask ((1U << minorbits)-1) // (1<<20-1) After this operation, the MINORMASK macro has a low 20-bit 1 and a height of 12 bits of 0 3 #define MAJOR (Dev) ((unsigned int) ((dev) >> minorbits) 4 #define MINOR (Dev) ((unsigned int) ((dev) & Minormask) 5 #define MKDEV (Ma,mi) (((MA) << minorbits) | (MI))
Second, the following set of functions for the CDEV structure to operate:
1 voidCdev_init (structCdev *,Const structFile_operations *);//Initialize, establish a connection between Cdev and File_operation2 structCdev *cdev_alloc (void);//dynamically request a Cdev memory3 voidCdev_put (structCdev *p);//Release4 intCdev_add (structCdev *, dev_t, unsigned);//registering devices, usually in the load function of the driver module5 voidCdev_del (structCdev *);//unregister the device, usually in the Unload function of the drive module
1) If you want to dynamically acquire a separate CDEV structure at run time, there are two ways to assign and initialize the CEDV structure.
1 structCdev *my_cdev =Cdev_alloc ();2My_cdev->ops = &My_fops;3 4 structCdev *cdev_alloc (void) 5 { 6 structCdev *p = Kzalloc (sizeof(structCdev), Gfp_kernel); 7 if(p) {8Init_list_head (&p->list); 9Kobject_init (&p->kobj, &ktype_cdev_dynamic); Ten } One returnp; A}
2) Sometimes it may be desirable to embed the CDEV structure in its own particular device structure, then initialize it with the Cdev_init () function after allocating the CDEV structure:
1 void cdev_init (struct cdev *cdev, struct File_operations *fops) { 0 , sizeof *cdev); 4 init_list_head (&cdev->list); 5 Kobject_init (&cdev->kobj, & ktype_cdev_default); 6 cdev->ops = FoPs; 7 }
3) Registration and logoff: The owner in the Cdev is set to This_moule, which should be called first when registering:
The int register_chrdev_region (dev_t from,unsigned count,const char *name) function assigns a device number to it, and this function is available:
int alloc_chrdev_region (dev_t *dev,unsigned baseminor,unsigned count,const char *name) function instead, the difference between them is: Register_chrdev When _region () is used for a known device number, the other is used for dynamic applications, with the advantage of not causing duplicate device number collisions.
After logoff, you should call the void Unregister_chrdev_region (dev_t from,unsigned count) function to release the previously requested device number.
The sequence relationship between them is as follows:
Register_chrdev_region ()-->cdev_add ()//This process is in the load module
Cdev_del ()-->unregister_chrdev_region ()//This process is in the Unload module
Reference Original: Http://bbs.ednchina.com/BLOG_ARTICLE_1897586.HTM
Cdev struct and its related functions