There was a big book with plain red leather covers; its tall pages were now almost filled. At the beginning there were many leaves covered with Bilbo's thin wandering hand; but most of it was written in Frodo's firm flowing script. It was divided into chapters but Chapter 80 was unfinished, and after that were some blank leaves.
"Why, you have nearly finished it, Mr. Frodo!" Sam exclaimed. "Well, you have kept at it, I must say."
"I have quite finished, Sam," said Frodo. "The last pages are for you."
—The Return of the King, Book VI, Chapter 9
In this studio, you will:
Please complete the required exercises below, as well as any optional enrichment exercises that you wish to complete.
As you work through these exercises, please record your answers, and when finished email your results to email@example.com with the phrase Loadable Kernel Modules in the subject line.
Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.
linux_sourcedirectory (which contains the
linuxdirectory in which you've built the kernel), create a new directory to hold your kernel modules, and
cdinto it. Save a copy of
simple_module.c(a simple template for writing kernel modules in this course, based on the "Hello, World!" module shown on pages 338 and 339 of Robert Love's Linux Kernel Development, Third Edition) into that directory. In that directory also create a Makefile that contains the line
obj-m := simple_module.o
module add raspberry
set KERNEL=kernel7if that's what your shell requires) and then
make -C ../linux/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- SUBDIRS=$PWD modules
linuxdirectory that holds the Linux code - if not, instead replace
../linux/with the path to the location of your
linuxdirectory). If that command is successful, it should produce a file named
simple_module.ko, in the current directory.
As the answer to this exercise, show the output that was produced by
sftpto get the
simple_module.kofile you produced in the previous exercise.
First, clear out the contents of the system log using the command
sudo dmesg --clear
and then use the
insmod utility to load your kernel module into the
kernel, as in:
sudo insmod simple_module.ko
If you recieved no error messages, then your module has been successfully loaded. To confirm this, you can check the system log by issuing the command
which prints out the system log, which now should show the message that was printed when the module loaded. As the answer to this exercise, please show the message that appears in the system log.
rmmod. When using this tool you can either specify the module name (as shown in
lsmod) or you can specify a
.kofile, as in
sudo rmmod simple_module.ko
Remove your module now, and verify its removal as before. As the answer to
this exercise, copy the output of
lsmod and the line of the system log,
which show that the module was unloaded.
One kernel variable we've talked about previously is the
counter. Recall that this variable keeps track of how many timer interrupts
(also called ticks) have occured since system boot.
simple_module.c to a new file called
and modify that new file, so that the system log messages that are generated when the module
is loaded and unloaded also give the value of the
(hint: it's an
unsigned long) to the system log. Note that although this
jiffies variable is not readily available to userspace programs, it is available directly when in kernelspace.
Makefile, build your new kernel module and use
sftp to copy the
jiffies_module.ko file that was
produced for it, over to your Raspberry Pi.
On your Raspberry Pi, load and unload your new kernel module, and as the
answer to this exercise please copy and paste the system log message that shows
the values of the
jiffies variable when your module was loaded and
when it was unloaded, and say how many ticks occurred between those messages.
In addition to the answers for the exercises above (and any of the optional enrichment exercises below that you may have completed), please submit:
jiffies_module.cfile for the new kernel module you created.
/include/uapi/asm-gerneic/errno-base.h. Modify your init function to return positive and negative values, respectively. As the answer to this exercise please describe briefly what happens when you load the module, and what you see in the system logs because of that.
EXPORT_SYMBOLmacro. You can see a list of all kernel symbols by looking at the file /proc/kallsyms, e.g.
cat /proc/kallsyms. You might notice that this is very similar to the symbol table of a traditional application. (Which you can print with the program
nm, if you've never done that before. Try it on any binary!) In fact, their syntax is identical, so you can use
man nmto find some more information about how to decode the contents of
Symbols that have been exported can be found in this list with the prefixes
__ksymtab_. These prefixes denote
a special kernel symbol that stores the name of the exported symbol and a
struct that stores information about the symbol, respectively. See the
EXPORT_SYMBOL to see how these are generated.
As the answer to this exercise, please list a few of those symbols that
are available for use in a kernel module.
insmodutility has been superceeded by another program called
modprobe, which in general should be used because it performs dependency resolution between modules. We use
rmmodhere simply to demonstrate the low-level utilities that actually perform module loading and unloading.
On your Raspberry Pi, run the command
to study the
modprobe utility, and then use that utility to
load and unload your modules from the required exercises. As the answer
to this exercise, please describe what you observed, including any differences
compared to what you saw when you used