Linux Device Drivers
About Me: I am Naveen, I studied B.TECH ,Electronics and Communication Engg from SITAMS ,Chittor dist,Affiliated to Javaharlal Nehru technolgical University.Main purpose is Creation of this Site is to share my knowledge to others.And also tell me suggestions about Linux topics. This blog Covers Linux Internels,Device drivers ,embedded Linux.
Tuesday, October 26, 2010
Monday, September 13, 2010
Basic Read/Write functions in driver
Device Driver ... Read/Write Functions
These functions are used to read and write data to a device. The kernel system call adds two extra parameters (filep and loff_t) to the original user call.
In the following examples the device driver will read and write to a small buffer in kernel space to simulate data transfer to an actual device.
In the following examples the device driver will read and write to a small buffer in kernel space to simulate data transfer to an actual device.
// small buffer used by our demonstration driver #define SCMD_SIZE 32 static char scmd_data[SCMD_SIZE];
Read/Write parameters
The parameters for the read and write functions are almost the same.
filep - the kernel allocated driver structure buf - the user space buffer count - the number of bytes to transfer lofft - the offset of the first byte to transfer
Return value
The return value is the actual count of data written to or read from the device.
For a read a return value of 0 is used to indicate that no more data is available.
For a write a return value of zero indicates that no data was written.
For a read a return value of 0 is used to indicate that no more data is available.
For a write a return value of zero indicates that no data was written.
Driver Read Function
The Read Function transfers count chars from the device into a user space buffer (buf):
static ssize_t scmd_read(struct file *filep, char *buf, size_t count, loff_t * f_pos) { int pos; int size; pos = *f_pos; size = SCMD_SIZE; /* check limits */ if (pos >= size) pos = size-1; if ((pos + count) >= size) count = (size - pos) - 1; /* copy count from kernel buffer to user space buffer */ /* copy_to_user returns 0 on success */ if (copy_to_user(buf,&scmd_data[pos],count)) return -EFAULT; pos += count; //filep->f_pos = pos; // Note this is deprecated *f_pos = pos; // new for 2.6 Kernel return count; }
Driver Write Function
The write function transfers count chars from user space to the device
static ssize_t scmd_write(struct file *filep, const char *buf, size_t count, loff_t * f_pos) { int pos; int size; pos = *f_pos; size = SCMD_SIZE; /* check limits */ if (pos >= size) pos = size; if ((pos + count) >= size) count = (size - pos) - 1; /* copy count from a user space buffer to the kernel buffer */ /* copy_from_user returns 0 on success */ if (copy_from_user(&scmd_data[pos],buf,count)) return -EFAULT; pos += count; //filep->f_pos = pos; // Note Deprecated *f_pos = pos; // new for 2.6 Kernel return count; }
Transferring Data
The Linux kernel provides a pair of functions to carry out data transfer between user space and kernel space.
These functions provide a check that the user space is valid.
They return the number of un copied bytes should an error in the count or buffer be detected. The driver should return such an error to the user code.
The kernel will automatically handle any page swapping required to map the user data space.
These functions provide a check that the user space is valid.
They return the number of un copied bytes should an error in the count or buffer be detected. The driver should return such an error to the user code.
The kernel will automatically handle any page swapping required to map the user data space.
// copy to kernel from user // returns number of uncopied bytes on error unsigned long copy_from_user(unsigned long kspace_to, unsigned long uspace_from, unsigned long length); // copy to user from kernel // returns number of uncopied bytes on error unsigned long copy_to_user(unsigned long uspace_to, unsigned long kspace_from, unsigned long length);
Sunday, September 12, 2010
Basic Open function call
The Open Function
The Open device driver function is used to set up the process access to the device. Normally the following functions are performed.
The parameters for the open function are as follows
- Set up a private data structure to save the state of the driver
- Create any memory areas used by the device drivers
- Manage any locks and semaphores used to control access to the device
The parameters for the open function are as follows
- struct inode *inode
- struct file *file
The inode refers to the device node found on the file system The file is a structure, created by the kernel, to hold the state of our use of the device within the device driverA typical Open Function is shown here
static unsigned long scmd_is_open static int scmd_open(struct inode *inode, struct file *file) { // allow only one user if(test_and_set_bit(0, &scmd_is_open)) return -EBUSY; // Activate the system scmd_start(); return nonseekable_open(inode, file); }Note that nonseekable_open open is defined in fs/open.c
/* * This is used by subsystems that don't want seekable * file descriptors */ int nonseekable_open(struct inode *inode, struct file *filp) { filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); return 0; }This is a typical close function. It is sometimes called release.
static int scmd_release(struct inode *inode, struct file *file) { // release the driver for others clear_bit(0, &scmd_is_open); // we are done return 0; }
A Basic Char Device Driver
A Basic Char Device Driver
The following code represents a most basic device driver. This code can be compiled to run on the host or the target systems. It is broken up into sections to help understand it.
Although this device driver does not have any actual Device Driver code it does perform the proper kernel functions to get to the point where the driver code can be added.
Although this device driver does not have any actual Device Driver code it does perform the proper kernel functions to get to the point where the driver code can be added.
Includes and defines
/* * Basic Character mode driver */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #define SCMD_DEV "scmd_basic" /* For static major number */ static int scmd_major = 250; /* For dynamic major number */ static int scmd_major = 0;
The fops table
Here we fill the file operations table with NULLs so that the kernel knows that this character device driver is unable to handle any sort of file system request (like read/write/ioctl/etc…).
struct file_operations scmd_driver_fops = { NULL };
Module registration
Here is the code that registers the module as a character device driver.
static int __init scmd_init(void) { int ret; ret = register_chrdev(scmd_major, SCMD_DEV, &scmd_driver_fops); if (ret < 0) { printk(KERN_NOTICE SCMD_DEV ": chrdev registration failed (ret=%i)\n", ret); return ret; } scmd_major = ret; printk(KERN_INFO SCMD_DEV ": register major %i\n", scmd_major); return 0; } module_init(scmd_init);Here is the cleanup code to remove the character device driver.
static void __exit scmd_exit(void) { int ret; ret = unregister_chrdev(scmd_major, SCMD_DEV); printk(KERN_INFO SCMD_DEV ": unregistered char device (ret=%i)\n", ret); } module_exit(scmd_exit);
The Linux Driver Model
The Linux Driver Model
This can best be described by examining a typical write system call. This is performed after an open call during which the kernel checks for user permissions on the device node and then creates an entry in the file descriptor table for future device access.
Following the open call the user process can then proceed to exchange data with the device using a number of methods.
*
read / write send and receive buffers to and from the device
*
ioctl send commands and a data buffer to the device
*
proc examine driver characteristics and even perform full communications
*
poll / select get notification when the device can provide or process data or has an exception
*
misc a number of misc system calls to seek and get signals on io completion.
The user process uses an index into the file descriptor table to define the major number which in turn refers to a particular device driver which uses a file operations table to satisfy a system service call for a given device operation.
In this example a user write call is shown.
A block of data in user space is to be transfered to the device driver in kernel space for eventual distribution to the device.
Friday, September 10, 2010
How Many Types of Device Drivers.
How Many Types of Device Drivers.
Following the “everything is a file” Unix™ tradition, device drivers are used to allow user code access to kernel functions controlling a number of peripheral components.
There are 3 classes for device drivers
■character drivers
■block drivers
■network drivers
Character drivers are widely use for a number of simple and more sophisticated applications. These range from simple led flashers to IEEE1394 ( firewire ) and USB drivers.
Block drivers interface to the file system and are used to mount things like disk partitions. They differ from simple character drivers in that access to the device data is usually buffered by the kernel.
Network drivers have a different structure and are closely connected with the network stacks that can be built into the kernel. They use ports and sockets to route data packets within, as well as to and from the system.
The user is normally not allowed to execute kernel code or access Input/Output (I/O) devices. When this functionality is required an application should use a device driver. They are quite easy to build and very fast to run so consider creating a device driver for all your I/O needs.
A device driver can be a module or it can be statically linked into the kernel. An appropriate kernel registration function is executed during the module init process.
(Replacing the simple printk used in the module example.)
This function passes pointers to one or more functions internal to the driver and may include some other parameters.
A device driver will register the following components:
■a fops table
■a Major Number
■a Device Class (block or char)
■a name
Special files called device nodes are created on a file system that hold the class, Major and Minor number of a particular device.
The device driver registers a number of callback functions that are used to extend the default behaviour of the kernel when accessing these device nodes. These functions are recorded in a file operations table.
The open system call retrieves that Major number and then looks for a device registered by the Major number in the device table to recover the fops table for the device.
This information is then recorded in a special per process table called the file descriptor table. The process uses a simple integer index (fd) to access the file descripter table entry after it has been opened.
Following the “everything is a file” Unix™ tradition, device drivers are used to allow user code access to kernel functions controlling a number of peripheral components.
There are 3 classes for device drivers
■character drivers
■block drivers
■network drivers
Character drivers are widely use for a number of simple and more sophisticated applications. These range from simple led flashers to IEEE1394 ( firewire ) and USB drivers.
Block drivers interface to the file system and are used to mount things like disk partitions. They differ from simple character drivers in that access to the device data is usually buffered by the kernel.
Network drivers have a different structure and are closely connected with the network stacks that can be built into the kernel. They use ports and sockets to route data packets within, as well as to and from the system.
The user is normally not allowed to execute kernel code or access Input/Output (I/O) devices. When this functionality is required an application should use a device driver. They are quite easy to build and very fast to run so consider creating a device driver for all your I/O needs.
A device driver can be a module or it can be statically linked into the kernel. An appropriate kernel registration function is executed during the module init process.
(Replacing the simple printk used in the module example.)
This function passes pointers to one or more functions internal to the driver and may include some other parameters.
A device driver will register the following components:
■a fops table
■a Major Number
■a Device Class (block or char)
■a name
Special files called device nodes are created on a file system that hold the class, Major and Minor number of a particular device.
The device driver registers a number of callback functions that are used to extend the default behaviour of the kernel when accessing these device nodes. These functions are recorded in a file operations table.
The open system call retrieves that Major number and then looks for a device registered by the Major number in the device table to recover the fops table for the device.
This information is then recorded in a special per process table called the file descriptor table. The process uses a simple integer index (fd) to access the file descripter table entry after it has been opened.
Thursday, September 9, 2010
Introduction
What Is A Kernel Module?
http://www.tldp.org/LDP/lkmpg/2.6/html/x40.html
So, you want to write a kernel module. You know C, you've written a few normal programs to run as processes, and now you want to get to where the real action is, to where a single wild pointer can wipe out your file system and a core dump means a reboot.
What exactly is a kernel module? Modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. For example, one type of module is the device driver, which allows the kernel to access hardware connected to the system. Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image. Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality.
http://www.tldp.org/LDP/lkmpg/2.6/html/x40.html
So, you want to write a kernel module. You know C, you've written a few normal programs to run as processes, and now you want to get to where the real action is, to where a single wild pointer can wipe out your file system and a core dump means a reboot.
What exactly is a kernel module? Modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. For example, one type of module is the device driver, which allows the kernel to access hardware connected to the system. Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image. Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality.
Subscribe to:
Comments (Atom)