Linux Char Device Driver
Transcript of Linux Char Device Driver
Linux Char Device Driver
Gary 2013/03/20
Outline
• Introduction
• Module
• Major Number and Minor Number
• Data Structure
• Registration
• Open and Release
• Read and Write
• Future Work
Introduction
• Device driver is a bridge between physical devices and programs, and it’s part of kernel. User program can manage physical devices via device driver.
• Driver can be roughly divided into Block device driver and Character device driver. The former transfer a fixed amount of data each time, and Character device driver transfer no-fixed amount of data.
Module
Module
Advantage:
• Reduce kernel image space
• Speed up the boot time
• Facilitate the development of the kernel function
Module
Linking a module to a kernel
Major Number and Minor Number
• Major number(0-255)
When the kernel receives open() system call,
it selects the driver based on major number.
• Minor number(0-255)
Identify individuals of similar devices.
Meaningless to kernel. Only the driver itself
knows the significance of the minor number.
Major Number and Minor Number
• “c” represents special file of char driver.
• “b” represents device file of block driver.
Major number Minor number
Major Number and Minor Number
• Use mknod command to create device node. Needs superuser priviledges and four arguments.
- <name> <device type> <major> <minor>
$mknod /dev/ant c 252 0
• Use rm command to delete device node.
$rm /dev/ant
Data Structure
• Struct file represents an opened-device.
• Struct file_operations is used for kernel to access the method in driver.
- defined in <linux/fs.h>
• Struct file has field f_op, which is the pointer point to struct file_operations
File_operations
File_operations
• struct module *owner;
Not a function pointer. For kernel to maintain
the usage count of module.
• loff_t (*llseek) (struct file *, loff_t, int);
Change the position of current file read write
point.
File
• The file mentioned here has no concerned with the file in normal application.
• For every file which is opened, there is a correspond struct file.
• The pointer point to file is named filp.
File
Old Registration Method
• Call register_chrdev()
- define in <linux/fs.h>
- /usr/src/<kernel version>/include/linux/fs.h
Old Registration Method
• $cat /proc/devices
New Registration Method
• Kernel uses struct cdev to represent char device driver. You need to include <linux/cdev.h>
• Use cdev_alloc() to configure struct cdev
• If you have your own designed struct, you need to use cdev_init()
Struct cdev *my_cdev = cdev_alloc();My_cdev->ops = &my_fops;
Void cdev_init(struct cdev *dev, struct file_operations *fops);
New Registration Method
• No matter how to initialize struct cdev, the owner field must be set
• The last step, use cdev_add() to add to kernel
struct cdev my_cdev;my_cdev.owner = THIS_MODULE;
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
Struct cdev you set
Major number
Total amount of device number
New Registration Method
• Destroy cdevvoid cdev_del(struct cdev *dev);
Open and Release
• Open operation offers driver initialization, and increase usage count.
• Release operation decrease usage count.
- Defined in <linux/module.h>
Open
• Most of the open operation of driver should do the following jobs.
- increase usage count
- check for device specific errors
(ex : no CD in CD-ROM)
- if the target device is opened the first time,
do initializtion
- Identify the minor number and update the f_op
pointer
- allocate and fill data structure in filp->private data
Open
• The first step of open operation is to check the target device’s minor number.
Release
• Release anything that open operation allocate to flip->private_data.
• Shut down the target device on the last close.
• Decrease usage count
Read and Write
• flip : file pointer
• buff : argument to the buffer in user-space
• count : transfer data amount
• offp : the file location
ssize_t read(struct file *filp, char *buff, size_t count, loff_t *offp);ssize_t write(struct file *filp, const char *buff, size_t count, loff_t *offp);
Read and Write
• Data transfer between kernel space and user space.
• Use the function defined in <asm/uaccess.h>
Read and Write
• The arguments to read
Future Work
• Read more
• Ioctl