This program is accumulated a little bit. At the beginning, only the read () and open () functions are implemented in file_operations for testing. As long as this step passes the subsequent tests, it is much easier, then, the write () and IOCTL () functions are added;
The driver module is relatively simple, but it took me several hours to complete the debugging. This module can be compiled and directly inserted into the currently running Ubuntu for test run.
The printk () Information in the driver module is not displayed on the terminal. It is input to the/var/LO/messages file. Available
Tail-F/var/log/messages to view the information printed by the driver through the printk () function in real time.
The helloworld. C (driver), makefile, app_helloworld.c (APP)
Directly make to generate a module that can be inserted into the current computer
Then insmod (information can be queried in/var/log/messages) is loaded into the module.
Create a device node in mknod so that you can use open () in the app for testing.
During driver compilation, there are problems with the compilation module, which may be caused by the Kernel configuration or the driver, for example, if a field pointer is used to cause a segment error.
The program function is to drive the user each time a character [A-Z] [A-Z] or [0-9] Through IOCTL implementation when to send what characters. The user space then adds the value to the kernel space and prints it.
###### Helloworld. c driver ##################################### ##
1 # include <Linux/kernel. h>
2 # include <Linux/init. h>
3 # include <Linux/module. h>
4 # include <Linux/fs. h>
5 # include <Linux/cdev. h>
6 # include <ASM/uaccess. h>
7 # include <Linux/mm. h>
8 # include <ASM/IO. h>
9 # include <ASM/system. h>
10
11 module_license ("dual BSD/GPL ");
12 # define hello_major 234
13 # define hello_minor 0
14 # define number_of_device 1
15
16 # define letteru 1
17 # define letterd 2
18 # define dig 3
19 static char touser = 'a ';
20
21 static hello_ioctl (struct inode * inodep, struct file * filp, unsigned int cmd, unsigned long a RG)
22 {
23 switch (CMD)
24 {
25 case letteru:
26 touser = 'a ';
27 printk ("Get IOCTL from user to use 'A'/N ");
28 break;
29
30 case letterd:
31 touser = 'a ';
32 printk ("Get IOCTL from user to use 'A'/N ");
33 break;
34
35 case dig:
36 touser = '1 ';
37 printk ("Get IOCTL from user to use dig '1'/N ");
38 break;
39
40 default:
41 printk ("Get invalid IOCTL from user/N ");
42}
43 return 0;
44}
45 int hello_open (struct inode * Pi, struct file * PF)
46 {
47 printk ("system call open success firstdriver/N ");
48 return 0;
49}
50 ssize_t hello_read (struct file * filp, char _ User * Buf, ssize_t count, loff_t * f_pos)
51 {printk ("in system call read firstdriver/N ");
52 copy_to_user (BUF, & touser, 1 );
53
54 touser ++;
55 return 1;
56}
57
58 ssize_t hello_write (struct file * filp, char _ User * Buf, ssize_t count, loff_t * f_pos)
59 {
60 char fruser;
61 copy_from_user (& fruser, Buf, count );
62 printk ("value from user space is % C/N", fruser );
63 return count;
64}
65
66 struct file_operations hello_ops =
67 {
68. Owner = this_module,
69. Open = hello_open,
70. Read = hello_read,
71. Write = hello_write,
72. IOCTL = hello_ioctl,
73
74 };
75
76 static int _ init hello_init (void)
77 {
78 int result;
79 result = register_chrdev (hello_major, "hello", & hello_ops );
80 If (result <0)
81 {
82 printk (kern_warning "Can 'r register the character device/N ");
83 return result;
84}
85
86
87 printk (kern_info "register character done! /N ");
88 return 0;
89}
90
91 static void _ exit hello_exit (void)
92 {
93 unregister_chrdev (hello_major, "hello ");
94 printk ("good bye from first driver/N ");
95}
96 module_init (hello_init );
97 module_exit (hello_exit );
######################## End driver ############## ##############################
############################## Makefile ######## ######################
Ker_dir: =/usr/src/Linux-headers-'uname-R '/
Mod_dir: = 'pwd'
OBJ: = helloworld. o
Modules:
$ (Make)-C $ {ker_dir} m =$ {mod_dir} modules
####################################### End makefile #####################
########## Test the app_helloworld.c ######################### ##########
1 # include <stdio. h>
2 # include <sys/types. h>
3 # include <unistd. h>
4 # include <fcntl. h>
5 # include <sys/STAT. h>
6 # include <sys/IOCTL. h>
7
8 # define letteru 1
9 # define letterd 2
10 # define dig 3
11
12 INT main (void)
13 {
14 int FD;
15 FD = open ("/dev/Hello", o_rdwr );
16 if (FD <0)
17 {
18 printf ("can't open file/N ");
19 Return-1;
20}
21
22 printf ("the data from kernel will be held evenif app exit so reset the kernel data/N ");
23 IOCTL (FD, letterd, null );
24
25 char Buf = '0 ';
26
27 int RB;
28 static int COUNT = 0;
29
30 While (1)
31 {
32 RB = read (FD, & Buf, 1 );
33 count ++;
34
35 if (count> 10)
36 {
37 static turn = 0;
38 turn ++;
39 COUNT = 0;
40 switch (turn % = 3)
41 {
42 printf ("The turn3 = % d/N", turn );
43 case letteru:
44 IOCTL (FD, letteru, null );
45 break;
46
47 case letterd:
48 IOCTL (FD, letterd, null );
49 break;
50
51 Case dig:
52 IOCTL (FD, dig, null );
53}
54}
55
56 printf ("the value return from kernel is % C/N", Buf );
57 sleep (2 );
58 Buf ++;
59 printf ("write to kernel is % C/N", Buf );
60 RB = write (FD, & Buf, 1 );
61 sleep (1 );
62}
63
64 return 0;
65}
####################### End of APP ############## ########################