ARTICLE:
I am working on Character Driver on Linux from last few days.Device Driver is simply a piece of code as a part of kernel,dynamic (temporary) or static (permanent) required to make the hardware accessible to the application. Device Drivers can be classified into three basic types: Character driver, Block driver and Network driver. A character device is one that can be accessed as a stream of bytes i.e. character by character. And code needed make communication possible b/w a character device and application is character driver.
As there is a very good feature of Linux i.e. the ability to extend the set of features offered by the kernel at runtime. This means that we can add functionality to the kernel (and remove functionality as well) while the system is up and running. Each piece of code that can be added to the kernel at runtime is called a module. Different types (or classes) of modules,that can be inserted to the Linux kernel includes device drivers but not limited to this. Each module is made up of object code that can be dynamically linked to the running kernel by the insmod program and can be unlinked by the rmmod program. Whenever we do insmod, the macro ‘module_init’ invokes our initialization routine and module is inserted to the kernel if it is valid. And when rmmod is done our module gets removed from the kernel through the macro ‘module_exit’. Our initialization routine registers the driver for the devices and obtains major no. from the registration call( int register_chrdev_region(dev_t first, unsigned int count, char *name); or int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);) and sets up some basic parameters we’ll be using ahead e.g struct ScullDev’s elements. Also we have to initialize the resources that are going to be used.In module_exit the opposite of initialization procedure is performed in reverse order.All the resources allocated to the driver to be freed and this is done by exit routine.After our module gets inserted successfully to the kernel,it can be seen in ‘/proc/modules’ file.And if we are able to register our driver successfully, we can see the driver’s name in ‘/proc/devices’ file.
To implement our character driver we have used SCULL (Simple Character Utility for Loading Localities). Scull acts on a memory as though it were a device.The advantage of scull is that it isn’t hardware dependent. Scull just acts on some memory, allocated from the kernel. Anyone can compile and run scull.We have mapped the system calls to the routines written in our own driver i.e. we have defined the behaviour of the system calls for a particular device. We have used cdev_init and cdev_add functions to initialize the struct cdev and inform the kernel about the device. In our open routine,we are checking the mode,the device is trying to being opened. And depending on that mode flags we are performing some specific tasks e.g. if device is opened in write only mode then the device memory will get trimmed before going ahead.In trimming routine we just free all the memory allocated to the scull. Also in open routine we are mapping the scull to the device by using the macro ‘container_of’.In brief it simply maps the scull into the device and returns a pointer to the memory of device having scull mapped onto it.And we have stored this pointer into the void pointer ‘filep->private_data’ to preserve the starting address of device memory for further use. In our write routine we are writing the data from application to the device through the scull quantums by using ‘copy_from_user’.Write routine also checks for the offset value i.e. cursor position where application wants to write.In read routine we are copying data from the device through scull quantums using ‘copy_to_user’ function.Read routine also checks for the offset value from where application wants to read. We have also implemented lseek routine that sets the offset value as provided by the application in lseek system call.And finally in release routine we have just released the resources used after opening the device.