16
16
#include <linux/semaphore.h> /* used acces to semaphore, process management
17
17
syncronization behaviour */
18
18
#include <asm/uaccess.h> /* copy_to_user;copy_from_user */
19
+ #include <linux/device.h>
19
20
20
21
/* (1)create structure for fake char device */
21
22
struct fake_device
@@ -39,7 +40,7 @@ int ret; /* will hold return value of the
39
40
dev_t dev_num ; /* will hold the device number that
40
41
the kernel gives; name appears in
41
42
/proc/devices */
42
-
43
+ static struct class * cl ; // Global variable for the device class
43
44
#define DEVICE_NAME "testCharDevice"
44
45
45
46
/* (7) called on device_open
@@ -126,13 +127,11 @@ static int driver_entry(void) {
126
127
major_number = MAJOR (dev_num ); /* extract major number from dev_num
127
128
and store it in our variable */
128
129
minor_number = MINOR (dev_num ); /* minor number */
130
+ printk (KERN_INFO "testCharDevice: module loaded, device is: /dev/%s" ,
131
+ DEVICE_NAME );
129
132
printk (KERN_INFO "testCharDevice: major number is: %d, minor number is: %d" ,
130
133
major_number ,
131
134
minor_number );
132
- printk (KERN_INFO "testCharDevice: Please execute 'sudo mknod /dev/%s c %d %d'" ,
133
- DEVICE_NAME ,
134
- major_number ,
135
- minor_number ); /* dmesg */
136
135
137
136
/* ----------(2)---------- */
138
137
mcdev = cdev_alloc (); /* create our cdev structure;
@@ -141,6 +140,20 @@ static int driver_entry(void) {
141
140
mcdev -> ops = & fops ; /* struct file operation */
142
141
mcdev -> owner = THIS_MODULE ;
143
142
143
+ /* populate sysfs entries under /sys/class/chardev/ */
144
+ if ((cl = class_create (THIS_MODULE , "chardev" )) == NULL )
145
+ {
146
+ unregister_chrdev_region (dev_num , 1 );
147
+ return -1 ;
148
+ }
149
+ /* create /dev/testCharDevice node */
150
+ if (device_create (cl , NULL , dev_num , NULL , DEVICE_NAME ) == NULL )
151
+ {
152
+ class_destroy (cl );
153
+ unregister_chrdev_region (dev_num , 1 );
154
+ return -1 ;
155
+ }
156
+
144
157
/* now that we have created our cdev, we have to add it to kernel */
145
158
/* int cdev_add(struct cdev*, dev, dev_t num, unsigned int count) */
146
159
ret = cdev_add (mcdev , dev_num , 1 );
@@ -152,18 +165,18 @@ static int driver_entry(void) {
152
165
153
166
/* (4) Initialize our semaphore */
154
167
sema_init (& virtual_device .sem ,1 ); /* initial value of one */
155
-
156
168
return 0 ;
157
169
}
158
170
159
171
static void driver_exit (void ) {
160
172
/* (5) unregister everything in reverse order */
161
173
// (a)
162
174
cdev_del (mcdev );
163
-
175
+ device_destroy (cl , dev_num ); /* delete node /dev/testCharDevice */
176
+ class_destroy (cl ); /* delete sysfs */
164
177
// (b)
165
178
unregister_chrdev_region (dev_num , 1 );
166
- printk (KERN_INFO "testCharDevice: unloaded module" );
179
+ printk (KERN_INFO "testCharDevice: module unloaded " );
167
180
168
181
}
169
182
0 commit comments