Get in touch:
01524 851 877
07718 896 553

Hash Table Implementation

Posted on Jun 12 2009

I have been doing some more kernel module coding and have been using the linked list implementation provided by list.h quite a bit recently as I have known in advance that the lists would only ever have a small amount of entries so looping through the list would not prove to be too much of a performance penalty.

For my latest problem however I have a list that could grow a bit larger in size so I made the decision to use a hash table instead of a linked list. I searched through the kernel source naively hoping there would be a neat generic hash table implementation included.. Alas there is not.

After a bit of searching I stumbled across uthash. This is a nice hash table implementation allowing you to basically put any struct into a hash table based on using one of the fields in the struct as the id. The included macro’s allow a string or an int to be used for the id as well which is quite useful.

So far it seems quite simple to use. All the functions are included in one header file wrapped us as macro’s so it is nice and easy to integrate with any project and it doesn’t rely on much to be included externally. In my case all the functions it does need are provided by the kernel so it was very simple to integrate. I will definitely be using this again in other projects in the future.

Simple Sleeping Linux Kernel Thread

Posted on May 26 2009

I am currently implementing the timeout functionality for the NP++ kernel module. Each physical mapping has a function pointer defined in its descriptive struct (struct np_sw) as described here.

Until now this hasn’t actually been implemented but I wanted to create a kernel thread that simply sleeps for 500 milliseconds, then awakes and looks through all the physical mappings available on the system and calls their timeout function.

This is a fairly simple process but in order to achieve it we need to include a couple of new headers :

#include <linux/kthread.h>
#include <linux/delay.h>

The first of these is for the thread related functions needed and the second is to allow us to sleep the thread.

Now we have those included we need to declare a function that will be called when we start the thread as follows :

int timeout_thread(void *data)
Any kernel thread function needs ro return an int and take a void pointer as the only argument to conform with the function pointer defined the kthread_create() function in kthread.h which the kthread_run() macro is a wrapper for.

Now we need to actually create the thread. I have done this in the modules init_module() function as follows:

kthread_run(timeout_thread, NULL, "NP++ Timeout Thread");
Now this is all done we simply need to put some implementation into the timeout_thread() function to perform the sleep as follows:

while(1)
{
set_current_state(TASK_RUNNING);
//Some Code Here
set_current_state(TASK_INTERRUPTIBLE);
msleep(500);
}

This sets the state of the thread to TASK_RUNNING to tell the kernel that the thread is working. The code to call the mappings individual timeout functions will go here. Then we set the state to TASK_INTERRUPTIBLE to tell the kernel we aren’t doing anything at which point we call the msleep() function to sleep the thread for 500 milliseconds.

Compile the module and you have a nice thread that will run roughly every 500 milliseconds. If you need a longer delay that can be measured in seconds the delay.h header also defines the following function that takes the number of seconds as the only argument:

void ssleep(unsigned int seconds);

Compiling Linux Modules Dependant On Exported Symbols

Posted on May 12 2009

I have been playing around with the NP++ Linux Kernel module today and it all seems to be working as planned at present. However I was in the process of writing a sample physical mapping module that uses the API from the NP++ module and ran into a bit of a problem.

Within the NP++ kernel module I have exported a few symbols (functions and variables) using the EXPORT_SYMBOL() macro. I expected to be able to use them quite simply in any other modules I created by simply including the NP++ header file. I had declared them as ‘extern’ in the header file and used the EXPORT_SYMBOL macro in the .c files as per all the documentation I had come across.

When I came to compile the mapping module that was trying to use these exported symbols however I came across a problem that the function I was trying to use was being shown as undefined during the link stage. This had me a bit stumped as I had convinced myself that the symbol should be visible.

It turns out that understandably as I had just compiled the module the kernel symbols table didn’t actually know about the symbols I had exported so compiling the new module still couldn’t see them. It turns out that the simple solution to this problem is to copy the Module.symvers file from the directory of the NP++ module to the directory of the mapping module.

The moral of this rambling is that you need to copy the Module.symvars file from the directory of a module once you have compiled it to the directory of any other out-of-tree module you are writing that relies on exported symbols from the first.

Building A Kernel In Ubuntu

Posted on May 01 2008

As I mentioned in a previous blog entry, I have started using Ubuntu for pretty much all of my Linux needs over the past few years. However, up until now all of my kernel development work has been done using other distros.

Yesterday I decided to start doing some kernel development in Ubuntu for a project I am working on. The kernel compilation process is a bit different to the traditional method and this post simply lists how to compile a kernel using the Ubuntu tools. Please note that a lot of the commands listed hereafter will need to be executed as root.

First of all you need to grab the source of the kernel version you wish to compile. For me this is the Mobile IP version of the kernel from The Nautilus6 working group. This should be done from the directory in which you want the source directory to be, usually this would be /usr/src.

#cd /usr/src
#apt-get source linux-image-2.6.22-10-mip6
This should grab all of the source for you and put it in the directory /usr/src/linux-source-2.6.22-2.6.22.

Often it is a good idea to use the configuration file from the currently running kernel as a base for the kernel you are going to build. This should ease the transition from a stock kernel to one you have customised. This is done as follows :

#cp /boot/config-`uname -r` ./.configNow you are ready to start configuring your kernel.

#make menuconfigThis will bring up an ncurses based menu system that will allow you to configure your kernel options. If you prefer a more graphical environment in which to perform the configuration you can use the following :

#make xconfigNote that if you are using xconfig you should run it with either `gksudo` or `kdesudo` rather than just `sudo`. Although this shouldn’t be an issue in this case it is a good habit to get into as described here.

Once you have decided what configuration options you want for your kernel you are ready to build it. This is done using the following two commands.

#make-kpkg clean
#fakeroot make-kpkg --initrd --append-to-version=-your_kernel_name
kernel_image kernel_headers
The string after `–append-to-version`can be anything you want to distinguish this kernel from the others on the system.. Note that it must begin with a `-` and must not contain any whitespace.

Now you might want to go grab a coffee as this compilation will take quite a while, obviously the amount of time is dependent on your machine spec and your kernel configuration.

Once the compilation has successfully completed you should find two new .deb files in /usr/src. The name of these will vary depending on which kernel source you are using and what you appended to the kernel name. On my build they are named :

linux-headers-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
linux-image-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
All that is left to do now is to install these files using dpkg :

#dpkg -i linux-headers-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
#dpkg -i linux-image-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
Your new kernel should now be installed and ready to go if all the above steps went smoothly so just restart your machine and you should be running your home built kernel. To check this is the case once the machine has restarted just do the following in a terminal.

#uname -rThis should display to you the name of your home built kernel and you are ready to start experimenting with different configurations or why not start hacking about with the code and see what happens :)

This blog entry went on for a bit longer than i anticipated so for the impatient here is a quick fire list of commands for compiling the kernel in Ubuntu (change names in dpkg commands as necessary) :)

#cd /usr/src
#apt-get source linux-image-2.6.22-10-mip6
#cp /boot/config-`uname -r` ./.config
#make menuconfig
#make-kpkg clean
#fakeroot make-kpkg --initrd --append-to-version=-your_kernel_name
kernel_image kernel_headers
#dpkg -i linux-headers-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
#dpkg -i linux-image-2.6.22.9-custom_2.6.22.9-custom-10.00.Custom_i386.deb
Hope you found this useful and good luck with your new kernel.