EmbLogic's Blog

Article – Character Driver

With the help of this article I am going to brief the basics of character driver & the work done by me till date.
First of all few questions arises in our mind that what is a driver & what is the need of driver in OS?. In general, driver is used to run or drive something. Here we are using driver(set of codes) to setup communication between the Hardware Device and the Operating System, so that our OS can drive nothing but access the device with the help of the “Device Driver”.
Device Drivers are also described as Loadable Kernel Modules (LKM), as these modules are loaded when ever & where ever used. This concept of using drivers increases the run-time efficiency of the Kernel.
We are right now working on the project i.e. “Development of one of the driver named as Character Driver “.
Character Driver operates on the basis of transferring the data character by character. In our project we are dealing with one application running on the user space & our Device Driver running on Kernel space. Till date we are working on creation of Multi Threaded Application in our Char Driver coding which consists of follow steps –
Initialization of driver -> Mapping of system calls from application to the driver -> open call -> Mapping of memory on to the device (including trim function) -> Write call -> Read call -> Seek call ->use of multi threaded application.
We have used command “insmod” to call the initialization macro i.e. module_init() which will insert the driver into the list of modules & “rmmod” to call the cleanup macro i.e. module_exit() which will remove the driver from the list. Driver starts with the registration using alloc_chrdev_region(). This registration (using alloc_chrdev_region()) is done so as to get the major number dynamically for the driver. Correspondingly a minor number is generated for the first device. We can also use register_chrdev() to register the driver if we want to assign the user defined major number.
After registration we got a 32 bit number stored in “dev” which is of “dev_t” type. First 12 bits will give major number by using macro “MAJOR” & remaining 20 bits will give the minor number by using macro “MINOR”. After getting the major & minor number, now its time to initialize the SCULL i.e. Simple character utility for loading localities. SCULL is a char driver that acts on the memory area as though it was a device. This SCULL is defined by a structure “Sculldev” contains blocks of memory called scullqsets which are also called as items and each item contains qsets which are nothing but array of pointers pointing to specific locations known as quantums. The scullqset or item can handle data maximum upto the data equal to product of qset_size and quantum size. Further each quantum can store maximum of bytes equal to quantum_size defined by the developer. We can calculate the number of scullqsets and number of quantums required for storing given number of bytes. One thing which is very important that these “items” or we can say that “scullqsets” should be linked like “link list” so as to store the data in quantums of different scullqsets.
After initializing the structure Sculldev, now we have to initialize the structure C_dev which will give the information of our device i.e. Owner of the device, Major & Minor numbers, operations that our device can perform etc. After this its time to map the system calls to the corresponding functions defined in the driver. As the mapping is done so now from the application end we will call the open system call which will call our defined function in driver. In normal routine open call creates a stream and after handing over of the stream this call terminates. For our driver we have written our own routines. In our open function we have used a macro “container_of” to map the memory allocated for scull from RAM to the device & along with the link of “Structure inode” with “Structure C_dev & SCULL. This mapping will return the starting address of the SCULL which we will store into the “private data” of the “Structure file”. When ever & where ever if we want to access the sculldev we will fetch the private data. After sending the address of Sculldev we will call the trim function. If we want to write on to the device, we have to check whether the device is having something onto its memory or not. If we found anything in quantums, we first trim the data nothing but flushing out the previously written bytes.
After trimming we will call write from the application. This write system call will call the write function which we have in our driver as we have already mapped all the operations to be performed by the applications in “Structure file_operations”. Writing here means getting the data from the user buffer & writing it on the quantums present in the SCULL i.e. Memory of device. In the starting of write function we will fetch the private data so as to get the address of SCULL. For writing we will use “Copy_from_user()”. Before writing we will calculate the number of items (scullqsets) to be created along with the number of quantums. Now we want to read what we have written earlier in the quantums. For this we will call the read function. This means reading the data from the quantums & passing it to the user buffer which we will receive in our application. For this we will use “Copy_to_user()”.
We have also done with seek function. Seeking means changing the position where we want to read or write. After seeking Multi Threaded Function is also created. Testing of is new threaded application is done & its working fine.
In linux everything 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 “node(named pipe)” created using command “mknod”. The application cannot access beyond this node. This node is the only medium from which the application will interact with the device driver.

This is all about what I have done till date in character driver coding.

Thanks
Rahul Attreja

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>