First, the experimental environment
Virtual machines: VMware Workstation 12.0;
Operating system: ubuntu16.04 (32-bit);
Current kernel version: 4.4.0-21-generic
Second, the Knowledge reserve
Now, let's take a look at what a kernel module is:
A module is a standalone program that can be compiled separately, but not run independently. It is linked to the kernel at run time as part of the kernel running in kernel space, which is different from the process running in user space. A module typically consists of a set of functions and data structures that implement a file system, a driver, or a function on top of another kernel.
Compare the differences between the application and kernel modules:
Next, let's start by writing a small program that takes this as a starting point to explore how to write kernel modules:
hello.c
1#include <linux/module.h>2#include <linux/kernel.h>3#include <linux/init.h>4 /*Necessary Header Files*/5 6 Static int__init Hello_init (void )7 {8PRINTK ("hello,world!\ n ");9 return 0;Ten } One A Static void__exit Hello_exit (void ) - { - PRINTK ("finish! \ n "); the } - Module_init (lkp_init); - Module_exit (lkp_cleanup); - +Module_license ("GPL");
A simple analysis:
Line 1th: Linux/module.h is a necessary header file that must be included in the kernel module code.
Line 2nd: linux/kernel.h contains common kernel functions.
Line 3rd: linux/init.h contains macros _init and _exit, which allow the kernel to free up memory.
Line 6th: the Hello_init () function is the entry point of the module, the initialization function of the module, which must contain such things as the code to be compiled, the initialization of the data structure, and so on. It is registered to the system via the Module_init () routine and is called when the kernel is loaded. All initialization functions of the module must conform to this form: int xx_init (void), because the INIT function is not normally called directly by an external function, so you do not have to export the function, so it can be marked as static. the init function returns a numeric value of type int, which returns 0 if the initialization is successful, otherwise a non-0 value is returned.
Line 8th: The function of PRINTK is similar to printf in C, which is defined by the kernel.
Line 12th: the Hello_exit () function is the Exit function of the module, and it has a module_exit () routine registered to the system. When the module is unloaded from the kernel, the kernel calls Hello_exit (). The Exit function may be responsible for cleaning up resources before returning to ensure that the hardware is in a consistent state, or doing other things. The exit function must conform to this form: void Xx_exit (void), or as static.
Line 16th/17: Functions Module_init () and Cleanup_exit () are the most basic and necessary two functions in module programming. Calling Module_init () is not a real function call, but a macro call, and its only parameter is the initialization function of the module. Module_exit (), the only argument is the Exit function.
Line 19th: module_license ("GPL"); macros are used to specify the copyright of the module.
The code is already there, but we don't compile it in the way of compiling C code, because in large development projects there are typically dozens of to hundreds of source files, which can be very inconvenient if you manually type the GCC command each time. Therefore, the make tool is often used to automate the compilation process. This automatic compilation can greatly simplify the development effort and avoid unnecessary recompilation. These include: If only a few source files have been modified, only those source files will be recompiled, and if a header file has been modified, all source files containing the header file will be recompiled. Makefile the following:
1 obj-m:=hello.o //Generate Hello Module target file 2 current_path:=$ (shell pwd)//current path where module is located 3 linux_kernel_path:=/usr/src/linux-headers-4.4. 0-generic//linux-The absolute path of the kernel source code 4all:5 make-c $ ( Linux_kernel_path) m=$ (Current_path) modules//compile module 6clean:7make -C $ (Linux_kernel_path) m=$ (current_path) clean//cleanup
Note: Before each command (for example, before the Make command), type a tab character (press the TAB key)
With makefile, the Execute make command automatically forms the associated suffix. O and. ko files.
Note: How do I view your kernel version?
Command: Uname–a
Once the module is compiled, insert it into the kernel: (Requires root access)
Insmod Hello.ko
Enter DMESG to view the output of the program.
Dmesg
When the module is not needed, unmount the module:
Rmmod Hello
Third, advanced module
Learn elder sister's code, can run directly, the function is to output the current process related information.
Code: 1.C
1#include <linux/init.h>2#include <linux/module.h>3#include <linux/kernel.h>4#include <linux/sched.h>5 6 Static structTask_struct *pcurrent;7 Static int__init Print_init (void)8 {9PRINTK (Kern_info"Print Current Task info\n");TenPrintk"pid\ttgid\tprio\tstate\n"); One for_each_process (pcurrent) { APrintk"%d \ t",pcurrent->pid); -Printk"%d \ t",pcurrent->tgid); -Printk"%d \ t",pcurrent->prio); thePrintk"%ld \ n",pcurrent->State ); - } - return 0; - } + Static void__exit Print_exit (void) - { +PRINTK (Kern_info"finished\n"); A } at Module_init (print_init); -Module_exit (Print_exit);
Makefile File:
1 obj-m:=1. O2 current_path:=$ (shell pwd)3 linux_kernel_path:=/usr/src /linux-headers-4.4. 0-generic4all:5 make-c $ (linux_kernel_path) m= $ (current_path) modules 6 Clean : 7 Make-c $ (Linux_kernel_path) m=$ (current_path) Clean
Operation Result:
Iv. Advanced Modules
① lists the segment permissions for the space of the current process virtual memory.
② finds the VMA of the specified virtual address and prints the start address, termination address, and segment flags for that segment. ③ find the physical address that corresponds to the specified virtual address.
④ build the file and test the code.
Source code from the network, but because its kernel version is too old, many function interfaces have changed, the code is not used, so now is improving, please expect ~ ~
Kernel module programming of Linux kernel design and analysis