mirror of
https://github.com/bashrc/LKMPG.git
synced 2018-06-11 03:06:54 +02:00
Remove example numbers
This commit is contained in:
@@ -136,7 +136,7 @@ When the first caveman programmer chiseled the first program on the walls of the
|
||||
|
||||
Here's the simplest module possible. Don't compile it yet; we'll cover module compilation in the next section.
|
||||
|
||||
*** Example 2-1. hello-1.c
|
||||
*** Example: hello-1.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* hello-1.c - The simplest kernel module.
|
||||
@@ -167,14 +167,14 @@ Typically, init_module() either registers a handler for something with the kerne
|
||||
|
||||
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.
|
||||
|
||||
*** Introducing printk()
|
||||
** Introducing printk()
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
** Compiling Kernel Modules
|
||||
|
||||
@@ -182,7 +182,7 @@ Kernel modules need to be compiled a bit differently from regular userspace apps
|
||||
|
||||
So, let's look at a simple Makefile for compiling a module named hello-1.c:
|
||||
|
||||
*** Example 2-2. Makefile for a basic kernel module
|
||||
*** Example: Makefile for a basic kernel module
|
||||
#+BEGIN_SRC makefile
|
||||
obj-m += hello-1.o
|
||||
|
||||
@@ -253,7 +253,7 @@ 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:
|
||||
|
||||
*** Example 2-3. hello-2.c
|
||||
*** Example: hello-2.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* hello-2.c - Demonstrating the module_init() and module_exit() macros.
|
||||
@@ -280,7 +280,7 @@ module_exit(hello_2_exit);
|
||||
|
||||
So now we have two real kernel modules under our belt. Adding another module is as simple as this:
|
||||
|
||||
*** Example 2-4. Makefile for both our modules
|
||||
*** Example: Makefile for both our modules
|
||||
#+BEGIN_SRC makefile
|
||||
obj-m += hello-1.o
|
||||
obj-m += hello-2.o
|
||||
@@ -305,7 +305,7 @@ The __exit macro causes the omission of the function when the module is built in
|
||||
|
||||
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.
|
||||
|
||||
*** Example 2-5. hello-3.c
|
||||
*** Example: hello-3.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* hello-3.c - Illustrating the __init, __initdata and __exit macros.
|
||||
@@ -384,7 +384,7 @@ I'd recommend to use something like grep -inr MODULE_AUTHOR * in /usr/src/linux-
|
||||
Users of traditional Unix editors, like emacs or vi will also find tag files useful. They can be generated by make tags or make TAGS in /usr/src/linux-2.6.x/ . Once you've got such a tagfile in your kerneltree you can put the cursor on some function call and use some key combination to directly jump to the definition function.
|
||||
|
||||
|
||||
*** Example 2-6. hello-4.c
|
||||
*** Example: hello-4.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* hello-4.c - Demonstrates module documentation.
|
||||
@@ -461,7 +461,7 @@ A good use for this is to have the module variable's default values set, like an
|
||||
Lastly, there's a macro function, MODULE_PARM_DESC(), that is used to document arguments that the module can take. It takes two parameters: a variable name and a free form string describing that variable.
|
||||
|
||||
|
||||
*** Example 2-7. hello-5.c
|
||||
*** Example: hello-5.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* hello-5.c - Demonstrates command line argument passing to a module.
|
||||
@@ -571,7 +571,7 @@ Sometimes it makes sense to divide a kernel module between several source files.
|
||||
|
||||
Here's an example of such a kernel module.
|
||||
|
||||
*** Example 2-8. start.c
|
||||
*** Example: start.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* start.c - Illustration of multi filed modules
|
||||
@@ -590,7 +590,7 @@ int init_module(void)
|
||||
The next file:
|
||||
|
||||
|
||||
*** Example 2-9. stop.c
|
||||
*** Example: stop.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* stop.c - Illustration of multi filed modules
|
||||
@@ -608,7 +608,7 @@ void cleanup_module()
|
||||
And finally, the makefile:
|
||||
|
||||
|
||||
*** Example 2-10. Makefile
|
||||
*** Example: Makefile
|
||||
#+BEGIN_SRC: makefile
|
||||
obj-m += hello-1.o
|
||||
obj-m += hello-2.o
|
||||
@@ -904,7 +904,7 @@ cat /proc/devices
|
||||
|
||||
(or open the file with a program) and the driver will put the number of times the device file has been read from into the file. We don't support writing to the file (like echo "hi" > /dev/hello), but catch these attempts and tell the user that the operation isn't supported. Don't worry if you don't see what we do with the data we read into the buffer; we don't do much with it. We simply read in the data and print a message acknowledging that we received it.
|
||||
|
||||
*** Example 4-1. chardev.c
|
||||
*** Example: chardev.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* chardev.c: Creates a read-only char device that says how many times
|
||||
@@ -1107,7 +1107,7 @@ Each time, everytime the file */proc/helloworld* is read, the function procfs_re
|
||||
HelloWorld!
|
||||
#+END_SRC
|
||||
|
||||
*** Example 5-1. procfs1.c
|
||||
*** Example: procfs1.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* procfs1.c - create a "file" in /proc
|
||||
@@ -1230,7 +1230,7 @@ The reason for copy_from_user or get_user is that Linux memory (on Intel archite
|
||||
|
||||
The only memory segment accessible to a process is its own, so when writing regular programs to run as processes, there's no need to worry about segments. When you write a kernel module, normally you want to access the kernel memory segment, which is handled automatically by the system. However, when the content of a memory buffer needs to be passed between the currently running process and the kernel, the kernel function receives a pointer to the memory buffer which is in the process segment. The put_user and get_user macros allow you to access that memory. These functions handle only one caracter, you can handle several caracters with copy_to_user and copy_from_user. As the buffer (in read or write function) is in kernel space, for write function you need to import data because it comes from user space, but not for the read function because data is already in kernel space.
|
||||
|
||||
*** Example 5-2. procfs2.c
|
||||
*** Example: procfs2.c
|
||||
#+BEGIN_SRC: c
|
||||
/**
|
||||
* procfs2.c - create a "file" in /proc
|
||||
@@ -1357,7 +1357,7 @@ Another interesting point here is the module_permission function. This function
|
||||
|
||||
It's important to note that the standard roles of read and write are reversed in the kernel. Read functions are used for output, whereas write functions are used for input. The reason for that is that read and write refer to the user's point of view --- if a process reads something from the kernel, then the kernel needs to output it, and if a process writes something to the kernel, then the kernel receives it as input.
|
||||
|
||||
*** Example 5-3. procfs3.c
|
||||
*** Example: procfs3.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* procfs3.c - create a "file" in /proc, use the file_operation way
|
||||
@@ -1571,7 +1571,7 @@ non NULL value, the function next() is called. This function is an iterator, the
|
||||
BE CARREFUL: when a sequence is finished, another one starts. That means that at the end of function stop(), the function start() is called again. This loop finishes when the function start() returns NULL. You can see a scheme of this in the figure "How seq_file works".
|
||||
|
||||
|
||||
*** Figure 5-1. How seq_file works
|
||||
*** Figure: How seq_file works
|
||||
|
||||
[seq_file]
|
||||
|
||||
@@ -1580,7 +1580,7 @@ seq_lseek, and some others. But nothing to write in the /proc file. Of
|
||||
course, you can still use the same way as in the previous example.
|
||||
|
||||
|
||||
*** Example 5-4. procfs4.c
|
||||
*** Example: procfs4.c
|
||||
#+BEGIN_SRC: c
|
||||
/**
|
||||
* procfs4.c - create a "file" in /proc
|
||||
@@ -1740,7 +1740,7 @@ The ioctl number encodes the major device number, the type of the ioctl, the com
|
||||
|
||||
If you want to use ioctls in your own kernel modules, it is best to receive an official ioctl assignment, so if you accidentally get somebody else's ioctls, or if they get yours, you'll know something is wrong. For more information, consult the kernel source tree at Documentation/ioctl-number.txt.
|
||||
|
||||
** Example 7-1. chardev.c
|
||||
** Example: chardev.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* chardev.c - Create an input/output character device */
|
||||
@@ -2019,7 +2019,7 @@ void cleanup_module()
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** Example 7-2. chardev.h
|
||||
** Example: chardev.h
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* chardev.h - the header file with the ioctl definitions.
|
||||
@@ -2089,7 +2089,7 @@ void cleanup_module()
|
||||
#endif
|
||||
#+END_SRC
|
||||
|
||||
** Example 7-3. ioctl.c
|
||||
** Example: ioctl.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* ioctl.c - the process to use ioctl's to control the kernel module
|
||||
@@ -2217,7 +2217,7 @@ Now, if B is removed first, everything will be well---it will simply restore the
|
||||
|
||||
Note that all the related problems make syscall stealing unfeasiable for production use. In order to keep people from doing potential harmful things sys_call_table is no longer exported. This means, if you want to do something more than a mere dry run of this example, you will have to patch your current kernel in order to have sys_call_table exported. In the example directory you will find a README and the patch. As you can imagine, such modifications are not to be taken lightly. Do not try this on valueable systems (ie systems that you do not own - or cannot restore easily). You'll need to get the complete sourcecode of this guide as a tarball in order to get the patch and the README. Depending on your kernel version, you might even need to hand apply the patch. Still here? Well, so is this chapter. If Wyle E. Coyote was a kernel hacker, this would be the first thing he'd try. ;)
|
||||
|
||||
** Example 8-1. syscall.c
|
||||
** Example: syscall.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* syscall.c
|
||||
@@ -2416,7 +2416,7 @@ Last input:
|
||||
hostname:~/lkmpg-examples/09-BlockingProcesses#
|
||||
#+END_SRC
|
||||
|
||||
** Example 9-1. sleep.c
|
||||
** Example: sleep.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* sleep.c - create a /proc file, and if several processes try to open it at
|
||||
@@ -2731,7 +2731,7 @@ void cleanup_module()
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** Example 9-2. cat_noblock.c
|
||||
** Example: cat_noblock.c
|
||||
#+BEGIN_SRC: c
|
||||
/* cat_noblock.c - open a file and display its contents, but exit rather than
|
||||
* wait for input */
|
||||
@@ -2810,7 +2810,7 @@ In Section 1.2.1.2, I said that X and kernel module programming don't mix. That'
|
||||
|
||||
The way this is done is by using current, a pointer to the currently running task, to get the current task's tty structure. Then, we look inside that tty structure to find a pointer to a string write function, which we use to write a string to the tty.
|
||||
|
||||
*** Example 10-1. print_string.c
|
||||
*** Example: print_string.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* print_string.c - Send output to the tty we're running on, regardless if it's
|
||||
@@ -2928,7 +2928,7 @@ In certain conditions, you may desire a simpler and more direct way to communica
|
||||
|
||||
The following source code illustrates a minimal kernel module which, when loaded, starts blinking the keyboard LEDs until it is unloaded.
|
||||
|
||||
*** Example 10-2. kbleds.c
|
||||
*** Example: kbleds.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* kbleds.c - Blink keyboard leds until the module is unloaded.
|
||||
@@ -3046,7 +3046,7 @@ Instead of doing that, we can create a function that will be called once for eve
|
||||
|
||||
There's one more point we need to remember here. When a module is removed by rmmod, first its reference count is checked. If it is zero, module_cleanup is called. Then, the module is removed from memory with all its functions. Things need to be shut down properly, or bad things will happen. See the code below how this can be done in a safe way.
|
||||
|
||||
** Example 11-1. sched.c
|
||||
** Example: sched.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* sched.c - scheduale a function to be called on every timer interrupt.
|
||||
@@ -3243,7 +3243,7 @@ files (specifically, drivers/char/keyboard.c), there is no way to restore it. Be
|
||||
This code binds itself to IRQ 1, which is the IRQ of the keyboard controlled under Intel architectures. Then, when it receives a keyboard interrupt, it reads the keyboard's status (that's the purpose of the inb(0x64)) and the scan code, which is the value returned by the keyboard. Then, as soon as the kernel thinks it's feasible, it runs got_char which gives the code of the key
|
||||
used (the first seven bits of the scan code) and whether it has been pressed (if the 8th bit is zero) or released (if it's one).
|
||||
|
||||
*** Example 12-1. intrpt.c
|
||||
*** Example: intrpt.c
|
||||
#+BEGIN_SRC: c
|
||||
/*
|
||||
* intrpt.c - An interrupt handler.
|
||||
|
||||
Reference in New Issue
Block a user