Reposted from: http://blog.csdn.net/zqixiao_09/article/details/50838043
1. Module compilation
In the part of driver transplantation in the previous kernel compilation, we mentioned that driver compilation is divided into static compilation and dynamic compilation ; static compilation is to compile the driver directly into the kernel, and dynamic compilation is to compile the driver into modules.
There are two types of dynamic compilation:
a -- internal compilation
Compile in the kernel source directory
b -- external compilation
Compile outside the kernel source directory
Second, the specific compilation process analysis
Note: This compilation is an external compilation, the kernel source code used is Ubuntu source code, not the linux 3.14 kernel source code used by the development board, and the operating platform is X86.
For an ordinary linux device driver module, the following is a classic makefile code. Using the following makefile can complete the compilation of most drivers. When using it, you only need to modify the name of the driver to be compiled and generated. Just modify the value of obj-m.
ifneq ($(KERNELRELEASE),) obj-m:=hello.o else KDIR := /lib/modules/$(shell uname -r)/build PWD:=$(shell pwd) all: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.symvers *.cmd *.cmd.o endif |
1. Variables in makefile
First explain the meaning of some variables in the following makefile:
(1) KERNELRELEASE is defined in the top-level makefile in the linux kernel source code
(2) Shell pwd gets the current working path
(3) shell uname -r gets the version number of the current kernel
(4) KDIR The source code directory of the current kernel.
There are two directories about linux source code, namely
"/lib/modules/$(shell uname -r)/build"
"/usr/src/linux-header-$(shell uname -r)/"
But if you have compiled the kernel, you will know that the source code in the usr directory is usually downloaded and decompressed by ourselves, while the source code in the lib directory is automatically copied during compilation. The file structure of the two is exactly the same, so sometimes Set the kernel source directory to /usr/src/linux-header-$(shell uname -r)/. The kernel source code directory can be modified according to your own storage location.
(5)make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
This is what compiles the module:
a -- First change the directory to the location specified by the -C option (that is, the kernel source code directory ), where the top-level makefile of the kernel is saved;
b - - The M= option makes the makefile return to the module source code directory before constructing the modules target ; then, the modules target points to the module set in the obj-m variable ; in the above example, we set the variable to hello .o.
2. Execution steps of make
a -- When entering for the first time, the macro "KERNELRELEASE" is not defined, so enter else;
b -- record the kernel path, record the current path;
Since there is no target behind make, make will execute the first target in the Makefile that does not start with . as the default target. By default, execute all this rule
c -- make -C $(KDIR) M=$(PWD) modules
-C Enter the directory of the kernel to execute the Makefile, KERNELRELEASE will be assigned a value during execution, M=$(PWD) means return to the current directory, execute the makefile again, modules are compiled into modules
So what actually runs here is
make -C /lib/modules/2.6.13-study/build M=/home/fs/code/1/module/hello/ modules
d -- Execute the makefile again , KERNELRELEASE will have a value, and obj-m:=hello.o will be executed
obj-m: means to link hello.o and other object files into a hello.ko module file, and compile hello.c into a hello.o file first when compiling
It can be seen that make is called 3 times here
1) -- make
2) -- The top-level makedile of the linux kernel source tree is invoked and generated. o file
3) -- linux kernel source tree makefile call, link .o file into ko file
3. Compile multiple files
If there are multiple source files, use the following method:
obj-m := hello.o
hello-objs := file1.o file2.o file3.o
3. Simple instructions for internal compilation
If you move the hello module into the kernel source code. For example, put it in /usr/src/linux/driver/, KERNELRELEASE will be defined.
In /usr/src/linux/Makefile there is KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION).
At this time, the hello module is no longer compiled with make alone, but compiled with make modules in the kernel. At this time, the driver module is compiled with the kernel.