00. Table of Contents
Article directory
01. Overview
For the linux kernel, there are two ways to add kernel modules to the kernel:
- 1. Compile the kernel module into a kernel module file, which is dynamically loaded manually by the user after the kernel is started.
- 2. Compile the module directly into the kernel and load it automatically when the kernel starts.
02. Test code
test.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
printk(KERN_EMERG "Hello Module Init\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_EMERG "Hello Module Exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("uplooking");
MODULE_DESCRIPTION("hello module");
MODULE_ALIAS("test_module");
03. Kernel module compilation
The building steps and compilation required for the kernel driver module object are very complicated. It takes advantage of the powerful functions of the Linux kernel build system. Of course, we do not need to understand this part of knowledge in depth. We can use a simple Make tool to compile the kernel driver we want. module.
Makefile reference is as follows
KERNEL_DIR=/home/deng/code/x3399/kernel
CROSS_COMPILE=aarch64-linux-gnu-gcc
obj-m := test.o
all:
$(MAKE) -C $(KERNEL_DIR) M=`pwd` modules
.PHONE:clean
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
- Line 1: Specify the storage location of the compiled kernel
- Line 2: Specify the cross-compilation tool chain
- Line 3: Indicates compilation as module
- Line 4: all is just a label, which can be defined by yourself. It is the default execution target of make.
- Line 5: $(MAKE):MAKE is a macro variable in the Makefile. To reference the macro variable, you must use symbols. This actually points to the make program, so you can also replace $(MAKE) with make. -C: is an option of the make command. -C is used to change directory. -C dir is to go to the dir directory. M=
pwd
: Return to the current directory. What this sentence means is: when make executes the default target all, -C (KERNEL_DIR) specifies to jump to the kernel source code directory to execute the Makefile there, and -C $ (KERNEL_DIR) specifies to jump to the kernel source code directory to execute there. Makefile, M=pwd
means returning to the current directory to execute the current Makefile. - Line 6: clean is to delete the files generated by make.
Check the current folder and add test.ko. This is the kernel driver module we wrote and compiled ourselves.
deng@local:~/code/test/1module$ make
make -C /home/deng/code/x3399/kernel M=`pwd` modules
make[1]: 进入目录“/home/deng/code/x3399/kernel”
CC [M] /home/deng/code/test/1module/test.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/deng/code/test/1module/test.mod.o
LD [M] /home/deng/code/test/1module/test.ko
make[1]: 离开目录“/home/deng/code/x3399/kernel”
deng@local:~/code/test/1module$
deng@local:~/code/test/1module$ ls
Makefile Module.symvers test.ko test.mod.o
modules.order test.c test.mod.c test.o
deng@local:~/code/test/1module$
04. Kernel module loading and unloading
After compiling the kernel driver module, test.ko can be copied to the development board in a variety of ways. Generally, the NFS network file system or SCP command is used.
Load module
[root@rk3399:/mnt/code/test/1module]# ls
Makefile modules.order test.ko test.mod.o
Module.symvers test.c test.mod.c test.o
[root@rk3399:/mnt/code/test/1module]# insmod test.ko
[ 652.669514] Hello Module Init
[root@rk3399:/mnt/code/test/1module]#
Uninstall module
[root@rk3399:/mnt/code/test/1module]# rmmod test
[ 668.206247] Hello Module Exit
[root@rk3399:/mnt/code/test/1module]#