register_chrdev_region / alloc_chrdev_region and cdev registered character device driver

The kernel provides three functions to register a group of characters device number, these three functions are register_chrdev_region (), alloc_chrdev_region () and register_chrdev ().


(1) register_chrdev   form older kernels registered   early drive
(2) register_chrdev_region / alloc_chrdev_region + cdev new drive form

Difference: register_chrdev () function inside the old version of the device number registration function, static and dynamic registration can be achieved two ways, mainly be distinguished by a given major number is 0, 0 when the dynamic registration. register_chrdev_region and alloc_chrdev_region is the function of the above-mentioned static and dynamic device registration number has been enhanced split .

 

register_chrdev_region (the dev_t First, COUNT unsigned int, char * name)
First: the initial value of the device number range to be allocated, the set of consecutive numbers starting device device number, corresponding to the register_chrdev () in the major number

Count: consecutive number range . this group is the size of the device number (device number of times is the number of)
the name: the name of the device associated with the number (/ proc / devices); the group name of the device driver.

alloc_chrdev_region function to let the kernel automatically assigned device number to us

(1) register_chrdev_region is the main known in advance to be used used for minor device numbers; ask to see the cat / proc / devices are not used to see.
(2) easier, smarter way is to let the kernel to us automatically assigned a major number, use alloc_chrdev_region can be automatically assigned.
(3) automatically assigned device number, we have to know his major and minor device numbers, or else can not go back mknod creates device files corresponding to him.

 

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

1: The first argument is the output parameter that obtained a number assigned to the device. MAJOR MINOR can use macros and macro, the major and minor numbers, extracted print it out, see how much is automatically assigned to help us use the major and minor numbers in the mknod create the device files. mknod / dev / xxx c major number minor device number

2: The second argument: the number of times the reference device, several times allocated from the first device number.

3: The third parameter: the number of times a device number.

4: The fourth parameter: name of the driver.

5: Return value: less than 0, error, wrong numbers automatically dispensing device. Otherwise, the device number assigned to get out of it was with the first argument.

 

Introduction cdev

cdev is a structure, the members of which come together to help us registration drive to the kernel, the expression of character device, this structure struct cdev populated, mainly filling is

Copy the code

the cdev {struct 

struct the kobject Kobj; 

struct * Module1 owner; // fill time value To THIS_MODULE, a block 

const struct file_operations * ops; // file_operations this structure, the key registration drive, to be filled into the structure variable 

struct List the list_head; 

the dev_t dev; // device number, the primary device number + minor number 

unsigned int count; // number of times a device number 

};

Copy the code

 

file_operations this structure variable, so that the value of the structure variable value file_operations ops members of cdev. This structure is cdev_add experience a kernel function would like to register

cdev structure, many functions can be used to operate his.

Such as:

cdev_alloc: let the kernel memory allocation for this structure

cdev_init: struct structure variables and the structure cdev type file_operations bundling

cdev_add: Adding a drive to the kernel inside, registration drive

cdev_del: log off from the kernel off a drive. Cancellation of driving

Device No

(1) dev_t types (including different major and minor numbers are not the same as defined in the core 16 and some 16-bit device number and rank the major number 20 is configured some minor number of the master number 12)

(2) MKDEV, MAJOR, MINOR three macro

MKDEV: is for the major and minor numbers, is converted into a major and minor number. (Device No)

MAJOR: device number is extracted from the inside out major number.

MINOR macros: No. extracted from the device out of the minor number.

The use of contrast register_chrdev_region register_chrdev:

Copy the code

