copy_from_user()
This function is used to Copy a block of data from user space (Copy data from user space to kernel space).
unsigned long copy_from_user(void *to, const void __user *from, unsigned long n);
Arguments
to
– Destination address, in kernel spacefrom
– Source address in user spacen
– Number of bytes to copy
Returns number of bytes that could not be copied. On success, this will be zero.
copy_to_user()
This function is used to Copy a block of data into user space (Copy data from kernel space to user space).
unsigned long copy_to_user(const void __user *to, const void *from, unsigned long n);
Arguments
to
– Destination address, in user spacefrom
– Source address in kernel spacen
– Number of bytes to copy
Returns number of bytes that could not be copied. On success, this will be zero.
Full Driver Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem_size 1024
dev_t dev = 0;
static struct class *dev_class;
static struct cdev etx_cdev;
uint8_t *kernel_buffer;
static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);
static int etx_open(struct inode *inode, struct file *file);
static int etx_release(struct inode *inode, struct file *file);
static ssize_t etx_read(struct file *filp, char __user *buf, size_t len,loff_t * off);
static ssize_t etx_write(struct file *filp, const char *buf, size_t len, loff_t * off);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = etx_read,
.write = etx_write,
.open = etx_open,
.release = etx_release,
};
static int etx_open(struct inode *inode, struct file *file)
{
/*Creating Physical memory*/
if((kernel_buffer = kmalloc(mem_size , GFP_KERNEL)) == 0){
printk(KERN_INFO "Cannot allocate memory in kernel\n");
return -1;
}
printk(KERN_INFO "Device File Opened...!!!\n");
return 0;
}
static int etx_release(struct inode *inode, struct file *file)
{
kfree(kernel_buffer);
printk(KERN_INFO "Device File Closed...!!!\n");
return 0;
}
static ssize_t etx_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
copy_to_user(buf, kernel_buffer, mem_size);
printk(KERN_INFO "Data Read : Done!\n");
return mem_size;
}
static ssize_t etx_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
copy_from_user(kernel_buffer, buf, len);
printk(KERN_INFO "Data Write : Done!\n");
return len;
}
static int __init etx_driver_init(void)
{
/*Allocating Major number*/
if((alloc_chrdev_region(&dev, 0, 1, "etx_Dev")) <0){
printk(KERN_INFO "Cannot allocate major number\n");
return -1;
}
printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
/*Creating cdev structure*/
cdev_init(&etx_cdev,&fops);
etx_cdev.owner = THIS_MODULE;
etx_cdev.ops = &fops;
/*Adding character device to the system*/
if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "Cannot add the device to the system\n");
goto r_class;
}
/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct class\n");
goto r_class;
}
/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1\n");
goto r_device;
}
printk(KERN_INFO "Device Driver Insert...Done!!!\n");
return 0;
r_device:
class_destroy(dev_class);
r_class:
unregister_chrdev_region(dev,1);
return -1;
}
void __exit etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}
module_init(etx_driver_init);
module_exit(etx_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EmbeTronicX
MODULE_DESCRIPTION("A simple device driver");
MODULE_VERSION("1.4");
|
User Space Application
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#include
#include
#include
#include
#include
#include
#include
int8_t write_buf[1024];
int8_t read_buf[1024];
int main()
{
int fd;
char option;
printf("*********************************\n");
fd = open("/dev/etx_device", O_RDWR);
if(fd < 0) {
printf("Cannot open device file...\n");
return 0;
}
while(1) {
printf("****Please Enter the Option******\n");
printf(" 1. Write \n");
printf(" 2. Read \n");
printf(" 3. Exit \n");
printf("*********************************\n");
scanf(" %c", &option);
printf("Your Option = %c\n", option);
switch(option) {
case '1':
printf("Enter the string to write into driver :");
scanf(" %[^\t\n]s", write_buf);
printf("Data Writing ...");
write(fd, write_buf, strlen(write_buf)+1);
printf("Done!\n");
break;
case '2':
printf("Data Reading ...");
read(fd, read_buf, 1024);
printf("Done!\n\n");
printf("Data = %s\n\n", read_buf);
break;
case '3':
close(fd);
exit(1);
break;
default:
printf("Enter Valid option = %c\n",option);
break;
}
}
close(fd);
}
|
Compile the User Space Application
Use below line in terminal to compile the user space application.
gcc -o test_app test_app.c
Execution (Output)
As of now, we have driver.ko and test_app. Now we will see the output.
- Load the driver using
sudo insmod driver.ko
- Run the application (
sudo ./test_app
)
*********************************
*******WWW.EmbeTronicX.com*******
****Please Enter the Option******
1. Write
2. Read
3. Exit
*********************************
- Select option 1 to write data to driver and write the string ( In this case i’m going to write “embetronicx” to driver.
1
Your Option = 1
Enter the string to write into driver :embetronicx
Data Writing ...Done!
****Please Enter the Option******
1. Write
2. Read
3. Exit
*********************************
- That “embetronicx” string got passed to the driver. And driver stored that string in the kernel space. That kernel space was allocated by
kmalloc
. - Now select the option 2 to read the data from the device driver.
2
Your Option = 2
Data Reading ...Done!
Data = embetronicx
No comments:
Post a Comment