diff --git a/LKMPG-3.16.html b/LKMPG-3.16.html index 4b19538..2a7fb3d 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">
- +mkdir -p ~/develop/kernel +cd ~/develop/kernel +sudo apt-get -y install fakeroot build-essential devscripts +sudo apt-get -y build-dep linux +apt-get -y source linux +cd linux-* +make -f debian/rules clean +make menuconfig ++
+Select save, enter the name .config then exit. The to build the kernel. +
+ +fakeroot make ++
So, you want to write a kernel module. You know C, you've written a few normal programs to run as processes, and now you want to get to where the real action is, to where a single wild pointer can wipe out your file system and a core dump means a reboot.
@@ -418,25 +449,74 @@ What exactly is a kernel module? Modules are pieces of code that can be loaded a-You can see what modules are already loaded into the kernel by running lsmod, which gets its information by reading the file /proc/modules. +Linux distros provide the commands modprobe, insmod and depmod within a package.
-How do these modules find their way into the kernel? When the kernel needs a feature that is not resident in the kernel, the kernel module daemon kmod[1] execs modprobe to load the module in. modprobe is passed a string in one of two forms: +On Debian: +
+ +sudo apt-get install kmod ++
+To discover what modules are already loaded within your current kernel use the command lsmod. +
+ +sudo lsmod ++
+Modules are stored within the file /proc/modules, so you can also see them with: +
+ +sudo cat /proc/modules ++
+This can be a long list, and you might prefer to search for something particular. To search for the fat module: +
+ +sudo lsmod | grep fat ++
+When the kernel needs a feature that is not currently resident in the kernel, the kernel module daemon kmod[1] runs the modprobe command to load it. modprobe is passed a string in one of two forms:
-If modprobe is handed a generic identifier, it first looks for that string in the file /etc/modprobe.conf.[2] If it finds an alias line like: +If modprobe is handed a generic identifier, it first looks for that string in the file /etc/modprobe.conf.[2] If it finds an alias line like:
-it knows that the generic identifier refers to the module softdog.ko. +it knows that the generic identifier refers to the module softdog.ko.
-Next, modprobe looks through the file /lib/modules/version/modules.dep, to see if other modules must be loaded before the requested module may be loaded. This file is created by depmod -a and contains module dependencies. For example, msdos.ko requires the fat.ko module to be already loaded into the kernel. The requested module has a dependency on another module if the other module defines symbols (variables or functions) that the requested module uses. +Next, modprobe looks through the file /lib/modules/version/modules.dep, to see if other modules must be loaded before the requested module may be loaded. This file is created by depmod -a and contains module dependencies. For example, msdos.ko requires the fat.ko module to be already loaded into the kernel. The requested module has a dependency on another module if the other module defines symbols (variables or functions) that the requested module uses.
-Lastly, modprobe uses insmod to first load any prerequisite modules into the kernel, and then the requested module. modprobe directs insmod to lib -modules/version/[3], the standard directory for modules. insmod is intended -to be fairly dumb about the location of modules, whereas modprobe is aware of the default location of modules, knows how to figure out the dependencies and load the modules in the right order. So for example, if you wanted to load the msdos module, you'd have to either run: +Lastly, modprobe uses insmod to first load any prerequisite modules into the kernel, and then the requested module. modprobe directs insmod to lib/modules/version[3], the standard directory for modules. insmod is intended to be fairly dumb about the location of modules, whereas modprobe is aware of the default location of modules, knows how to figure out the dependencies and load the modules in the right order. So for example, if you wanted to load the msdos module, you'd have to either run:
insmod /lib/modules/2.6.11/kernel/fs/fat/fat.ko -insmod /lib/modules/2.6.11/kernel/fs/msdos/msdos.ko +sudo insmod /lib/modules/3.16.0-4-amd64/kernel/fs/fat/fat.ko +sudo insmod /lib/modules/3.16.0-4-amd64/kernel/fs/msdos/msdos.ko
modprobe msdos +sudo modprobe msdos
-What we've seen here is: insmod requires you to pass it the full pathname and to insert the modules in the right order, while modprobe just takes the name, without any extension, and figures out all it needs to know by parsing /lib/modules/version/modules.dep. -
- --Linux distros provide modprobe, insmod and depmod as a package called module-init-tools. In previous versions that package was called modutils. Some distros also set up some wrappers that allow both packages to be installed in parallel and do the right thing in order to be able to deal with 2.4 and 2.6 kernels. Users should not need to care about the details, as long as they're running recent versions of those tools. +What we've seen here is: insmod requires you to pass it the full pathname and to insert the modules in the right order, while modprobe just takes the name, without any extension, and figures out all it needs to know by parsing /lib/modules/version/modules.dep.
@@ -489,9 +563,9 @@ Now you know how modules get into the kernel. There's a bit more to the story if
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 @@ -501,7 +575,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 @@ -513,7 +587,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 @@ -530,7 +604,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. @@ -560,12 +634,12 @@ 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.
@@ -575,9 +649,9 @@ Here's the simplest module possible. Don't compile it yet; we'll cover module co/*
@@ -619,9 +693,9 @@ Lastly, every kernel module needs to include linux/module.h. We needed to includ
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. @@ -637,9 +711,9 @@ If the priority is less than int console_loglevel, the message is printed on you
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.
@@ -649,9 +723,9 @@ So, let's look at a simple Makefile for compiling a module named hello-1.c:obj-m += hello-1.o
@@ -749,17 +823,17 @@ Here's another exercise for the reader. See that comment above the return statem
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:
/*
@@ -792,9 +866,9 @@ So now we have two real kernel modules under our belt. Adding another module is
obj-m += hello-1.o
@@ -816,9 +890,9 @@ you can see, some things get hardwired into the kernel (obj-y) but where are all
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.
@@ -836,9 +910,9 @@ These macros are defined in linux/init.h and serve to free up kernel memory. Whe/*
@@ -869,9 +943,9 @@ module_exit(hello_3_exit);
If you're running kernel 2.4 or later, you might have noticed something like this when you loaded proprietary modules:
@@ -940,9 +1014,9 @@ Users of traditional Unix editors, like emacs or vi will also find tag files use/* @@ -995,9 +1069,9 @@ MODULE_SUPPORTED_DEVICE("testdevice");
Modules can take command line arguments, but not with the argc/argv you might be used to.
@@ -1042,9 +1116,9 @@ Lastly, there's a macro function, MODULE_PARM_DESC(), that is used to document a/* @@ -1157,9 +1231,9 @@ hello-5.o: invalid argument syntax for mylong: 'h'
Sometimes it makes sense to divide a kernel module between several source files.
@@ -1169,9 +1243,9 @@ Here's an example of such a kernel module./*
@@ -1196,9 +1270,9 @@ The next file:
/*
@@ -1222,9 +1296,9 @@ And finally, the makefile:
obj-m += hello-1.o
@@ -1253,9 +1327,9 @@ make what object files are part of that module.
Obviously, we strongly suggest you to recompile your kernel, so that you can enable a number of useful debugging features, such as forced module unloading (MODULE_FORCE_UNLOAD): when this option is enabled, you can force the kernel to unload a module even when it believes it is unsafe, via a rmmod -f module command. This option can save you a lot of time and a number of reboots during the development of a module.
@@ -1352,12 +1426,12 @@ If you do not desire to actually compile the kernel, you can interrupt the buildA program usually begins with a main() function, executes a bunch of instructions and terminates upon completion of those instructions. Kernel modules work a bit differently. A module always begin with either the init_module or the function you specify with module_init call. This is the entry function for modules; it tells the kernel what functionality the module provides and sets up the kernel to run the module's functions when they're needed. Once it does this, entry function returns and the module does nothing until the kernel wants to do something with the code that the module provides.
@@ -1372,9 +1446,9 @@ Every module must have an entry function and an exit function. Since there's morProgrammers use functions they don't define all the time. A prime example of this is printf(). You use these library functions which are provided by the standard C library, libc. The definitions for these functions don't actually enter your program until the linking stage, which insures that the code (for printf() for example) is available, and fixes the call instruction to point to that code.
@@ -1409,9 +1483,9 @@ You can even write modules to replace the kernel's system calls, which we'll doA kernel is all about access to resources, whether the resource in question happens to be a video card, a hard drive or even memory. Programs often compete for the same resource. As I just saved this document, updatedb started updating the locate database. My vim session and updatedb are both using the hard drive concurrently. The kernel needs to keep things orderly, and not give users access to resources whenever they feel like it. To this end, a CPU can run in different modes. Each mode gives a different level of freedom to do what you want on the system. The Intel 80386 architecture has 4 of these modes, which are called rings. Unix uses only two rings; the highest ring (ring 0, also known as `supervisor mode' where everything is allowed to happen) and the lowest ring, which is called `user mode'.
@@ -1422,9 +1496,9 @@ Recall the discussion about library functions vs system calls. Typically, you usWhen you write a small C program, you use variables which are convenient and make sense to the reader. If, on the other hand, you're writing routines which will be part of a bigger problem, any global variables you have are part of a community of other peoples' global variables; some of the variable names can clash. When a program has lots of global variables which aren't meaningful enough to be distinguished, you get namespace pollution. In large projects, effort must be made to remember reserved names, and to find ways to develop a scheme for naming unique variable names and symbols.
@@ -1439,9 +1513,9 @@ The file /proc/kallsyms holds all the symbols that the kernel knows aboutMemory management is a very complicated subject—the majority of O'Reilly's `Understanding The Linux Kernel' is just on memory management! We're not setting out to be experts on memory managements, but we do need to know a couple of facts to even begin worrying about writing real modules.
@@ -1460,15 +1534,15 @@ By the way, I would like to point out that the above discussion is true for anyOne class of module is the device driver, which provides functionality for hardware like a TV card or a serial port. On unix, each piece of hardware is represented by a file located in /dev named a device file which provides the means to communicate with the hardware. The device driver provides the communication on behalf of a user program. So the es1370.o sound card device driver might connect the /dev/sound device file to the Ensoniq IS1370 sound card. A userspace program like mp3blaster can use /dev/sound without ever knowing what kind of sound card is installed.
The file_operations structure is defined in linux/fs.h, and holds pointers to functions defined by the driver that perform various operations on the device. Each field of the structure corresponds to the address of some function defined by the driver to handle a requested operation.
@@ -1627,9 +1701,9 @@ An instance of struct file_operations containing pointers to functions that areEach device is represented in the kernel by a file structure, which is defined in linux/fs.h. Be aware that a file is a kernel level structure and never appears in a user space program. It's not the same thing as a FILE, which is defined by glibc and would never appear in a kernel space function. Also, its name is a bit misleading; it represents an abstract open `file', not a file on a disk, which is represented by a structure named inode.
@@ -1644,9 +1718,9 @@ Go ahead and look at the definition of file. Most of the entries you see, like sAs discussed earlier, char devices are accessed through device files, usually located in /dev[7]. The major number tells you which driver handles which device file. The minor number is used only by the driver itself to differentiate which device it's operating on, just in case the driver handles more than one device.
@@ -1675,9 +1749,9 @@ If you pass a major number of 0 to register_chrdev, the return value will be theWe can't allow the kernel module to be rmmod'ed whenever root feels like it. If the device file is opened by a process and then we remove the kernel module, using the file would cause a call to the memory location where the appropriate function (read/write) used to be. If we're lucky, no other code was loaded there, and we'll get an ugly error message. If we're unlucky, another kernel module was loaded into the same location, which means a jump into the middle of another function within the kernel. The results of this would be impossible to predict, but they can't be very positive.
@@ -1698,9 +1772,9 @@ It's important to keep the counter accurate; if you ever do lose track of the coThe next code sample creates a char driver named chardev. You can cat its device file.
@@ -1716,9 +1790,9 @@ The next code sample creates a char driver named chardev. You can cat its device/*
@@ -1893,9 +1967,9 @@ The next code sample creates a char driver named chardev. You can cat its device
The system calls, which are the major interface the kernel shows to the processes, generally stay the same across versions. A new system call may be added, but usually the old ones will behave exactly like they used to. This is necessary for backward compatibility – a new kernel version is not supposed to break regular processes. In most cases, the device files will also remain the same. On the other hand, the internal interfaces within the kernel can and do change between versions.
@@ -1919,9 +1993,9 @@ Update: What we've said above was true for kernels up to and including 2.6.10. YIn Linux, there is an additional mechanism for the kernel and kernel modules to send information to processes — the /proc file system. Originally designed to allow easy access to information about processes (hence the name), it is now used by every bit of the kernel which has something interesting to report, such as /proc/modules which provides the list of modules and /proc/meminfo which stats memory usage statistics.
@@ -1958,9 +2032,9 @@ HelloWorld!/*
@@ -2079,9 +2153,9 @@ HelloWorld!
We have seen a very simple example for a /proc file where we only read the file /proc/helloworld. It's also possible to write in a /proc file. It works the same way as read, a function is called when the /proc file is written. But there is a little difference with read, data comes from user, so you have to import data from user space to kernel space (with copy_from_user or get_user)
@@ -2095,9 +2169,9 @@ The only memory segment accessible to a process is its own, so when writing regu/**
@@ -2219,9 +2293,9 @@ The only memory segment accessible to a process is its own, so when writing regu
We have seen how to read and write a /proc file with the /proc interface. But it's also possible to manage /proc file with inodes. The main interest is to use advanced function, like permissions.
@@ -2239,9 +2313,9 @@ It's important to note that the standard roles of read and write are reversed in/*
@@ -2450,9 +2524,9 @@ Still hungry for procfs examples? Well, first of all keep in mind, there are rum
As we have seen, writing a /proc file may be quite "complex". So to help people writting /proc file, there is an API named seq_file that helps @@ -2470,9 +2544,9 @@ BE CARREFUL: when a sequence is finished, another one starts. That means that at