1 // function module mounting 
 2 chrdev_init the __init static int (void) 
 . 3 {     
 . 4 int retval; 
 . 5      
 . 6 the printk (KERN_INFO "HelloWorld chrdev_init the init \ n-"); 
 . 7 
 . 8 / * 
 . 9 // function to register the call in the macro module_init character device driver 
10 // major pass 0 into vowed to make the kernel to help us automatically assigned a suitable blank major number has not been used 
11 // assign a good kernel if successful will return the assigned master; If the allocation will fail returns negative 
12 is mymajor = the register_chrdev (0, MYNAME, & test_fops); 
13 is IF (mymajor <0) 
14 { 
15 the printk (KERN_ERR "the register_chrdev Fail \ n-"); 
16 return -EINVAL; 
. 17} 
18 is the printk (KERN_INFO "the register_chrdev Success. % D = mymajor .. \ n-", mymajor);. 
. 19 * /     
20 is
21 // cdev the new registration character device driver interface 
22 // new interface register requires two steps character device driver 
23 is      
24 // Step 1: Register / assigned major and minor number 
25 mydev = MKDEV (MYMAJOR, 0 ) ; 
26 is retval = register_chrdev_region (that mydev, MYCNT, MYNAME); // 
// dynamically changed directly below 2526 while the other rows are removed as 
// int alloc_chrdev_region (dev_t * dev, unsigned baseminor, unsigned count, const char * name) 
IF 27 (retval) { 
28 the printk (KERN_ERR "Unable to Register for Minors% S \ n-", MYNAME); 
29 return -EINVAL; 
30} 
31 is the printk (KERN_INFO "register_chrdev_region Success \ n-"); 
32 // step 2 : registered character device driver 
33 is cdev_init (& test_cdev, & test_fops); 
34 is retval = cdev_add (& test_cdev, that mydev, MYCNT);
35     if (retval) { 
36 the printk (KERN_ERR "Unable to cdev_add \ n-");
Return -EINVAL 37 [; 
38 is} 
39 the printk (KERN_INFO "cdev_add Success \ n-"); 
40 
41 is      
mode 42 @ using dynamic mapping operation to register 
43 is IF (! Request_mem_region (GPJ0CON_PA,. 4, "GPJ0CON")) 
44 is return - EINVAL; 
45 IF (! request_mem_region (GPJ0DAT_PA,. 4, "GPJ0CON")) 
46 is return -EINVAL; 
47      
48 pGPJ0CON = ioremap (GPJ0CON_PA,. 4); 
49 pGPJ0DAT = ioremap (GPJ0DAT_PA,. 4); 
50      
51 is pGPJ0CON * = 0x11111111; 
52 * pGPJ0DAT = ((0 << 3) | (0 << 4) | (0 << 5)); // light 
53 is      
54 is 
55 return 0;
56} 
57 
58 // download function module 
59 static void __exit chrdev_exit (void)
{60 
61 is the printk (KERN_INFO "HelloWorld chrdev_exit Exit \ n-"); 
62 is 
63 is pGPJ0DAT * = ((<<. 1. 3) | (<<. 1. 4) | (<<. 1. 5));     
64      
65 // unmap 
66 iounmap (pGPJ0CON); 
67 iounmap (pGPJ0DAT); 
68 release_mem_region (GPJ0CON_PA,. 4); 
69 release_mem_region (GPJ0DAT_PA,. 4); 
70 
71 is / *     
72 // call the function of the macro module_exit to unregister character device driver 
73 unregister_chrdev (mymajor , MYNAME); 
74 * /     
75 
76 // using a new interface to unregister character device driver 
77 @ cancellation in two steps: 
78 // step true character device driver with cancellation cdev_del 
79 cdev_del (& test_cdev);  
80 // the second step is to apply for cancellation of major and minor device numbers
81 unregister_chrdev_region ( that mydev, MYCNT); 
82}

Copy the code

Complete code:

 View Code

 View Code

 cdev_alloc to define a pointer type struct cdev allocated heap space out

Internal cdev_alloc is actually called the kernel kmalloc to give struct_cdev to allocate heap memory, the memory size is the size of the struct cdev.

Example: If we define a global static struct cdev * pcdev; we can use pcdev = cdev_alloc (); heap memory to allocate space for the pcdev. Releases (pcdev) when cdev_del out of this application to the heap memory, cdev_del internal function is to know your target struct cdev is defined by the stack memory or heap memory or data memory segment. When this function cdev_del call, you will first have to see without the use of heap memory, to be useful if, then, will go freed heap memory for you, and then you write off this device driver. Prevent memory leaks. Note that if struct cdev use heap memory must use this cdev_alloc provided by the kernel to allocate heap memory, because the internal records will do so in cdev_del write off the drive when the release will go out of that part of heap memory.

Use cdev_alloc directly pcdev-> ops = fops; to bind, the function does not need cdev_init,

Code:

Copy the code

 

static dev_t mydev;
//static struct cdev test_cdev;
static struct cdev *pcdev;

......... 

// Step 2: Registered character device driver 
    pcdev = cdev_alloc (); // allocate memory to pcdev, examples of the pointer 
    // cdev_init (& test_cdev, & test_fops ); // The following code the sentence stresses replaced 
    pcdev-> = THIS_MODULE owner; 
    pcdev-> OPS = & test_fops;

Copy the code

cdev_init Source:

1

2

3

4

5

6

7

8

void cdev_init(struct cdev *cdev, const struct file_operations *fops)

{

    memset(cdev, 0, sizeof *cdev);

    INIT_LIST_HEAD(&cdev->list);

    cdev->kobj.ktype = &ktype_cdev_default;

    kobject_init(&cdev->kobj);

    cdev->ops = fops;

}

 cdev_init in other operations in the cdev_alloc have done.

 

Since finishing

http://blog.csdn.net/tommy_wxie/article/details/7195471

http://blog.sina.com.cn/s/blog_14f1867f70102wlrj.html

http://edu.51cto.com/pack/view/id-529.html

 http://blog.csdn.net/zqixiao_09/article/details/50839042 (Haotie)

Tags:  Linux

Guess you like

Origin blog.csdn.net/ll148305879/article/details/93602359