embedded linux kernel and driver development - lab book

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

Upload: others

Post on 12-Sep-2021

31 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Embedded Linux kernel and driver development - Lab book

Embedded Linux kerneland driver development

Training lab book

Embedded Linux kernel and driver developmentTraining lab book

Free Electronshttp://free-electrons.com

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

Page 2: Embedded Linux kernel and driver development - Lab book

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

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 foundon 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 translationsavailable on http://free-electrons.com/training/drivers.

Corrections, suggestions, contributions and translations are welcome!

3

Embedded Linux kerneland driver development

Training lab book

Page 3: Embedded Linux kernel and driver development - Lab book

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

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

Embedded Linux kerneland driver development

Training lab book

Page 4: Embedded Linux kernel and driver development - Lab book

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

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.

Running the Kubuntu installation

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

5

Embedded Linux kerneland driver development

Training lab book

Free

Windowssystem partition

Windowsdata partition

Used

Before

Windowssystem partition

Windowsdata partition

After

Linuxpartition

Page 5: Embedded Linux kernel and driver development - Lab book

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

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 partition editor. Using the partition editor, you can resize your Windows partition (if using Windows XP) by right-clicking on the 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 is not supported (assuming it is in partition n)

mkdir /mnt/windowsmount /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=2000mkfs.ext3 ­F /mnt/windows/casper­rwdd if=/dev/zero of=/mnt/windows/labs.img bs=1M count=5000mkfs.ext3 ­F /mnt/windows/labs.img

The first file has to be named casper­rw and be present in the root 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/windowssudo mount ­o loop /mnt/windows/labs.img /mnt/labs

6

Embedded Linux kerneland driver development

Training lab book

/dev/hda or /dev/sda represents the first IDE master disk on your PC. Then /dev/hda1 is the first primary partition of the first IDE master disk.

If you are running the system from the cdrom, never forget to mount /mnt/labs each time you need to restart your machine. Otherwise, you will quickly fill up the ramdisk in which /mnt is located, and you will also lose your files after reboot.

<user> is the regular user account:- ubuntu if you are using the live CD- the user name that you chose if you installed Linux on the hard disk.

Page 6: Embedded Linux kernel and driver development - Lab book

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

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 fromhttp://free-electrons.com/labs/embedded_linux.tar.bz2 into the /mnt/labs directory.

Logged as root, extract the contents of the archive :cd /mnt/labssudo tar jxf embedded_linux.tar.bz2sudo 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

Embedded Linux kerneland driver development

Training lab book

root permissions are required to extract the character and block device files contained in the lab structure.

Page 7: Embedded Linux kernel and driver development - Lab book

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

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 the latest stable version.

Just to make sure you know how to do it, check the version of the Linux kernel running on your machine.

We will use linux­2.6.23, which this lab was tested with.

To practice the patch command later, download the full 2.6.22 sources. Unpack the archive, which creates a linux­2.6.22 directory.

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.

View one of the 2 patch files with vi or gvim (if you prefer a graphic editor), to understand the information carried by such a file. How are described added or removed 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

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

Embedded Linux kerneland driver development

Training lab book

Pay attention to the meaning of F, V, VI, C links on this page

For your convenience, you may copy the source URL from your web browser and then use wget to download the sources from the command line:

wget <url> wget <url>.sign

wget can continue interrupted downloads

Vim supports supports syntax highlighting for patch files

Did you know it? gvim can open compressed files on the fly!

You may look for all files with logo in their name.

Page 8: Embedded Linux kernel and driver development - Lab book

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

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.

Try LXR (Linux Cross Reference) at http://lxr.free-electrons.com and choose the Linux version closest to yours.

As in the previous section, use this tool to find where the platform_device_register() is declared, implemented and even used.

9

Embedded Linux kerneland driver development

Training lab book

Of course, if your kernel has a significant amount of custom code, or if you are not always connected to the Internet, you can run LXR on your own computer.

