INTRODUCTION:
Device driver is basically a module(piece of code) used to make possible the communication between hardware and application like VLC media player,firefox,USB devices etc.So device driver is used to drive the hardware according to the application.Different type of applications require different type of drivers like USB driver can’t work for VLC media player and vice-versa.
I think the need of using device drivers is to increase the functionality of kernel.We use the driver as LKM(Loadable Kernel Module) to make our kernel less bulky in size & also it is not essential to keep driver present in the kernel until system is power on.
I am working on Character Driver from last few days.In this article I am going to discuss what i know about character driver briefly.
Character driver sends the data byte by byte to the kernel buffer and user buffer when application give call of write and read respectively.
Now as I have to make my driver capable of directly handshake with the kernel so it was essential to work in kernel space instead of user space,so i have to use the kernel libraries(like kernel.h,init.h,fs.h etc..) instead of glibc libraries(like stdio.h,stdlib.h,fcntl.h etc…).
DEVICE DRIVER IMPLEMENTATION ROUTE MAP:
I firstly used two predefined macros named as module_init(entry_function) and module_exit(exit_function) as entrance point as main() in user space and exit point respectively.In this entry_function and exit_function is written by me.So after executing module_exit execution will start from my function where I have to specify the major number and name of our driver,capacity to handle maximum number of device at a time and maximun memory of the driver. I am firstly allocating major number to my driver which is basically a highest possible integer value between 0 to 255 by which our driver will be known in the kernel like other device drivers as stored in /proc/devices file.We can select major number for our driver from prevoiusly mentioned path but generally we privilege kernel to select major number because kernel will allocate it dynamically.This can be done with the register_chrdev_region() function call defined in fs.h kernel library.This will give the result of 32 bit(12 + 20 bit) at the address as give in first argument of call.Now later on i have used that the first 12 bit i.e major number but i specify my own minor number generally 0 to upward in MKDEV() macro defined in kdev_t.h.Now used the cdev_init() and cdev_add() to initialize and add the cdev structure for our device which will contains the device specifications.Now i initialize the sculldev structure(user defined structure that contain all information of the driver) to add the maximum memory of device and the partition of that memory like size of one quantum etc.
Now I have open,write,read,lseek and close file till now.So i have mapped these system calls in struct file_operations structure with my respective open,write,read,lseek and close functions according to prototype defined in <fs.h> kernel header file that will now handles the application calls instead of drivers of the OS.
But Before doing anything we have to map our allocated memory with the device memory this is done in the open function of driver with
container_of(ptr,type,member) in which first argument is pointer to i_cdev member of struct inode,2nd argument is user defined structure which contains pointer to struct cdev and third argument is pointer to struct cdev.Actually struct cdev is actual representation of the device.Now return of container_of will be starting address of mapped memory that we will use to read and write on device and i store this address in the private_data of the struct file structure defined in fs.h library.
After doing this now i have made my read,write and lseek function compatible with the almost all type of requests from application.In this write function will store the written data in own quantum when write request comes and give back that data according to the read request of application.I have also handled the single multi threaded application.
Now to test this driver firstly compile and insert our module in running kernel dynamically.This is done with command insmod <lkm.ko> on shell here lkm is my name of c file of driver.Compilation of the file should be by Makefile. And to make communication possible between application application and device driver,we require node in Virtual File System(VFS). Node is created by the commend “mknod node_name c major no. minor no.”,here c is to specify that is making for character driver.
After testing we should have to remove the module from kernel with command “rmmod” like rmmod lkm to free the allocated major number.
That was all i have done with character driver.
THANK YOU!!!