When I was learning Linux device drivers I faced a lot of challenges. The reason was I didn't find any article which talks about device drivers from lehman point of view.
The article I have written here is for people who are from different operating system backgrounds or from different technology altogether.
I have divided the article in 5 stages and every next stage will be the superset of the next stage.
As a new learner I recommend people to understand every API of the code below before reading any driver development book.
Ok so without wasting much time let us start the stage 1.
Stage 1
Stage 1 is going to talk about the fundamentals of a device driver module.
Look at the below code and try to understand purpose of every api or include file:
/* filename: fld.c */
#include /* module_init and module_exit APIs are declared */
/* __init/__exit - [include/linux/init.h] * After boot, the kernel frees up a special section; * functions marked with __init are dropped after boot is complete: similarly * modules discard this memory after initialization. * __exit is used to declare a function which is only * required on exit: the function will be dropped if this * file is not compiled as a module. */ static int __init fld_init(void) { printk(KERN_INFO "FLD Init Called"); return 0; }
static void __exit fld_exit(void) { printk(KERN_INFO "FLD Exit Called"); }
/* The module_init() macro defines which function is to be called at module insertion * time (if the file is compiled as a module). * The module_exit() macro defines which function is to be called at module removal * time (if the file is compiled as a module). */ module_init(fld_init); module_exit(fld_exit);
/* In kernel 2.4 and later, MODULE_MODULE_LICENSE mechanism help identify code licensed * under the GPL so people can be alerted that the code is non open-source.*/ MODULE_LICENSE("GPL");
/* MODULE_DESCRIPTION() is used to describe what the module does, MODULE_AUTHOR() * declares the module's author */ MODULE_AUTHOR("Mukesh Krishna"); MODULE_DESCRIPTION("For self-learning LDD"); |
The code is self explanatory. module_init and module_exit are core of the driver since these functions get called when we insert or remove the driver.
Create a file name Makefile and fill the content:
obj-m := fld.o |
Run the following command in your terminal:
$ make -C /lib/modules/$(uname -r)/build M=$PWD modules |
Note: Please post in the comment if you see any error. I already checked it and don’t see any errors.
Once you compile you should have fld.ko in your folder. Just cross check.
Follow the steps below:
Inserting the module
Inserting the module means the module will be plugged into the kernel. To do it, run the following command in the terminal.
Note: insertion or removal of modules need superuser permission.
$ sudo insmod fld.ko |
Removing the module
When your purpose is done, it doesn’t make sense to have the driver still loaded into the kernel. Like when your work with a pen drive is over, you remove the pen drive and once the pen drive is removed there is no purpose of the USB mass storage driver and subsequently it also gets removed.
To remove the driver from kernel, following command needs to be run:
$ sudo rmmod fld.ko |
It is important to know if your driver is actually loaded or removed otherwise it doesn’t make sense to do all the above activities.
To see if the module driver is loaded or removed or any other function we perform on it, we need to see the debug log message of the kernel. Please run the below command to see kernel message:
$ sudo tail -f /var/log/syslog |
My additional suggestions will be to have 3 terminal tab and reserve each one one of the below activity:
Compilation
Operation performed on kernel driver
Viewing log message
In the log message you should see the message during inserting module and during removing the module.
On driver insert, you should see “FLD Init Called” while on removal you should see “FLD Exit Called”.