The makefile of the Linux kernel is divided into five parts:
Makefile: the top-level makefile that reads the. config file and is responsible for creating vmlinux (kernel image) and modules (module file ).
In the. config Kernel configuration file, call the make menuconfig or make xconfig command.
ARCH/$ (ARCH)/makefile kernel-related, makefile of the specific architecture
Scripts/makefile. * Public compilation rule definition file. All kbuild makefile rules, including definitions and rules.
Each subdirectory of kbuild makefiles has kbuild makefile, which is used to generate built-in or modular targets. (Note: kbuild makefile refers to the makefile using the kbuild structure. Most makefiles in the kernel are kbuild makefiles .)
The. config file read by the top-level makefile, which is generated by the Kernel configuration program.
The top-level makefile is responsible for making: vmlinux (Kernel File) and modules (module file ). The creation process is mainly implemented by recursively accessing sub-directories. Determine which subdirectories to access based on the Kernel configuration file. The top-level makefile must contain a specific architecture. Its name is similar to arch/$ (ARCH)/makefile. This architecture makefile provides the top-level makefile with special information about its architecture.
Each subdirectory has a kbuild MAKEFILE file to execute commands passed from its upper directory.
Kbuild makefile extracts information from the. config file and generates a list of files required for kbuild to complete kernel compilation.
Scripts/makefile. * contains all definitions, rules, and other information. These files are used to compile kbuild-based
Makefile Kernel
Makefile compilation process
When you use Linux makefile to compile the kernel version, the makefile compilation process is as follows:
Run the command line or graphical interface configuration tool to cut the kernel and generate the. config configuration file.
Save the kernel version information to include/Linux/version. h.
Generate the symbolic link include/ASM, pointing to the actual directory include/ASM-$ (ARCH)
Make necessary preparations for the generation of the final target file
Recursively enter the/init,/core,/drivers,/NET,/lib, and other directories and subdirectories to compile and generate all target files.
Link the target file generated in the above process to generate vmlinux, which is stored in the root directory of the kernel code tree
Finally, the final image bootimage is created based on the Post-compiled processing rules defined in the arch/$ (ARCH)/MAKEFILE file, including the creation of boot records, preparation of initrd images and related processing.
Key rules and definitions of makefile
1) target definition
The target definition is the core part of the MAKEFILE file. The target definition notifies makefile of the target files to be generated, how to link the target files according to the special compilation options, and control which subdirectories should be recursively entered for compilation.
In this example, the MAKEFILE file is located in the/fs/ext2 directory:
OBJ-$ (config_ext2_fs) + = ext2.o
Ext2-y: = balloc. O bitmap. O dir. o file. O fsync. O ialloc. O inode. o ioctl. O nameI. o super. O symlink. o
Ext2-$ (config_ext2_fs_xattr) + = xattr. O xattr_user.o xattr_trusted.o
Ext2-$ (config_ext2_fs_posix_acl) + = ACL. o
Ext2-$ (config_ext2_fs_security) + = xattr_security.o
Ext2-$ (config_ext2_fs_xip) + = xip. o
This indicates that the target file associated with ext2 is composed of a list of files defined by the ext2-y, where ext2-$ (*) is composed of the Kernel configuration file. the configuration items in config determine that the makefile will generate a unified ext2.o target file in this directory (determined by obj-$ (config_ext2_fs ). OBJ-y indicates the set of target files required to generate the vmlinux file. The specific files depend on the Kernel configuration.
Makefile compiles all the files defined in $ (obj-y) and calls the linker to link these files to the built-in.o file. The final built-in.o file is linked to vmlinux through the top-level makefile. The order of $ (obj-y) files is very important. The list file can be repeated. When a file appears for the first time, it is linked to the built-in.o, and the file with the same name that appears later will be ignored. The file order directly determines the order in which they are called.
All target files included in the Lib-y definition will be compiled into the next Unified Library file in this directory. It is worth noting that the Lib-y definition is generally restricted in the lib and arch/$ (ARCH)/lib directories.
The MAKEFILE file of the system and the top-level MAKEFILE file jointly define the rules for creating vmlinux files.
$ (Head-y) lists objects that are first linked to vmlinux.
$ (Libs-y) lists the directories that can be found in the Lib. A file.
Other variables list directories that can find embedded object files.
The objects listed in $ (init-y) are located after the $ (Head-y) object.
Then the order is as follows:
$ (Core-y), $ (libs-y), $ (drivers-y), and $ (net-Y ).
The top-level makefile defines all common directories. The ARCH/$ (ARCH)/MAKEFILE file only needs to add system-related directories.
Example: # arch/i386/makefile
Libs-y + = ARCH/i386/lib/
Core-y + = ARCH/i386/kernel /\
ARCH/i386/MM /\
ARCH/i386/$ (mcore-y )/\
ARCH/i386/crypto/
Drivers-$ (config_math_emulation) + = ARCH/i386/Math-emu/
Drivers-$ (config_pci) + = ARCH/i386/PCI/
................................................
2) Directory Recursion
Makefile is only responsible for the target file in the current directory. Files in the subdirectory are compiled by makefile in the subdirectory. The compilation system uses obj-y and obj-m to automatically recursively compile files in each subdirectory.
For FS/makefile:
OBJ-$ (config_ext2_fs) + = ext2/
If config_ext2_fs is set to Y or m in the Kernel configuration file. config, the kernel makefile will automatically go to The ext2 directory for compilation. The kernel makefile only uses this information to determine whether to compile this directory. The makefile in the subdirectory specifies which files are compiled as modules and which files are compiled into the kernel.
3) Dependency
The Linux makefile is generated during the compilation process. file Name. o. CMD (for example, for Main. c file, which corresponds to the dependent file name. main. o. CMD) to define the dependency.
The dependency of a file consists of the following parts:
All pre-dependent files (including all related *. C and *. h)
All files related to the config _ Option
Command Line used to compile the target file
4) Special rules
Special rules are used when the kernel compilation requires rule definition but no corresponding definition. Typical examples include rules for generating header files during compilation. Other examples include special rules for system makefile to compile boot images. The special rules are written in the same way as the general makefile rules.
The Compiling Program cannot be executed in the directory where makefile is located. Therefore, all special rules must provide the relative paths of the prerequisite file and the target file.
When defining special rules, two variables are used:
$ (SRC): $ (SRC) is the relative path of the MAKEFILE file directory. This variable $ (SRC) is used when using files in the code tree ).
$ (OBJ): $ (OBJ) is the relative path of the target file directory. Use the $ (OBJ) variable to generate the file.
Example: # Drivers/SCSI/makefile
$ (OBJ)/53c8xx_d.h: $ (SRC)/53c7, 8xx. scr $ (SRC)/script_asm.pl
$ (CPP)-dchip = 810-<$ <|... $ (SRC)/script_asm.pl
This is a special compilation rule using common syntax.
The target file depends on two prerequisite files. The prefix of the target file is $ (OBJ), and the prefix of the prerequisite file is $ (SRC) (because they are not generated files ).
5) Pilot Image
The MAKEFILE file defines the target objects for compiling vmlinux files, compresses and encapsulates them into Boot Code, and copies them to the appropriate location. This includes various installation commands. In Linux, makefile cannot provide a standard method for all architectures. Therefore, it is often necessary to provide additional processing rules for makefile in a specific hardware architecture.
The additional processing process is usually located in the boot/directory under ARCH/$ (ARCH.
The kernel compilation system cannot provide a convenient method to create the target system file under the boot/directory. Therefore, arch/$ (ARCH)/makefile must call the make command to create the target system file in the boot/directory. We recommend that you set a call in arch/$ (ARCH)/makefile and reference ARCH/$ (ARCH)/boot/makefile using the full path.
Example: # arch/i386/makefile
Boot: = ARCH/i386/boot
Bzimage: vmlinux
$ (Q) $ (make) $ (build) = $ (BOOT)/$ @
We recommend that you use the "$ (q) $ (make) $ (build) = <dir>" method to call the make command in the subdirectory.
When the make command without parameters is executed, the first target object will be compiled first. In the top-level makefile, the first target object is all :.
A system structure needs to define a default bootable image.
Adding a new prerequisite file to all targets can set a default target object different from vmlinux.
Example: # arch/i386/makefile
ALL: bzimage
When the "make" command without parameters is executed, the bzimage file will be compiled.
6) Common compilation commands
If_changed
If necessary, execute the passed command.
Usage:
$ (Builtin-target): $ (obj-y) Force
$ (Call if_changed, link_o_target)
When this rule is used, it checks which files need to be updated or the command line is changed. This will force the re-Compilation of the execution file whose compilation option is changed. The target object using if_changed must be listed in $ (builtin-target). Otherwise, the command line check will fail and the target will always be compiled.
If_changed_dep
If necessary, execute the passed command and update the dependent file.
Usage:
%. O: %. s force
$ (Call if_changed_dep, as_o_s)
When this rule is used, it checks which files need to be updated or the command line is changed. At the same time, it will re-detect changes in dependencies and generate new dependency files. This is different from the if_changed command.
7) custom commands
When a compiled command is executed normally, the brief information of the command is displayed. (To display the detailed command, add v = 1 to the command line ). To enable this function for custom commands, you need to set two variables:
Quiet_cmd _ <command>-content to be displayed
CMD _ <command>-executed command
Example :#
Quiet_pai_image = build $ @
Export _image = $ (OBJ)/tools/build $ (buildflags )\
$ (OBJ)/vmlinux. Bin >$ @
Targets + = bzimage
$ (OBJ)/bzimage: $ (OBJ)/vmlinux. Bin $ (OBJ)/tools/build force
$ (Call if_changed, image)
@ Echo 'kernel: $ @ is ready'
When you execute the make command to compile $ (OBJ)/bzimage targets, the following information is displayed:
Build ARCH/i386/boot/bzimage
8) pre-processing link script
The arch/$ (ARCH)/kernel/vmlinux. LDS link script is used when the vmlinux image is compiled.
The vmlinux. LDS. s file in the same directory is a variation of this script preprocessing. The kernel compilation system knows the. LDS file. And use the Rule * lDs. S-> * lDs.
Example: # arch/i386/kernel/makefile
Always: = vmlinux. LDS
# Makefile
Export cppflags_vmlinux.lds + =-p-c-u $ (ARCH)
The $ (always) value assignment statement tells the compilation system that the compilation target is vmlinux. LDS. $ (Cppflags_vmlinux.lds)
The value assignment statement tells the compilation system to compile the compilation options of the vmlinux. LDS target.
The following variables are used for compiling *. LDS:
Cppflags: The makefile defined on the top layer
Extra_cppflags: it can be set in the compiled MAKEFILE file.
Cppflags _ $ (@ F): The target compilation option. Use the full name of the file.
9) Compilation of host AIDS
The kernel compilation system supports compiling executable programs on the host during the compilation phase. Two steps are required to use the host Program: the first step is to use the hostprogs-y variable to tell the kernel to compile the system that the Host Program is available. Step 2: add potential dependencies to the Host Program. There are two ways to add dependencies or use the $ (always) variable in the rule.
10) Clean Mechanism
The Clean command clears most of the files generated in the compiled kernel, such as host programs, which are listed in $ (hostprogs-y), $ (hostprogs-m), and $ (always), $ (extra-y) and $ (targets) will all be deleted. The "*. [OAS]", "*. Ko", and some additional files generated by the compilation system in the Code directory are also deleted.
You can use $ (Clean-files) to define additional files.
Example: # Drivers/PCI/makefile
Clean-Files: = devlist. h classlist. h
When the "make clean" command is executed, the "devlist. h classlist. H" files will be deleted. By default, these files have the same relative paths as makefile. Otherwise, you must set an absolute path starting.
To delete the entire directory, use the following methods:
Example: # scripts/package/makefile
Clean-dirs: = $ (objtree)/Debian/
In this way, the entire Debian directory, including sub-directories, will be deleted. If the absolute path starting with '/' is not used for Kernel compilation, the relative path is used by default.
Generally, the kernel compilation system enters the subdirectory according to "obj-*: = DIR/", but the following method must be explicitly used in the system makefile:
Example: # arch/i386/boot/makefile
Subdir-: = compressed/
The above value assignment statement indicates that compressed/directory is entered when the compilation system executes the "make clean" command.
In the makefile of the final compiled boot image file, an optional target object name is archclean.
Example: # arch/i386/makefile
Archclean:
$ (Q) $ (make) $ (clean) = ARCH/i386/boot
When "make clean" is executed, the compiler enters the MAKEFILE file in arch/i386/boot, arch/i386/boot, and uses the subdir-marker to enter the lower-level directory.
Note 1: ARCH/$ (ARCH)/makefile cannot use "subdir-", because it is included in the top-level makefile, and the compilation mechanism does not work at this location.
NOTE 2: all directories listed in core-y, Libs-y, drivers-y, and net-y will be cleared by the "make clean" command.