Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

Embedded Linux kernel

and driver development


Training lab book

Embedded Linux kernel and driver development


Training lab book

Free Electrons
http://free-electrons.com

1 © Copyright 2004-2008, Free Electrons, http://free-electrons.com, Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

About this document


This document is part of an embedded Linux training from Free
Electrons.
You will find the whole training materials (slides and lab book)
on http://free-electrons.com/training/drivers.
Lab data can be found
on http://free-electrons.com/labs/embedded_linux.tar.bz2.

Copying this document


© 2004-2008, Free Electrons, http://free-electrons.com.
This document is released under the terms of the Creative
Commons Attribution - ShareAlike 2.5 license. This means
you are free to download, distribute and even modify it,
under certain conditions.
Document updates and translations
available on http://free-electrons.com/training/drivers.
Corrections, suggestions, contributions and translations are
welcome!

3 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Training setup
The training labs are done with the vanilla version of Kubuntu
(http://www.kubuntu.org), a derivative of Ubuntu that uses the KDE
desktop environment. Most of the needed packages are readily
available from Kubuntu official repositories, but Free Electrons
provides an additional repository for other packages.

General guidelines
Useful during all the labs:
You should only use the root user for operations that require
super-user privileges, such as: mounting a file system, loading a
kernel module, changing file ownership, configuring the network.
Most regular tasks (such as downloading, extracting sources,
compiling...) can be done as a regular user.
If you ran commands from a root shell by mistake, your regular
user may no longer be able to handle the corresponding
generated files. In this case, use the chown ­R command to give
back the new files to your regular user.
Example: chown ­R myuser:myuser /mnt/labs/
In Debian, Ubuntu, Kubuntu and other derivatives, don't be
surprised if you cannot run graphical applications as root. You
could set the DISPLAY variable to the same setting as for your
regular user, but again, it's unnecessary and unsafe to run
graphical applications as root.
In Kubuntu running in LiveCD mode, do not store data or
generate files in /home/ubuntu. Otherwise, your system will
quickly freeze. /home is in RAM. The bigger /home gets, the less
RAM is left for your applications.

Different setup options


There are several setup options to use Kubuntu for the training labs :
The best option is to install Kubuntu on your hard drive. It allows
the system to be fast and offer all the features of a properly
installed system. This option is described in the section “Installing
Kubuntu”
The second option is to use Kubuntu in LiveCD mode. However, in
this mode, personal informations are stored in RAM, which will
not be sufficient for the training labs. The solution is to create a
big file inside an existing partition, that we will then use to store
informations. This option is described in the section “Using
Kubuntu in LiveCD mode with external image”
The third option is to install Kubuntu inside a virtual machine
emulator on your existing operating system. The installation
process is similar to the regular installation process, except for
the virtual machine emulator configuration, which depends on
your particular software.

Installation Kubuntu
If you are allowed to install GNU/Linux on your PC, you may choose
to install Kubuntu on your hard disk.
Real life experience from training life has shown that:
cdrom access is slow, making the system very slow to respond to

4
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

user interaction and to start new applications (not cached in RAM


yet). Many training users have asked to run Kubuntu from the
hard disk!
Experiments with kernel drivers can cause kernel lockups. Having
the training user home directory on the hard disk (instead of on a
ramdisk) is then very convenient. User settings (such as proxy
configuration) no longer has to be redefined over and over again
at each reboot. Similarly, you won't have to mount the lab
partition (including creating its mount point) at each boot.
A distribution running in LiveCD mode consumes a significant
amount of memory. On PCs which do not have much RAM, this
can also impact performance, because of reduced file caching in
RAM.
The cdrom medium or its driver is not extremely reliable. I/O
errors might happen (typically 2 or 3 times a week in a room
containing 10 PCs), corrupting the root file system, and requiring
a reboot.

Freeing space on the hard drive


In order to install Kubuntu and do the labs in good conditions, you
will need 10 GB of free space on your hard drive. It can work with as
few as 4 GB of free space, but you will have to clean up generated
files after each lab.
The standard way to create space is to shrink a Windows partition. If
you are not ready to touch any Windows partition (typically if you are
using your professional laptop or workstation), a safer but less
convenient solution is to use a file in a Windows partition. Go to the
“Using Kubuntu in LiveCD mode with external image” section if you
choose this option.
If you are using Microsoft Windows Vista, then use the disk
management tool provided with your operating system to create
enough free space for Kubuntu. If you are using Microsoft Windows
XP, then make sure if you have enough free space and use the
defragmentation tool provided with your operating system : the
Kubuntu installer will allow you to shrink your Windows partition.

Before
Used Free

Windows Windows
system partition data partition

After

Windows Windows Linux


system partition data partition partition

Running the Kubuntu installation


The Kubuntu CD-ROM provides both a LiveCD mode and an

5 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

installation mode. Insert the CD before powering up your computer,


and make sure your computer properly boots from the CD. After a
while, the KDE environment will show up : the system is running in
LiveCD mode. In order to install Kubuntu on your hard drive, click on
the installation icon available on the desktop.
Follow the installation process steps until the partitioning step. At
that step, select the “Manual” mode which will allow you to access a /dev/hda or /dev/sda represents the
first IDE master disk on your PC. Then
partition editor. Using the partition editor, you can resize your /dev/hda1 is the first primary partition
Windows partition (if using Windows XP) by right-clicking on the of the first IDE master disk.
partition and selecting « Edit partition ». Once enough free space is
created, you will have to create two partitions :
A partition for the system and user data themselves, of around
10 GB, with the ext3 type, and the mount point set to /
A partition for the swap, of around the size of the system memory
(RAM)
Once done, you can proceed to the next step and finalize the
installation. The installation process installed a Grub menu that
allows you to select Kubuntu or Windows at boot time. Start
Kubuntu, and once in Kubuntu, create a /mnt/labs directory as root,
and change the owner to the normal user account you created :
sudo mkdir /mnt/labs/
sudo chown ­R <user>:<user> /mnt/labs/
The root password is the same as your user password : by default,
Kubuntu configure the system so that the user that made the
installation is the administrator.

Using Kubuntu in LiveCD mode with external image


Mount your Windows partition, which must be of type FAT 32, NTFS
<user> is the regular user account:
is not supported (assuming it is in partition n)
- ubuntu if you are using the live CD
mkdir /mnt/windows - the user name that you chose if you
installed Linux on the hard disk.
mount /dev/hdan /mnt/windows
Create two big files (one of 2 GB, the other of 5 GB) and format
them. The first file will be used to store the new programs that we
will install, and your system configuration, while the second file will
be used to store the labs data.
dd if=/dev/zero of=/mnt/windows/casper­rw bs=1M count=2000 If you are running the system from the
mkfs.ext3 ­F /mnt/windows/casper­rw cdrom, never forget to mount
dd if=/dev/zero of=/mnt/windows/labs.img bs=1M count=5000 /mnt/labs each time you need to
restart your machine. Otherwise, you
mkfs.ext3 ­F /mnt/windows/labs.img will quickly fill up the ramdisk in
which /mnt is located, and you will
The first file has to be named casper­rw and be present in the root
also lose your files after reboot.
directory of your FAT 32 partition. The other file can be anywhere in
your FAT 32 partition, and can have another name.
Now, restart the system. At the Kubuntu boot menu, press F6 and
add the “persistent” option to the boot command line. This will tell
Kubuntu to look for a casper­rw file and use it to store newly
installed programs and system configuration. You will have to do that
every time you boot Kubuntu.
Once booted, mount your FAT 32 partition, and your lab data
sudo mkdir /mnt/windows/
sudo mount /dev/hdan /mnt/windows
sudo mount ­o loop /mnt/windows/labs.img /mnt/labs

6
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

You will have to do these steps (adding the persistent boot option
and mounting the labs.img file) at each boot. That's why we
recommend the Kubuntu installation option, which is more
convenient.

Configure the network and repositories


Make sure you can access the network properly. If not, adjust the
network settings using “System Settings” available in the KDE menu.
Then, make sure the Kubuntu package repositories are properly
enabled, by running the Adept package manager (System -> Adept
Manager in the KDE menu) and look in Adept -> Manage
repositories if the Kubuntu software repositories (main, universe,
restricted and multiverse) are all enabled. If not, enable them.
If the Internet access works using a proxy, add the following line to
the /etc/apt/apt.conf file :
Acquire::http::Proxy "http://ProxyServer:Port";

Download lab data


From your regular user, download the lab files from
http://free-electrons.com/labs/embedded_linux.tar.bz2 into the
/mnt/labs directory.
Logged as root, extract the contents of the archive :
cd /mnt/labs root permissions are required to
extract the character and block device
sudo tar jxf embedded_linux.tar.bz2 files contained in the lab structure.
sudo chown ­R <user>:<user> *
exit
You are now ready to start the real practical labs!

More guidelines
Can be useful throughout any of the labs
Read instructions and tips carefully. Lots of people make mistakes
or waste time because they missed an explanation or a guideline.
Always read error messages carefully, in particular the first one
which is issued. Some people stumble on very simple errors just
because they specified a wrong file path and didn't pay enough
attention to the corresponding error message.
If your workstation freezes, tell your instructor. In many cases,
the workstation is still alive and can be fixed without rebooting.
Never stay stuck with a strange problem more than 5 minutes.
Show your problem to your colleagues or to the instructor.

7 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Lab 1 - Kernel sources


Objective: Learn how to get the kernel sources and patch
them. Get familiar with the sources.

After this lab, you will be able to


Get the kernel sources from the official location
Check the authenticity of the kernel sources
Apply kernel patches
Explore the sources in search for files, function headers or other
kinds of information...

Setup
Go to the /mnt/labs/linux/lab1 directory.

Get the sources


Go to the Linux kernel web site (http://www.kernel.org/) and identify Pay attention to the meaning of F, V,
VI, C links on this page
the latest stable version.
Just to make sure you know how to do it, check the version of the For your convenience, you may copy
Linux kernel running on your machine. the source URL from your web browser
and then use wget to download the
We will use linux­2.6.23, which this lab was tested with. sources from the command line:

To practice the patch command later, download the full 2.6.22  wget <url> 
sources. Unpack the archive, which creates a linux­2.6.22  wget <url>.sign
directory. wget can continue interrupted
downloads
Apply patches
Install the patch command, either through the graphical Adept
package manager, or using the following command line :
sudo aptitude install patch
Download the 2 patch files corresponding to the latest 2.6.23 stable
release. Check their authenticity too.
Without uncompressing them (!), apply the 2 patches to the
linux­2.6.22 directory.
Did you know it? gvim can open
View one of the 2 patch files with vi or gvim (if you prefer a graphic compressed files on the fly!
editor), to understand the information carried by such a file. How are Vim supports supports syntax
described added or removed files? highlighting for patch files

Rename the linux­2.6.22 directory to linux­2.6.23.<n>.

Get familiar with the sources


As a Linux kernel user, you will very often need to find which file
implements a given function. So, it is useful to be familiar with
exploring the kernel sources.
1. Find the Linux logo image in the sources You may look for all files with logo in
their name.
2. Find who the maintainer of the 3C505 network driver is.
3. Find the home page of the parallel port team.
4. Find the declaration of the platform_device_register() 

8
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

function.

Use a kernel source indexing tool


Now that you know how to do things in a manual way, let's use more
automated tools.
Of course, if your kernel has a
Try LXR (Linux Cross Reference) at http://lxr.free-electrons.com and significant amount of custom code, or
choose the Linux version closest to yours. if you are not always connected to the
Internet, you can run LXR on your own
As in the previous section, use this tool to find where the computer.
platform_device_register() is declared, implemented and even
used.

9 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Lab 2 – Configuration and compiling


Objective: get familiar with configuring and compiling the
kernel

After this lab, you will be able to


Configure, compile and boot your kernel on a virtual PC.
Mount and modify a root filesystem image by adding entries
to the /dev/ directory.

Setup
Stay in the /mnt/labs/linux/lab1 directory from the previous lab.

Objectives
The goal of this lab is to configure, build and boot a kernel for a
minimalistic, virtual PC, emulated by the qemu emulator
(http://qemu.org)

Makefile tweaks
Add the usage of ccache during compiling, to speed up recompiling,
in case you make multiple configuration changes. You will need to
install the ccache package.

Kernel configuration
Run make xconfig to start the kernel configuration interface. The
kernel configuration interface is provided as source code in the
kernel, make xconfig compiles it automatically, but requires libraries
and headers. You will need to install the libqt3­mt­dev package,
which contains the Qt development files, and the g++ package, the C
++ compiler.
In the interface, toggle the Option   ­>   Show   Name option. This is Also try with make   menuconfig.
useful sometimes, when the parameter name is more explicit than its Though it is not graphical, some people
description, or when you're are following guidelines which give the prefer this interface. As the
menuconfig interface is based on the
parameter name itself. Ncurses library, you will have to install
Also try the Option   ­>   Show   All   Options and Option   ­>   Show  the libncurses­dev package to use it.

Debug   Info options. They let you see all the parameters which
wouldn't appear otherwise, because they depend on the values of
other parameters. By clicking on the description of such a
parameter, you will see its preconditions and understand why it is
not selectable.
Specify a version suffix, so that you can identify your kernel in the
running system by running uname ­r
or cat /proc/version.
Configure your kernel for a minimalistic PC:
We advise you to unselect all options at
Pentium-Pro processor (i686) once, and add only the ones that you
need.
IDE hard disk (not only ATA / IDE support!)
ext2 filesystem
Support for elf binaries

10
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Take your time to have a look at other available features!


Don't hesitate to ask your trainer for more details about a given
option, or when you doubt whether the option should be unselected
or not.

Compile your kernel


Just run: Here, we won't need to run the make 
make install command. If we ran it, the
kernel would be installed for the
workstation PC, while our plans are to
The qemu PC emulator use an emulated PC.

qemu is a fast tool which can emulate several processors (x86, ppc,
arm, sparc, mips...) or even entire systems.
By using an emulator, you won't have to reboot your workstation
over and over again to test your new kernel.
To install qemu on your system, simply install the qemu package.

Booting your kernel


qemu is going to emulate a virtual PC
You are now ready to (try to) boot your new kernel. We will use the with the following features:
data/linux_i386.img file as root filesystem. ­m: specifies its amount of RAM.
­hda: specifies the contents (and size!)
Back to the main lab1 directory, run the run_qemu script (just adjust of the virtual hard disk.
the path to the Linux kernel image): ­boot: specifies its boot device.
­kernel: kernel image to boot. qemu is
qemu ­m 32 ­kernel linux­<ver>/arch/i386/boot/bzImage \ here a bootloader too. Before starting
­append "root=/dev/hda" \ the emulation, it copies the kernel file
­hda data/linux_i386.img ­boot c to the RAM of the virtual PC.
­append: options for the kernel. In
If the kernel doesn't manage to boot, and if the error message is particular, root=/dev/hda instructs
explicit enough, try to guess what is missing in your kernel the kernel to boot on the first IDE hard
disk of the virtual PC.
configuration, and rebuild your kernel. Thanks to the use of ccache,
recompiling may be much faster.
Don't hesitate to show your issue to your trainer.
If you are really stuck, you can try with the rescue config file in the
data/ directory, which your instructor is supposed to have checked.
If everything goes right, you should reach this message:
Warning: unable to open an initial console.
This happens because no console device file is available in the root
filesystem. Without such a file, the shell has no way to interact with
the hardware: reading what you type on the keyboard, and displaying
the output of commands on the screen.
In our case, the device file the shell is trying to user is
/dev/console. All you need is to create it!
Type [Ctrl] C in the terminal running qemu to stop the emulation or
close the qemu window.

Adding a console device to the root filesystem


If you made a full installation of Kubuntu, use the following root permissions are required to create
an entry in /mnt/, as well as to run the
commands in /mnt/labs/linux/lab1 to access the contents of the
mount command
filesystem image :
mkdir fs

11 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

mount ­o loop data/linux_i386.img fs/
Still logged as root, create the dev/console device that is missing. Whatever the architecture Linux runs
You can check the /dev/console device file on your training on, major and minor device numbers
are always the same.
workstation to find out the file type as well as the major and minor
device numbers. If you don't umount a filesystem or do
not use special mount options, you
Once this is done, unmount the root filesystem: can't be sure that your changes have
umount fs already been committed on the
physical media (the .img file in this
Rerun your qemu command. Now, you should reach a command line case).
shell.
To unmount a filesystem, remember
Run a few commands in the virtual PC shell. that you must be outside of the
directory where the filesystem is
mounted. Otherwise umount will fail
Kernel version with Device or resource busy.
Query the version of the running kernel and make sure you find the
version suffix that you specified at configuration time.

Conclusion
Well done! Now you know how to configure, compile and boot a
kernel on a minimalistic PC.

12
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Lab 3 – Cross-compiling
Objective: Learn how to cross-compile a kernel for another
target platform.

After this lab, you will be able to


Set up a cross-compiling environment
Configure the kernel Makefile accordingly
Cross compile the kernel for a virtual target arm platform.
Check that the kernel you compiled can boot the virtual system
and even execute graphical applications.

Setup
Go to the /mnt/labs/linux/lab3 directory.

Target system
We are going to cross-compile and boot a Linux kernel for the ARM q3mu rul3z!
Versatile PB development board, emulated by qemu.

Getting the sources


We are going to need the Linux 2.6.20 sources for this lab.
You can either reuse the sources from the previous lab and apply
patches backwards to 2.6.20. Another possibility is to use the
ketchup tool (http://www.selenic.com/ketchup/).
If you want to use ketchup, first make sure you can download kernel
sources from the command line with wget (follow instructions in
lab1).
Now run:
ketchup ­G 2.6.20

Applying a kernel patch


Apply the kernel patch available in the data/ subdirectory.

Cross-compiling environment setup


To cross-compile Linux, you need to install the cross-compiling
toolchain. To do that, you firs need to add the Free Electrons
package repository by adding the following line to
/etc/apt/sources.list :
deb http://free­electrons.com/labs/ubuntu/ ./
Then you can install the buildroot­uclibc­arm­toolchain 
package, and add the cross-compiling toolchain to your PATH 
environment variable:
export PATH=/usr/local/uclibc­0.9.28­2/arm/bin/:$PATH

Makefile setup
Modify the toplevel Makefile file to cross-compile for the arm 
platform using the above toolchain.

13 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Linux kernel configuration


Pick up the default Linux 2.6 configuration for the Versatile PB board
emulated by qemu.
Don't hesitate to visualize the new settings by running make xconfig 
afterwards!

Cross compiling
Try to compile your kernel. You will soon see whether there are
issues in your setup or not.
If the run was successful, where was the compressed Linux kernel
image created?

Booting your kernel


At last, it's time to boot your virtual system!
First, you need a root filesystem to boot from.
Using the initramfs technique, use the root filesystem in See how simple this is compared to
data/rootfs/, and recompile your kernel. You will have to install the having to create your own filesystem!
gawk package, which contains the gawk utility, required to integrate
the root filesystem as an initramfs inside the kernel.
Now start the emulator with your fresh kernel image:
./run_qemu
If you can reach a command line shell, congratulations!

Running a graphical demo


You can even start a nice graphical demo:
run_demo
Did you see how small the kernel image was
(including the filesystem) ?

14
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Lab 4 – NFS booting and writing modules


Objective: learn how to write and compile a module

After this lab, you will be able to NFS root filesystems are particularly
useful to compile modules on your
Boot an i386 kernel using an NFS root filesystem, which is host, and make them directly visible on
somewhere on your development workstation. the target. You longer have to update
the root filesystem by hand and
Write a kernel module with several capabilities, including module transfer it to the target (requiring a
parameters and a /proc output interface. shutdown and reboot).

Access any kernel internals from your module.


Setup the environment to compile it
Add the sources of your module to the kernel source tree and
build a kernel patch from your new sources.

Lab implementation
You know that code from Linux kernel modules is treated just as any
kernel code, and executed without any control. In particular, any
mistake in module code can corrupt or crash the running kernel.
This is particularly true with modules under development. If you
used your PC workstation to test your new modules, you could face
several critical failures, and waste a significant amount of time
rebooting your system and restoring your development environment
(all the more if you use the live CD which forgets all your settings).
To make your first practice with Linux kernel modules easier, we are
going to use a virtual Linux system again. When your test system
crashes, you will just have to restart the emulator.
There is a practical problem though: how to update the compiled
module files (.ko) on the virtual system, every time they are
recompiled? Copying them each time from the development PC to
the target root filesystem would be tedious: halting the virtual
system, mounting the target root filesystem image, updating the
module file, unmounting and eventually restarting the virtual system.
Fortunately, it is possible to set up networking between the
development workstation and the virtual target. Then, workstation
files can be accessed through the network by the target, using NFS.

Development PC
/work/modules directory

test.ko
Virtual PC (qemu)
NFS
 e xpo /mnt/nfs directory
rt
test.ko
Virtual
network

15 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Setup
Go to the /mnt/labs/linux/lab4 directory. The way you do it is up to you. You can
reuse sources from the previous labs,
Get the sources from the latest 2.6.20.x release and place them in download fresh sources again or
directly use ketchup. Just make sure
the current directory.
the architecture is set to i386.

Kernel configuration
Configure this kernel with the configuration file available in the
data/ subdirectory.
Now add the configuration options that enable booting on a root Other TCP/IP networking configuration
filesystem which sits on an NFS remote directory. settings are already enabled in the
provided configuration file.
Compile your kernel.

Host-target networking
Of course, we will need networking between the host (workstation)
and the target (qemu emulated PC).
To do this, we will add the ­net tap ­net nic options to the qemu 
command line.
When qemu is run with the above options, it creates a userspace
(software) IP tunnel between the virtual machine and the host. On
the host, this corresponds to the tun0 network interface. qemu 
automatically sets its IP address to 172.20.0.1.
In the virtual machine, this corresponds to a regular Ethernet
interface (eth0 if only one interface is created). We will assign the
172.20.0.2 address to it.

NFS booting
Install the NFS server by installing the nfs-kernel-server package.
Once installed, edit the /etc/exports file as root to add the
following lines :
/mnt/labs/linux/lab4/nfsroot 172.20.0.2(rw,no_root_squash,no_subtree_check)
/mnt/labs/linux/lab5/nfsroot 172.20.0.2(rw,no_root_squash,no_subtree_check)
/mnt/labs/linux/lab6/nfsroot 172.20.0.2(rw,no_root_squash,no_subtree_check)

And then, restart the NFS server :


sudo /etc/init.d/nfs­kernel­server restart
Have a look at the run_qemu script available in the lab directory. See
how it instructs the kernel to boot from an NFS exported directory.
Note that this time, Qemu is run as root using sudo, because root
privileges are required to create a TUN/TAP network interface.
Adapt file paths in the run_qemu script according to your exact
kernel version.
Now, try to boot your virtual system:
./run_qemu

Writing a module
Go to the nfsroot/src directory. All the files you generate there will
also be visible from the target. That's great to load modules!
Create a hello_version.c file implementing a module which
displays this kind of message when loaded:

16
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Hello Master. You are currently using Linux <version>. You may just start with a module that


displays a hello message, and add
... and displays a goodbye message when unloaded. version information later.

Caution: you must use a kernel variable or function to get version


Suggestion: you can use kernel sources
information, and not just the value of a C macro. Otherwise, you will from the previous labs to look for files
only get the version of the kernel you used to build the module. which contain version in their name,
and see what they do.
Building your module
Actually, you don't need complete
The current directory contains a Makefile file, which lets you build kernel sources to build a module. A
modules outside a kernel source tree. build directory is enough.

Compile your module.

Testing your module


Load your new module file. Check that it works as expected. Until
this, unload it, modify its code, compile and load it again as many
times as needed.
Run a command to check that your module is on the list of loaded
modules. Now, try to get the list of loaded modules with only the cat 
command.

Adding a parameter to your module


Add a who parameter to your module. Your module will say “Hello
<who>” instead of “Hello Master”.
Compile and test your module by checking that it takes the who 
parameter into account when you load it.

Adding time information


You may search for other drivers in the
Improve your module, so that when you unload it, it tells you how kernel sources using the
do_gettimeofday() function. Looking
many seconds elapsed since you loaded it.
for other examples always helps!
You can use the do_gettimeofday() function to achieve this.

Adding a /proc interface


Add a userland interface to your module by making live elapsed time To get familiar with a function (which
information available in /proc/hello_version_elapsed. may not be documented), it's good to
look for example usages in the kernel
To do this, use the create_proc_info_entry() function. sources. You will find a good example
in drivers/char/toshiba.c

Adding the hello_version sources to the kernel sources


Add your module sources to the drivers/misc/ directory in your
kernel sources. Of course, also modify kernel configuration and
building files accordingly, so that you can select your module in make 
xconfig and have it compiled by the make command.
Configure your kernel with the config file corresponding to your
running kernel. Now check that the configuration interface shows
You may also wait for compiling to be
your new driver and lets you configure it as a module. over and look for a new
hello_version.ko file, but this may
Run the make command and make sure that the code of your new
take much more time.
driver is getting compiled. Once you see this, you can abort
compiling.

17 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Create a kernel patch


You can be proud of your new module! To be able to share it with
others, create a patch which adds your new files to the mainstream
kernel.
Test that your patch file is compatible with the patch command by
applying it to unmodified kernel sources.
Good job!

18
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Lab5 - Simple character drivers


Objective: understanding the basics of managing a /dev entry

After this lab, you will be able to


Write a simple character driver
Have the kernel allocate a free major number for you, and create
a device file accordingly
Write simple file_operations functions for a device, including
ioctl controls.
Use the kmalloc and kfree utilities
Copy data from user memory space to kernel memory space and
vice-versa.
You will practice kernel standard error codes a little bit too.
As in lab4, we will use a virtual PC booted from NFS.

Setup
Go to the /mnt/labs/linux/lab5 directory.
Reuse the run_qemu script from lab4, but adjust paths to continue to
As in the previous lab, look at the lab
use the kernel you built in lab4. directory for files that you can reuse.
Now go to the nfsroot/src directory.
Just like in the previous lab, you have a ready-made Makefile to
compile your module, and a template echo.c module which you will
fill with your own code.

Major number registration


Start the emulator.
Find an available character device major number on your virtual
system.
Modify the echo.c file to register this major number in your new
driver. Compile your module, load it, and check that it effectively
registered the major number you chose.

Simplistic character driver


Now, add code to register a character driver with your major
number, and the empty file operation functions which already exist
in echo.c. Also create the corresponding /dev/echo device file.
Now, fill the read file operation function so that when you read from
your device, you always get a fixed string of your choice. For
example:
> cat /dev/echo
Penguin: Resistance is futile

19 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Write file operation


Fill your write file operation function, and modify the read one, to
set the string that you get when your read /dev/echo. Make sure you
use kernel memory management routines to store the input string in
kernel memory (instead of using a fixed size kernel buffer).
Your device should then behave as follows:
> echo “forget me not” > /dev/echo
> cat /dev/echo
forget me not
> echo “Windows Vista Embedded (just kidding)” > /dev/echo
> cat /dev/echo
Windows Vista Embedded (just kidding)
We suggest you to go to http://lxr.free-electrons.com and look for You don't have to imagine all worst
examples with the functions you need to use! cases (like several simultaneous
writers on the device...). We just need
Also, make sure that you perform basic checks and return to practice the concepts!
appropriate error codes when needed, such as "Out of memory".
Whenever you face kernel oopses,
Going further don't forget that you can use the
eternal techniques of debugging and
When everything works and if you have time, you can implement the display the value of your internal
below improvements in the code: variables or function arguments on the
kernel log file.
Implement a ioctl file_operation function, which makes it
possible to make changes to recorded string, such as turning it
into uppercase or lowercase. To test these features, you may use
the ioctl C executable supplied in your src directory.
Once you have followed the “Concurrent access to resources”
section in the lectures, implement concurrent access
management, to prevent trouble with 2 processes writing to
/dev/echo at the same time, or 1 process reading from the device
while another is writing to it.
Modify your driver to write to video RAM, in a location found in
/proc/iomem.
Good luck!

20
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License
Embedded Linux kernel
and driver development
Training lab book

Lab 6 - Interrupts
Objective: learn how to register and implement a simple
interrupt handler.

During this lab, you will


Make sure you know how to implement a simple interrupt
handler.
Register and unregister this handler for a shared interrupt line on
your GNU/Linux host.
See how Linux handles shared interrupt lines.

Setup
Go to the /mnt/labs/linux/lab6 directory.
As in lab4, we will use a virtual PC booted from NFS.
Reuse the run_qemu script from lab5!
Go to the nfsroot/src directory.

Purpose of this lab


The goal of this lab is just to implement a simple module that Note the number of interrupts is
registers an interrupt handler which keeps track of how many already available
interrupts it receives. through /proc/interrupts. However, our
driver could add more information...
As we have no dedicated hardware to receive interrupts from, we
will register a new handler on a shared interrupt line that already
exists on your virtual PC. Remember that Linux will execute all the
registered handlers handlers on a given interrupt line. So, having an
extra handler will not interfere with the correct execution of the
standard handlers defined on your system.
We suggest you to reuse the Makefile and intr_monitor.c files
provided in the nfsroot/src directory.

/proc interface
Implement and register a /proc/intr_monitor interface for your Don't hesitate to reuse the /proc 
module. At the beginning, just make it display a global variable that interface code you wrote in Lab 4!
will count the number of interrupts intercepted by your driver.
Note that each time an interrupt is
received, the handler could just printk 
Interrupt handler the updated counter value. However, a
/proc interface is a much better
Implement an interrupt handler that just increases the interrupt solution, as the number of interrupts
counter variable. can be huge. Using printk would just
keep the kernel log too busy.
Make sure it returns a correct value though.

Handler registration
In your module init function, register your handler on a shared
interrupt line, which is defined by a irq module parameter.
Make sure that you test that the handler registration was successful!
Otherwise, just make the module init function return a negative
value (suggestion: ­EBUSY), causing module loading to fail.

21 © 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License


Embedded Linux kernel
and driver development
Training lab book

Once module loading is successful, check that /proc/intr_monitor 


works as expected.

Going further
You could improve your driver by:
Making it compute the number of interrupts per second.

22
© 2004-2008 Free Electrons, http://free-electrons.com Creative Commons License

You might also like