Page 9: Embedded Linux kernel and driver development - Lab book

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

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 entriesto 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 useful sometimes, when the parameter name is more explicit than its description, or when you're are following guidelines which give the parameter name itself.

Also try the Option ­> Show All Options and Option ­> Show 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 ­ror cat /proc/version.

Configure your kernel for a minimalistic PC:

Pentium-Pro processor (i686)

IDE hard disk (not only ATA / IDE support!)

ext2 filesystem

Support for elf binaries

10

Embedded Linux kerneland driver development

Training lab book

Also try with make   menuconfig. Though it is not graphical, some people prefer this interface. As the menuconfig interface is based on the Ncurses library, you will have to install the libncurses­dev package to use it.

We advise you to unselect all options at once, and add only the ones that you need.

Page 10: Embedded Linux kernel and driver development - Lab book

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

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:

make

The qemu PC emulator

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

You are now ready to (try to) boot your new kernel. We will use the data/linux_i386.img file as root filesystem.

Back to the main lab1 directory, run the run_qemu script (just adjust the path to the Linux kernel image):

qemu ­m 32 ­kernel linux­<ver>/arch/i386/boot/bzImage \­append "root=/dev/hda" \­hda data/linux_i386.img ­boot c

If the kernel doesn't manage to boot, and if the error message is explicit enough, try to guess what is missing in your kernel 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 commands in /mnt/labs/linux/lab1 to access the contents of the filesystem image :

mkdir fs

11

Embedded Linux kerneland driver development

Training lab book

root permissions are required to create an entry in /mnt/, as well as to run the mount command

qemu is going to emulate a virtual PC with the following features:­m: specifies its amount of RAM.­hda: specifies the contents (and size!) of the virtual hard disk.­boot: specifies its boot device.­kernel: kernel image to boot. qemu is here a bootloader too. Before starting the emulation, it copies the kernel file to the RAM of the virtual PC.­append: options for the kernel. In particular, root=/dev/hda instructs the kernel to boot on the first IDE hard disk of the virtual PC.

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

Page 11: Embedded Linux kernel and driver development - Lab book

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

mount ­o loop data/linux_i386.img fs/

Still logged as root, create the dev/console device that is missing. You can check the /dev/console device file on your training workstation to find out the file type as well as the major and minor device numbers.

Once this is done, unmount the root filesystem:umount fs

Rerun your qemu command. Now, you should reach a command line shell.

Run a few commands in the virtual PC shell.

Kernel version

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

Embedded Linux kerneland driver development

Training lab book

Whatever the architecture Linux runs on, major and minor device numbers are always the same.

To unmount a filesystem, remember that you must be outside of the directory where the filesystem is mounted. Otherwise umount will fail with Device or resource busy.

If you don't umount a filesystem or do not use special mount options, you can't be sure that your changes have already been committed on the physical media (the .img file in this case).

Page 12: Embedded Linux kernel and driver development - Lab book

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

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 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

Embedded Linux kerneland driver development

Training lab book

q3mu rul3z!

Page 13: Embedded Linux kernel and driver development - Lab book

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

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 data/rootfs/, and recompile your kernel. You will have to install the 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

Embedded Linux kerneland driver development

Training lab book

See how simple this is compared to having to create your own filesystem!

Page 14: Embedded Linux kernel and driver development - Lab book

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

Lab 4 – NFS booting and writing modules

Objective: learn how to write and compile a module

After this lab, you will be able to

Boot an i386 kernel using an NFS root filesystem, which is somewhere on your development workstation.

Write a kernel module with several capabilities, including module parameters and a /proc output interface.

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.

15

Embedded Linux kerneland driver development

Training lab book

NFS root filesystems are particularly useful to compile modules on your host, and make them directly visible on the target. You longer have to update the root filesystem by hand and transfer it to the target (requiring a shutdown and reboot).

Development PC

Virtual PC (qemu)

/mnt/nfs directory

/work/modules directory

test.ko

