Embedded-Linux-Device-Driver/C3/Data-Transfer-between-User-and-Kernel-Space/English
Visual cue : | Narration : |
Slide 1 :
Welcome slide: |
Welcome to the spoken tutorial on Data transfer between user and kernel space. |
Slide 2:
Learning objectives: |
In this tutorial, we will learn how to copy the data from the
|
Slide 3:
System Requirements: |
To record this tutorial, I am using,
|
Slide 4:
Prerequisites: |
To follow this tutorial, you should be familiar with:
If not, then go through the C/C++ and Linux spoken tutorials on this website. |
Point to the folder and file in desktop
|
Go to the DeviceDriver folder in the desktop which we have created earlier.
In this directory, I have created a directory named DataTransfer. Here, I have saved a simple_driver dot c driver file, Makefile and user-read-write dot c file. I’ll use these files for demonstration. |
Slide 5:
Code files: |
* The files used in this tutorial are available in the Code Files link on this tutorial page.
|
Open the terminal
|
Open the terminal by pressing ALT+Ctrl+T keys simultaneously.
Go to the directory where DataTransfer is saved in your system. Press Enter key after every command. |
Type >> gedit simple_driver.c | Type gedit space simple_driver dot c.
I have used the same file simple_driver dot c which we used earlier. |
Highlight #include<linux/uaccess.h>
|
We have to include the uaccess dot h kernel header file.
It contains the read() and write() functions declarations. These are used to transfer the data between user space and kernel space. We have to add the protocols of read() and write() functions as shown here. |
Highlight mydevice_write and mydevice_read. | Let us add the read and write functions in the file_operations structure. |
Now let us see the write function which can be used to write data to a device. | |
Highlight
mydevice_write (struct file *filp, const char __user *buff, size_t len, loff_t *loff) Highlight *buff Highlight len Highlight *loff Highlight mydevice_write |
The write() function is used to send data to the device.
buff represents the user space data buffer. len specifies the size of the requested data transfer. loff indicates the start position from which data should be written in the file. The return value is the number of bytes written. I have defined the write function as shown here. |
Let us see the kernel specialized function to transfer the data. | |
Highlight
copy_from_user (void * to, const void __user * from, unsigned long n) Highlight to Highlight from Highlight n Highlight unsigned long Highlight unsigned long |
The copy_from_user function copies blocks of data from user to the kernel space.
to specify the destination address in the kernel space. from specifies the source address in the user space n specifies the number of bytes to copy. On failure, it returns a number of bytes that could not be copied. It will return zero on success. |
Highlight printk() | Now, check whether the user data size is greater than the kernel buffer or not.
If it is more, then this error message will print with the termination of a program. |
Highlight len,buff,ptr
Highlight copy_from_user(ptr,buff,len) Highlight EFAULT |
Otherwise, it will copy the len bytes of data of user buffer buff to the kernel buffer ptr.
The copy_from_user also checks whether the user pointer buff is valid or not. If it is invalid, it will not copy the data and returns the EFAULT error. Depending upon its success or failure, the corresponding messages will be printed. |
Now let us see the read function which can be used by users to read the data from a device. | |
Highlight
mydevice_read (struct file *filp, char __user *buff, size_t len, loff_t *loff) Highlight *buff Highlight len Highlight *loff Highlight mydevice_read() |
The read() function is used to read the data from the device file.
buff specifies the pointer to buffer from the user space. len specifies the size of the requested transfer. loff indicates the start position from which data should be read. The return value is the number of bytes read. I have defined the read function as shown here. |
Now let us see the kernel's specialized function to transfer data. | |
Highlight
unsigned long copy_to_user(void __user *to, const void *from, unsigned long count) Highlight to Highlight from Highlight n Highlight unsigned long Highlight unsigned long |
copy_to_user function copies a block of data from a kernel buffer into user space.
to specifies the destination address in the user space. from specifies the source address in the kernel space. n specifies the number of bytes to copy. On failure, it returns a number of bytes that could not be copied. It will return zero on success. |
Highlight len, ptr, buff.
Highlight copy_to_user(buff,ptr,len) Highlight printk Highlight unsigned long copy_to_user() |
It will copy the len bytes of the data from kernel buffer ptr to the user buffer buff.
The copy_to_user also checks the validity of the user pointer. Depending upon its success or failure, the corresponding messages will be printed. Using these functions, the driver can access the user space buffer in a safe way. |
Type >> clear. | Save and close the file.
Switch back to the terminal. Clear the screen. |
Type >> sudo su.
Type >> password. |
To be a superuser, Type sudo space su.
Now, type the system password. |
Type >> gedit Makefile
Open the terminal |
To compile the driver, we have to create a Makefile.
Type gedit space Makefile. Type the code as shown here or you can use the downloaded Makefile. Save and close the file. |
Switch back to the terminal | |
Now let us write a user program to write and read data from a device. | |
Type >> gedit user-read-write.c
Highlight *userData Highlight string |
Type gedit space user-read-write dot c
I have already created a user program. It will open, close, read and write data to the new_device by its driver. Here, I have defined the userData pointer which points to the string “Linux Device Driver”. |
We will write and read this string from a device using respective system calls. | |
Highlight write()
Highlight DataSize |
After opening a device, the write system call is used to write the data to it.
It will write the string of length DataSize to a device as shown here. When it executes, the kernel internally calls a write function from the driver. |
Highlight read()
Highlight DataSize Open the terminal |
Similarly, the read system call will read the data from a device.
It will read the data from a device and store it in the kernelData as shown here. When it executes, the kernel internally calls read function from the driver Save and close the file. |
Type >> clear | switch back to the terminal.
Clear the screen. |
Type >> make all | Let’s compile the driver.
Type make space all. Clear the screen. |
Type >> insmod simple_driver
.ko |
Now load the driver into the kernel.
Type insmod space simple_driver dot ko. |
Type >> dmesg | grep simple_driver
Highlight the output |
Let’s see the loaded printk messages.
Type dmesg space pipe space grep space simple_ driver. Here, you can see the device, its class were created successfully. Clear the screen. |
Type >> gcc -c user-read-write.c
Type >> gcc -o user-read-write user_read_write.o |
Now compile the user program.
Type gcc space hyphen c space user-read-write dot c Then type the command as shown here. |
Type ./user
|
Now let us execute the user program.
Type dot slash user. We can see the data write and data read message from the device successfully. Clear the screen. |
Type >> dmesg | grep simple_driver
Highlight the respective messages Type >> clear |
Type dmesg space pipe space grep space simple_driver.
This shows that the kernel called the write and read functions from the driver. Clear the screen. |
Type rmmod simple_driver.ko
Type dmesg | grep simple_driver Highlight the respective messages |
Now lets unload the driver.
Type rmmod space simple_driver dot ko To see the unloaded printk messages type this dmesg command. It shows that the struct cdev, device file, it’s class are removed from the system. The device is also unregistered here. |
With this, we come to the end of this tutorial. Let us summarise. | |
Slide 6:
Summary: |
In this tutorial, we learnt how to copy the data from
|
Slide 7:
|
As an assignment:
|
Slide 8:
|
* The video at the following link summarizes the Spoken Tutorial project.
|
Slide 9:
Spoken Tutorial workshops : |
The Spoken Tutorial Project Team:
For more details, please write to us. |
Slide 10:
|
* Please post your timed queries in this forum |
Slide 11:
Forum for specific questions : |
* Do you have any general or technical questions on Embedded Linux Device Driver?
|
Slide 12:
Acknowledgment: |
The Spoken Tutorial Project is funded by MHRD, Government of India. |
Slide 13:
Thank you slide: |
This tutorial has been contributed by FOSSEE and Spoken Tutorial Project, IIT Bombay.
This is usha signing off. Thanks for watching. |