The goal of this practical is for you to write a simple character device driver as a kernel module. You will be using chapter 3 of LDD3 (Linux Device Drivers, 3rd edition - see the Resources page) as reference. You may also need to find some references online to complete some of the functionality - a Google search for "linux character device driver" is a good starting point.
You will need the module developed in the previous practical.
Please note it is strongly recommended that you do all kernel development on the virtual image (we recommend ssh'ing in using ssh(1) or Putty on Windows) as it is very easy to crash the kernel you are working on while doing development. It is possible you may lose data if you work on a physical Linux machine and crash its kernel.
Before attempting to implement this prac, you should skim through chapter 3 of LDD3 book as stated above.
The character driver you are writing should buffer any data written to it, allowing the same data to be read out. The following assumptions/restrictions apply:
You will need to implement the functions given in the .c file given below, using the LDD3 book for reference. Note that before you can build your device, you will need to intergrate it with the module you created in the last practical.
The following memory allocation functions may be useful to you:
Add a printk() call to the device_open() function so your module prints something out every time it is opened.
Either merge the .c file from the last practical with this one, or see if you can find a way to build a kernel module from multiple source files.
To use the device, you first need to register it. To do this, you must print out the major and minor numbers that the module is assigned using printk(). This way, when you load the module, you are able to see the identifier the kernel has assigned the module. Once you know these numbers, type the following:
mknod device c MAJOR MINOR
(where MAJOR and MINOR are the major and minor numbers you found out before). This creates a block device on the file system (called device) that looks like a file. You can now use this to access the device.
Try running cat device and noting the output (if any). What is the return status? What happened? Check dmesg to see if the printk() you added is printed.
Now write a userspace test program (in C) that performs the following functions:
After running the test program, try to unload the kernel module. Does it work?
Don't throw away the code you have written in this prac - it will form a basis for assignment 2.
It is recommended you read the LDD3 chapters that are linked on the Resources page, as they will be invaluable for completing assignments 2 and 3.