Article on Character Driver
This Article describes you the process of writing a Character Driver module. The Linux kernel version used is -3.3.4-5. Character Driver operates on Bytes that is transferring data byte by byte or character by character. Serial port driver, key bord driver and mouse driver are some real time examples for character Driver. Character Driver is one of the mechanism of running the driver policy. Each Driver has similar policie with different mechanism. One among them is our discussion that is character driver which provides communication between application and hardware upon Inserting the module on demand and removing the module after the task completion. The module can be inserted using the command insmod and removed using rmmod.
The driver starts with device registration done using alloc_chrdev_region ( ), by which the device is registered at kernel and for every device registration a major and minor number is allocated for the device and is stored in a variable of type dev_t dev . Major number specifies the Driver and minor number specifies the devices connected (type of mechanism followed by that driver) and are independent of devices. Dev variable is of 32 bit of which first 12 bits represents major number and the next 20 bits represents the minor number. After allocation of major and minor numbers they can be extracted using predefined macros called MAJOR(dev) and MINOR(dev). Defining the way of opening the Device, writing, reading procedures and closing the device plays an important part in Implementing the mechanism of char driver.
SCULL(simple character utility for loading localities) defines the procedural mechanism of char driver and is apart from opening a normal low level file .The real flavor of character driver is defined in its SCULL, which describes the memory allocation strategies, way of performing the operations and procedure for loading localities. The SCULL contains blocks of memory called scull_qsets and each scull_qset contain qsets which handles array of pointers pointing to specific bytes of data called quantum. The scull_qset can handle upto maximum of data equal to product of qset_size and quantum size. Further each quantum can handle upto maximum of bytes equal to quantum_size defined by driver developer. Mathematically we can find the required number of scull_qsets and quantums required for accommodating given number of bytes and memory is allocated for scull_qset and quantum accordingly.
Number of Scull_qset =data_size/ (qset_size * quantum_size)
Number of quantum= data_size/quantum_size;
In order to reach data quantum we have to point from sculldev->scullqset->data[i].
Writing and reading data can be done only on quantum. cdev(charecter device) is an important member of sculldev which points to a structure containing file_operations specific to driver routines. The operations are mapped and specific sub routines are defined which defines the specified operations ( open,read,write and close). Ones the scull is prepared required size of memory is allocated using kmalloc. The scull structure is initialized through cdev cdev_init and is added to the kernel using cdev_add.
Now the main part is to define the file operation subroutines. Before performing writing and reading operations, the device has to be opened and from open mapping of SCULL on to device memory is done using predefined kernel facility container_of which contain starting address of scull as its return value. This value is preserved in private_data which is a member of struct file. The private data can be fetched before performing write and read operations. The write operation specifies writing data from application to kernel buffer which can be handled using kernel facility copy_from_user and reading specifies reading data from kernel buffer to user buffer at application which can be done using copy_to user.
Everything in linux is a file, whenever you connect a device it is treated as a file and an inode is created for that file. The communication between application and kernel is carried out using FIFO(named pipe) created using command mknod. So through FIFO, utilizing the mechanism of SCULL the communication between application and the kernel will be carried out.
Note:The article tries to describe the procedure for implementing the character driver and the syntax is not concentrated as of now. The further Implementations will be added on in the next article. Comments and doubts are welcome.
Thank you
Sampath Kumar Kotigari.