diff --git a/LKMPG-3.16.html b/LKMPG-3.16.html index 2a7fb3d..af6819c 100644 --- a/LKMPG-3.16.html +++ b/LKMPG-3.16.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- ++Before you can compile anything you'll need the header files for your current kernel. +
+ +sudo apt-get update
+apt-cache search linux-headers-$(uname -r)
+
++This will tell you what kernel header files are available. Then for example: +
+ +sudo apt-get install linux-headers-3.16.0-4-amd64 ++
Before we delve into code, there are a few issues we need to cover. Everyone's system is different and everyone has their own groove. Getting your first "hello world" program to compile and load correctly can sometimes @@ -575,7 +596,7 @@ for the first time, it will be smooth sailing thereafter.
A module compiled for one kernel won't load if you boot a different kernel unless you enable CONFIG_MODVERSIONS in the kernel. We won't go into module @@ -587,7 +608,7 @@ versioning errors, compile a kernel with modversioning turned off.
It is highly recommended that you type in, compile and load all the examples this guide discusses. It's also highly recommended you do this from a @@ -604,7 +625,7 @@ information, do all your work from the console.
Very often, Linux distros will distribute kernel source that has been patched in various non-standard ways, which may cause trouble. @@ -637,9 +658,9 @@ by using gcc's -I switch.
When the first caveman programmer chiseled the first program on the walls of the first cave computer, it was a program to paint the string `Hello, world' in Antelope pictures. Roman programming textbooks began with the `Salut, Mundi' program. I don't know what happens to people who break with this tradition, but I think it's safer not to find out. We'll start with a series of hello world programs that demonstrate the different aspects of the basics of writing a kernel module.
@@ -649,9 +670,24 @@ Here's the simplest module possible. Don't compile it yet; we'll cover module co+Make a test directory: +
+ +mkdir -p ~/develop/kernel/hello-1
+cd ~/develop/kernel/hello-1
+
++Paste this into you favourite editor and save it as hello-1.c: +
+/*
@@ -678,54 +714,9 @@ Here's the simplest module possible. Don't compile it yet; we'll cover module co
-Kernel modules must have at least two functions: a "start" (initialization) function called init_module() which is called when the module is insmoded into the kernel, and an "end" (cleanup) function called cleanup_module() which is called just before it is rmmoded. Actually, things have changed starting with kernel 2.3.13. You can now use whatever name you like for the -start and end functions of a module, and you'll learn how to do this in Section 2.3. In fact, the new method is the preferred method. However, many people still use init_module() and cleanup_module() for their start and end functions. +Now you'll need a Makefile. If you copy and paste this change the indentation to use tabs, not spaces.
--Typically, init_module() either registers a handler for something with the kernel, or it replaces one of the kernel functions with its own code (usually code to do something and then call the original function). The cleanup_module() function is supposed to undo whatever init_module() did, so the module can be unloaded safely. -
- --Lastly, every kernel module needs to include linux/module.h. We needed to include linux/kernel.h only for the macro expansion for the printk() log level, KERN_ALERT, which you'll learn about in Section 2.1.1. -
--Despite what you might think, printk() was not meant to communicate -information to the user, even though we used it for exactly this purpose in hello-1! It happens to be a logging mechanism for the kernel, and is used to log information or give warnings. Therefore, each printk() statement comes with a priority, which is the <1> and KERN_ALERT you see. There are 8 priorities and the kernel has macros for them, so you don't have to use cryptic numbers, and you can view them (and their meanings) in linux/kernel.h. If you don't specify a priority level, the default priority, DEFAULT_MESSAGE_LOGLEVEL, will be used. -
- --Take time to read through the priority macros. The header file also describes what each priority means. In practise, don't use number, like <4>. Always use the macro, like KERN_WARNING. -
- --If the priority is less than int console_loglevel, the message is printed on your current terminal. If both syslogd and klogd are running, then the message will also get appended to /var/log/messages, whether it got printed to the console or not. We use a high priority, like KERN_ALERT, to make sure the printk() messages get printed to your console rather than just logged to your logfile. When you write real modules, you'll want to use priorities that are meaningful for the situation at hand. -
--Kernel modules need to be compiled a bit differently from regular userspace apps. Former kernel versions required us to care much about these settings, which are usually stored in Makefiles. Although hierarchically organized, many redundant settings accumulated in sublevel Makefiles and made them large and rather difficult to maintain. Fortunately, there is a new way of doing these things, called kbuild, and the build process for external loadable modules is now fully integrated into the standard kernel build mechanism. To learn more on how to compile modules which are not part of the official kernel (such as all the examples you'll find in this guide), see file linux/ Documentation/kbuild/modules.txt. -
- --So, let's look at a simple Makefile for compiling a module named hello-1.c: -
-obj-m += hello-1.o
@@ -739,95 +730,130 @@ So, let's look at a simple Makefile for compiling a module named hello-1.c:
-From a technical point of view just the first line is really necessary, the "all" and "clean" targets were added for pure convenience. -
- --Now you can compile the module by issuing the command make . You should obtain an output which resembles the following: -
- - -hostname:~/lkmpg-examples/02-HelloWorld# make -make -C /lib/modules/2.6.11/build M=/root/lkmpg-examples/02-HelloWorld modules -make[1]: Entering directory `/usr/src/linux-2.6.11' - CC [M] /root/lkmpg-examples/02-HelloWorld/hello-1.o - Building modules, stage 2. - MODPOST - CC /root/lkmpg-examples/02-HelloWorld/hello-1.mod.o - LD [M] /root/lkmpg-examples/02-HelloWorld/hello-1.ko -make[1]: Leaving directory `/usr/src/linux-2.6.11' -hostname:~/lkmpg-examples/02-HelloWorld# --
-Note that kernel 2.6 introduces a new file naming convention: kernel modules now have a .ko extension (in place of the old .o extension) which easily distinguishes them from conventional object files. The reason for this is that they contain an additional .modinfo section that where additional information about the module is kept. We'll soon see what this information is good for. -
- --Use modinfo hello-*.ko to see what kind of information it is. +And finally just:
hostname:~/lkmpg-examples/02-HelloWorld# modinfo hello-1.ko -filename: hello-1.ko -vermagic: 2.6.11 preempt PENTIUMII 4KSTACKS gcc-3.3 -depends: +make
-Nothing spectacular, so far. That changes once we're using modinfo on one of our the later examples, hello-5.ko . +If all goes smoothly you should then find that you have a compiled hello-1.ko module. You can find info on it with the command:
hostname:~/lkmpg-examples/02-HelloWorld# modinfo hello-5.ko -filename: hello-5.ko -license: GPL -author: Peter Jay Salzman -vermagic: 2.6.11 preempt PENTIUMII 4KSTACKS gcc-3.3 -depends: -parm: myintArray:An array of integers (array of int) -parm: mystring:A character string (charp) -parm: mylong:A long integer (long) -parm: myint:An integer (int) -parm: myshort:A short integer (short) -hostname:~/lkmpg-examples/02-HelloWorld# +sudo modinfo hello-1.ko
-Lot's of useful information to see here. An author string for bugreports, license information, even a short description of the parameters it accepts. +At this point the command: +
+ +sudo lsmod | grep hello ++
+should return nothing. You can try loading your shiny new module with: +
+ +sudo insmod hello-1.ko ++
+The dash character will get converted to an underscore, so when you again try: +
+ +sudo lsmod | grep hello ++
+you should now see your loaded module. It can be removed again with: +
+ +sudo rmmod hello_1 ++
+To see what just happened in the logs: +
+ +sudo tail /var/log/messages | grep kernel ++
+You now know the basics of creating, compiling, installing and removing modules. Now for more of a description of how this module works.
-Additional details about Makefiles for kernel modules are available in linux/Documentation/kbuild/makefiles.txt. Be sure to read this and the related files before starting to hack Makefiles. It'll probably save you lots of work. +Kernel modules must have at least two functions: a "start" (initialization) function called init_module() which is called when the module is insmoded into the kernel, and an "end" (cleanup) function called cleanup_module() which is called just before it is rmmoded. Actually, things have changed starting with kernel 2.3.13. You can now use whatever name you like for the +start and end functions of a module, and you'll learn how to do this in Section 2.3. In fact, the new method is the preferred method. However, many people still use init_module() and cleanup_module() for their start and end functions.
-Now it is time to insert your freshly-compiled module it into the kernel with insmod ./hello-1.ko (ignore anything you see about tainted kernels; we'll cover that shortly). +Typically, init_module() either registers a handler for something with the kernel, or it replaces one of the kernel functions with its own code (usually code to do something and then call the original function). The cleanup_module() function is supposed to undo whatever init_module() did, so the module can be unloaded safely.
-All modules loaded into the kernel are listed in /proc/modules. Go ahead and cat that file to see that your module is really a part of the kernel. Congratulations, you are now the author of Linux kernel code! When the novelty wears off, remove your module from the kernel by using rmmod hello-1. Take a look at /var/log/messages just to see that it got logged to your system logfile. +Lastly, every kernel module needs to include linux/module.h. We needed to include linux/kernel.h only for the macro expansion for the printk() log level, KERN_ALERT, which you'll learn about in Section 2.1.1. +
++Despite what you might think, printk() was not meant to communicate information to the user, even though we used it for exactly this purpose in hello-1! It happens to be a logging mechanism for the kernel, and is used to log information or give warnings. Therefore, each printk() statement comes with a priority, which is the <1> and KERN_ALERT you see. There are 8 priorities and the kernel has macros for them, so you don't have to use cryptic numbers, and you can view them (and their meanings) in linux/kernel.h. If you don't specify a priority level, the default priority, DEFAULT_MESSAGE_LOGLEVEL, will be used.
++Take time to read through the priority macros. The header file also describes what each priority means. In practise, don't use number, like <4>. Always use the macro, like KERN_WARNING. +
+ ++If the priority is less than int console_loglevel, the message is printed on your current terminal. If both syslogd and klogd are running, then the message will also get appended to /var/log/messages, whether it got printed to the console or not. We use a high priority, like KERN_ALERT, to make sure the printk() messages get printed to your console rather than just logged to your logfile. When you write real modules, you'll want to use priorities that are meaningful for the situation at hand. +
++Kernel modules need to be compiled a bit differently from regular userspace apps. Former kernel versions required us to care much about these settings, which are usually stored in Makefiles. Although hierarchically organized, many redundant settings accumulated in sublevel Makefiles and made them large and rather difficult to maintain. Fortunately, there is a new way of doing these things, called kbuild, and the build process for external loadable modules is now fully integrated into the standard kernel build mechanism. To learn more on how to compile modules which are not part of the official kernel (such as all the examples you'll find in this guide), see file linux/Documentation/kbuild/modules.txt. +
+ ++Additional details about Makefiles for kernel modules are available in linux/Documentation/kbuild/makefiles.txt. Be sure to read this and the related files before starting to hack Makefiles. It'll probably save you lots of work. +
+ +Here's another exercise for the reader. See that comment above the return statement in init_module()? Change the return value to something negative, recompile and load the module again. What happens?
-
-As of Linux 2.4, you can rename the init and cleanup functions of your modules; they no longer have to be called init_module() and cleanup_module() respectively. This is done with the module_init() and module_exit() macros. These macros are defined in linux/init.h. The only caveat is that your init and cleanup functions must be defined before calling the macros, otherwise you'll get compilation errors. Here's an example of this technique: +As of Linux 2.4, you can rename the init and cleanup functions of your modules; they no longer have to be called init_module() and cleanup_module() respectively. This is done with the module_init() and module_exit() macros. These macros are defined in linux/init.h. The only caveat is that your init and cleanup functions must be defined before calling the macros, otherwise you'll get compilation errors. Here's an example of this technique:
-This demonstrates a feature of kernel 2.2 and later. Notice the change in the definitions of the init and cleanup functions. The __init macro causes the init function to be discarded and its memory freed once the init function finishes for built-in drivers, but not loadable modules. If you think about when the init function is invoked, this makes perfect sense. +This demonstrates a feature of kernel 2.2 and later. Notice the change in the definitions of the init and cleanup functions. The __init macro causes the init function to be discarded and its memory freed once the init function finishes for built-in drivers, but not loadable modules. If you think about when the init function is invoked, this makes perfect sense.
-There is also an __initdata which works similarly to __init but for init variables rather than functions. +There is also an __initdata which works similarly to __init but for init variables rather than functions.
-The __exit macro causes the omission of the function when the module is built into the kernel, and like __exit, has no effect for loadable modules. Again, if you consider when the cleanup function runs, this makes complete sense; built-in drivers don't need a cleanup function, while loadable modules do. +The __exit macro causes the omission of the function when the module is built into the kernel, and like __exit, has no effect for loadable modules. Again, if you consider when the cleanup function runs, this makes complete sense; built-in drivers don't need a cleanup function, while loadable modules do.
-These macros are defined in linux/init.h and serve to free up kernel memory. When you boot your kernel and see something like Freeing unused kernel memory: 236k freed, this is precisely what the kernel is freeing. +These macros are defined in linux/init.h and serve to free up kernel memory. When you boot your kernel and see something like Freeing unused kernel memory: 236k freed, this is precisely what the kernel is freeing.