Operating Systems

DM510, Spring 2009

Daniel Merkle

DM510 Required Assignment 2: Kernel Module

In this assignment, your task is to make a kernel module. This module must implement a driver that exposes two character devices to user-space. Their function will be explained below.

To complete this task it will be necessary to study the following sources:

  • Chapters 2, 3, 5 (especially for semaphores) and 6 (especially for blocking and non-blocking I/O and for device control with ioctl) in the online book Linux Device Drivers (LDD), 3rd edition (for 2.6 kernels) hold all the information you need to complete this assignment. The original source code of all examples from LDD can be found here. At the time of writing LDD, the Linux kernel 2.6.10 was used. An updated version of all files that should work with kernel 2.6.28 can be found here.
  • You can also use The Linux Kernel Module Programming Guide [pdf, ps.gz, html] as a source of information.

The files that you can use as a starting point for you kernel module can be found here.

The Driver

Normally a device driver sits between some hardware and the kernel I/O subsystem. Its purpose is to give the kernel a consistent interface to the type of hardware it "drives". This way the kernel can communicate with all hardware of a given type through the same interface, even though the actual hardware differs.

In this assignment we will not interface to hardware because of the complexity this would impose. Instead we will make two processes communicate trough a device driver.

The figure to the left illustrates how the driver should work. Basically it solves the producer-consumer problem. Here the two processes can be both producers and consumers. This resembles the functionality of a real hardware device driver, where both the hardware and the kernel can produce and consume data.

When a process writes (produces) to character device /dev/dm510-0 the data is stored in bounded buffer 1. If the buffer is full the process has to wait until another process has read from /dev/dm510-1.

When a process reads (consumes) from character device /dev/dm510-0 the data is read from bounded buffer 0. If the buffer is empty the process has to wait until another process has written to /dev/dm510-1.

Writes and reads to and from /dev/dm510-1 are handled in the same way.

In the code from LDD there is an example (scull/pipe.c) which does almost the same (chapter 6 of LDD). The difference is that only one character device has been used (one minor). This means that the data you write to it can be read back from the same device.


The requirements are:

  • You should either use a major number of 254 and minor numbers of 0 and 1 or automatically assigned major/minor numbers (see Chapter 3 of LDD).
  • Blocking and Non-blocking I/O must be supported (see Chapter 6 of LDD, page 147ff).
  • Several processes at a time must be able to open each device for reading, only one process at the time should be able to open a device for writing.
  • A certain degree of device control should be possible via the ioctl system call. Implement for example adjusitng the buffer sizes or the maximal number of processes thar are allowed to read the device at a time via ioctl (see Chapter 6 of LDD, page 135ff or Chapter 7 of The Linux Kernel Module Programming Guide).
  • The device should support multiple processes executing simultaneously in the device driver at the same time. As this could lead to race conditions and other problems, you should use semaphores (or other synchronisation methods) to avoid potential problems.

This is not required:

  • Backward compatibility. The module does only have to be compatible with kernel other than 2.6.28.
  • udev and devfs support.
  • Poll, select and asynchronous notification support (see Chapter 6 of LDD).

Attacking the Problem

The hardest part of most kernel programming is to understand the environment that your code should run in. Therefore, most of your time should be spent studying how character devices work. This will minimize the testing and debugging phase. Recommended is to start with reading the first chapters of LDD. Here is a starting point for your implementation:

Compiling and inserting a simple module

Create a working directory for your project as a subdirectory of the directory dm510, that you created for installing UML. Fetch the files that are the starting point for your implementation (dm510_dev.c, Makefile, dm510_load, and dm510_unload), store them in the working directory, change into the working directory containing these files and edit Makefile if necessary. (You may have to change the KERNELDIR variable with the path to your UML kernel, if you are using a non-standard location).

Now you can compile the module by running make. If the compilation succeds there will now be a file called dm510_dev.ko which is the module. Start the UML kernel. Create the necessary devices and insert the module by executing


To remove the module and to delete the devices execute:


See LDD chapter 4 and check the two scripts for details.

Making the Driver

The file dm510_dev.c is the code for the simple module above. It has almost empty declarations of all the functions that you need to modify in order to complete this assignment. These are:

int dm510_init_module(void);
void dm510_cleanup_module(void);
int dm510_open(struct inode *, struct file *);
int dm510_release(struct inode *, struct file *);
ssize_t dm510_read(struct file *, char *, size_t, loff_t *);
ssize_t dm510_write(struct file *, const char *, size_t, loff_t *);
int dm510_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);

To get an idea of how to implement these functions you should study the implementation of the scull device driver, especially the pipelined version of the driver. This driver is explained in detail in LDD, especially pages 153ff. The source code including the necessary script to load and unload the driver can be found here.. Study this example thoroughly, especially pipe.c.

Report / Submisson

The report submission procedure is similar to the submission procedure of the first required assignment. The report must be short and precise (maximum 10 pages, English langauge, without source code). Remember that you must prove that you have understood the problems and solutions. It must include the following:

  • A small introduction.
  • A description of the design decisions you have made.
  • A description of your implementation.
  • A description of the tests you have made and the motivation for these. The tests must be able to verify that your solution works correctly, but you do not have to test all possible error scenarios. Remember it is better to document a bug rather than just ignoring it. An inspiring test program for one test can be found here.
  • A discussion of what would happen if multiple processes use the devices simultaneously.
  • A small conclusion.

Furthermore, your report has to be supplemented again by a recorded desktop session, in which you show that your implementation is working correctly. During the session you should also perform all or some of the tests that you described in your report. In your report you should refer to the tests you performed by giving the precise time in the video file. The session you record should start when you start UML with the command ./linux in a shell. The recorded session should be maximally 5 minutes long and have a maximal size of 20MB. If one of these constraints is not fulfilled the video file will be considered as not submitted.

For recording the desktop session you should again use the tool gtk-recordMyDesktop. Do not forget to change the "Video Quality" to 10 (using the slider), and the "Frames per Second" to be recorded to 5 (Advanced Setting / Performance) to reduce the file size. Sound recording is not required.

For submitting the report, the sources, and the desktop session, proceed as follows: Create the following directory structure


Put your report, sources, and video in the corresponding directory. The sources should not include the source code of the complete Linux kernel, but only the files you changed and those files you added. The report direcory and the sources directory should not contain more than 10MB of data. Similar to the size of the video file: If this constraint is not fulfilled the submission will be not considered.

Change to the directory assignment2 and type aflever DM510.

Additionally, in contrast to the first required assignment, you shall hand in a printout of your report and of your source code. (Department secretaries office).

The strict deadline for submission (electronically and printouts) is Thursday, April 23rd, 13:00. (This deadline was extended from 22nd to 23rd because of file server problems on April 21st).

As this project is quite resource consuming, please take care, that you clean up your home directory and that you remove unneeded files as soon as possible.

Note that the third required assignment is scheduled to be announced at the beginning of week 16 (probably Tuesday, April 14th). The last required assignment will require a significantly larger amount of implementaion. Therefore I recommend to submit this second required assignment before the strict deadline.

Frequently Asked Questions (FAQ)

  • Are we allowed to work in groups?
  • For everything except the report and recording the desktop session, you are allowed to work in groups of at most three people. Write the members of your group on the front page of your report. The report you have to write on your own. Remember that the three required assignments are part of your final exam, i.e., you have to fully understand all parts of what you have done.

Design by 1234.info | Modified by Daniel Merkle | CSS 2.0