How the kernel calls the driver entry function in linux character device driver

Keywords: PHP Linux

/* How does the kernel call the driver entry function?*/
/*Answer: use the module init() function.
The module_init() function defines a structure in which there is a function pointer.
Point to the driver entry function first_drv_init(), when we load or install a driver,
The kernel automatically finds such a structure and then calls the function pointer in the structure.
This calls the driver entry function first_drv_init(void), and then,
The driver entry function passes a struct file_operations type structure to the kernel.
So the kernel can call the function pointer in this structure to call the specific driver operation function.
In fact, the open, read,write and other functions called by the application program when operating the device file will eventually
Calling struct file_operations type structure*/

Here is the driver:

 1 #include <linux/module.h>
 2 #include <linux/kernel.h>
 3 #include <linux/fs.h>
 4 #include <linux/init.h>
 5 #include <linux/delay.h>
 6 #include <asm/uaccess.h>
 7 #include <asm/irq.h>
 8 #include <asm/io.h>
 9 #include <asm/arch/regs-gpio.h>
10 #include <asm/hardware.h>
11 
12 static struct class *firstdrv_class;
13 static struct class_device    *firstdrv_class_dev;
14 
15 volatile unsigned long *gpfcon = NULL;
16 volatile unsigned long *gpfdat = NULL;
17 
18 
19 static int first_drv_open(struct inode *inode, struct file *file)
20 {
21     //printk("first_drv_open\n");
22     /* Configure GPF4,5,6 as output */
23     *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
24     *gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
25     return 0;
26 }
27 
28 static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
29 {
30     int val;
31 
32     //printk("first_drv_write\n");
33 
34     copy_from_user(&val, buf, count); //    copy_to_user();
35 
36     if (val == 1)
37     {
38         // Lighting
39         *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));
40     }
41     else
42     {
43         // Lights out
44         *gpfdat |= (1<<4) | (1<<5) | (1<<6);
45     }
46     
47     return 0;
48 }
49 
50 static struct file_operations first_drv_fops = {
51     .owner  =   THIS_MODULE,    /* This is a macro that automatically creates _this_module variables when pushing to compile modules */
52     .open   =   first_drv_open,     
53     .write    =    first_drv_write,       
54 };
55 
56 
57 int major;
58 static int first_drv_init(void)/*Driven entry function*/
59 {
60     major = register_chrdev(0, "first_drv", &first_drv_fops); /*Register and tell the kernel first_drv_fops*/
61 
62     firstdrv_class = class_create(THIS_MODULE, "firstdrv");
63 
64     firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
65 
66     gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
67     gpfdat = gpfcon + 1;
68 
69     return 0;
70 }
71 
72 static void first_drv_exit(void)
73 {
74     unregister_chrdev(major, "first_drv"); // uninstall
75 
76     class_device_unregister(firstdrv_class_dev);
77     class_destroy(firstdrv_class);
78     iounmap(gpfcon);
79 }
80 /* How does the kernel call the driver entry function? */
81 /* Answer: Using the module_init() function,
82 module_init()A function defines a structure in which there is a function pointer.
83 Point to the driver entry function first_drv_init(), when we load or install a driver,
84 The kernel automatically finds such a structure and then calls the function pointer in the structure.
85 This calls the driver entry function first_drv_init(void), and then,
86 The driver entry function passes a struct file_operations type structure to the kernel.
87 So the kernel can call the function pointer in this structure to call the specific driver operation function.
88     The open, read,write functions that the application calls when it operates the device files will eventually do so.
89 Calling struct file_operations type structure*/
90 module_init(first_drv_init);
91 /**/
92 module_exit(first_drv_exit);
93 
94 /**/
95 MODULE_LICENSE("GPL");

Posted by haolan on Fri, 11 Oct 2019 09:55:20 -0700