test.koVirtual

network

NFS export

Page 15: Embedded Linux kernel and driver development - Lab book

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

Setup

Go to the /mnt/labs/linux/lab4 directory.

Get the sources from the latest 2.6.20.x release and place them in the current directory.

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 filesystem which sits on an NFS remote directory.

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

Embedded Linux kerneland driver development

Training lab book

The way you do it is up to you. You can reuse sources from the previous labs, download fresh sources again or directly use ketchup. Just make sure the architecture is set to i386.

Other TCP/IP networking configuration settings are already enabled in the provided configuration file.

Page 16: Embedded Linux kernel and driver development - Lab book

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

Hello Master. You are currently using Linux <version>.

... and displays a goodbye message when unloaded.

Caution: you must use a kernel variable or function to get version information, and not just the value of a C macro. Otherwise, you will only get the version of the kernel you used to build the module.

Building your module

The current directory contains a Makefile file, which lets you build modules outside a kernel source tree.

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

Improve your module, so that when you unload it, it tells you how many seconds elapsed since you loaded it.

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 information available in /proc/hello_version_elapsed.

To do this, use the create_proc_info_entry() function.

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 your new driver and lets you configure it as a module.

Run the make command and make sure that the code of your new driver is getting compiled. Once you see this, you can abort compiling.

17

Embedded Linux kerneland driver development

Training lab book

You may just start with a module that displays a hello message, and add version information later.

Suggestion: you can use kernel sources from the previous labs to look for files which contain version in their name, and see what they do.

Actually, you don't need complete kernel sources to build a module. A build directory is enough.

You may also wait for compiling to be over and look for a new hello_version.ko file, but this may take much more time.

To get familiar with a function (which may not be documented), it's good to look for example usages in the kernel sources. You will find a good example in drivers/char/toshiba.c

You may search for other drivers in the kernel sources using the do_gettimeofday() function. Looking for other examples always helps!

Page 17: Embedded Linux kernel and driver development - Lab book

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

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

Embedded Linux kerneland driver development

Training lab book

Page 18: Embedded Linux kernel and driver development - Lab book

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

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 use the kernel you built in lab4.

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/echoPenguin: Resistance is futile

19

Embedded Linux kerneland driver development

Training lab book

As in the previous lab, look at the lab directory for files that you can reuse.

Page 19: Embedded Linux kernel and driver development - Lab book

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

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/echoforget me not> echo “Windows Vista Embedded (just kidding)” > /dev/echo> cat /dev/echoWindows Vista Embedded (just kidding)

We suggest you to go to http://lxr.free-electrons.com and look for examples with the functions you need to use!

Also, make sure that you perform basic checks and return appropriate error codes when needed, such as "Out of memory".

Going further

When everything works and if you have time, you can implement the below improvements in the code:

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

Embedded Linux kerneland driver development

Training lab book

You don't have to imagine all worst cases (like several simultaneous writers on the device...). We just need to practice the concepts!

Whenever you face kernel oopses, don't forget that you can use the eternal techniques of debugging and display the value of your internal variables or function arguments on the kernel log file.

Page 20: Embedded Linux kernel and driver development - Lab book

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

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 registers an interrupt handler which keeps track of how many interrupts it receives.

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 module. At the beginning, just make it display a global variable that will count the number of interrupts intercepted by your driver.

Interrupt handler

Implement an interrupt handler that just increases the interrupt counter variable.

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

Embedded Linux kerneland driver development

Training lab book

Note the number of interrupts is already available through /proc/interrupts. However, our driver could add more information...

Don't hesitate to reuse the /proc interface code you wrote in Lab 4!

Note that each time an interrupt is received, the handler could just printk the updated counter value. However, a /proc interface is a much better solution, as the number of interrupts can be huge. Using printk would just keep the kernel log too busy.

Page 21: Embedded Linux kernel and driver development - Lab book

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

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

Embedded Linux kerneland driver development

Training lab book