Ever wanted to get into the world of Linux Driver Development and started with LDD book:
- Then looked at the ‘Hello World’ driver module, finished it successfully. Later after introspection found it was too easy and did not learn much ‘critical’!
- After reading a few pages, eventually realized its not for you and left the journey?
If this is the case, go ahead and read further..
Well, its not that easy or that difficult. However ‘careful’ is the word one should always remember, as any small misadventure can ruin the system. Just follow this:
- Take a deep breath
- Just understand what you are doing
- Leave the mentality of user space development, outside the room
- Follow the best practices in the kernel space development
Here, I’m going to take a live module from Linux kernel space as an example to get started and show how to tweak and learn more in the process of ‘Linux Driver Development’!
SDIO UART Driver
You can find this driver module at drivers/mmc/card/sdio_uart.c in the Linux source. Thanks to Nicolas Pitre and Co. this driver module is a loadable kernel module, which means this driver you can tweak, build, and install, all this.. while the kernel is running!
You can download the Linux kernel source from kernel.org. Untar the tar ball at a preferred location. Then create a directory, say ~/ldd_live, and copy the sdio_uart.c from drivers/mmc/card/ location.
Now we’ve got the source. However we need to tweak and then build, for that we need a Makefile. Let’s create it.
I have my Linux kernel source at /home/thecottonsilk/linux-2.6.36/. So, my Makefile uses the source path as below.
obj-m += sdio_uart.o
make -C /home/thecottonsilk/linux-2.6.36/ SUBDIRS=$(PWD) modules
make -C /home/thecottonsilk/linux-2.6.36/ SUBDIRS=$(PWD) clean
As you would know, this Makefile, allows two possibilities:
- To build the driver module, and
- To clean the driver binary and other intermediate files, as needed.
Now let’s build the driver module to confirm Makefile works.
Follow the command under the ldd_live:
You can see, Makefile creates many intermediate files and then the required file sdio_uart.ko. This .ko file is the one which would help us load the SDIO UART module.
Install the LKM
Use following command to first remove the existing SDIO UART module if any.
Use following command to install the SDIO UART LKM.
Important SDIO UART Driver APIs
Important meaning important for this article, otherwise all the APIs are required and that is why it exists there! SDIO UART driver has two APIs sdio_uart_receive_chars() and sdio_uart_transmit_chars() for reading and writing data to a SDIO client respectively.
You can refer the source for further details.
Tweak SDIO UART Driver
Here, I will just go by ‘Hello World’ example way, and add only one ‘printf’, ouch..I’m sorry, old habits die hard! As you would know, at Kernel space we use ‘prink’ statement to output a string.
So, here we go:
Add following printk statement under sdio_uart_transmit_chars() as below:
len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);
printk(KERN_DEBUG “Attempting to write %d byte(s) \n”, len);
Let’s save the changes and build module.
> make clean
Let’s install the LKM.
> rmmod sdio_uart
> insmod ./sdio_uart.ko
Test SDIO UART Driver
Now that the LKM is loaded, let’s verify that whatever change we made is working inside the kernel or not. This can be done by inserting a SDIO card into the SD/SDIO slot of your system (I’m assuming your system has one).
Let’s confirm the SDIO card is initialized, by using following ‘dmesg’ command:
If the SDIO card is successfully initialized, at the end of the dmesg output you should see the acknowledgement of SDIO card being recognized. Otherwise, you should see some error message because of timeout error, etc. One thing can be tried out under such circumstances is to re-insert the card and verify.
For more details, you can go through following references:
- SDIO Specification Version 2.0
- SDIO info
- LDD Book
To understand the SDIO protocol.
Visit the SD/SDIO website for more information on SDIO.
Best documentation is the source – people say. I agree very minimally. That statement is true provided the code is well-written. Well, the SDIO UART driver is easy to understand, provided you know the details like, tty layer, SDIO protocol, other dependent source under driver/mmc/core, etc.
To understand the intricacies of the driver development.
Fine then, ALL THE BEST!
Intentionally I have left some of the minor details, so that there will be some queries in the comments! 🙂