Linux Source makefile detailed (complete)

Source: Internet
Author: User

Transferred from: http://www.cnblogs.com/Daniel-G/p/3286614.html

With the wide application of Linux operating system, especially the development of Linux in the field of embedded, more and more people begin to devote themselves to the development of Linux kernel level. Faced with the growing number of Linux kernel source code, developers after completing their own kernel code, will face the same problem, that is, how to integrate the source code into the Linux kernel, add the appropriate Linux configuration options, and eventually compiled into the Linux kernel. This requires an understanding of the Linux kernel configuration system.

As we all know, the Linux kernel is developed by Linux enthusiasts distributed around the world, and the Linux kernel faces many new changes every day. However, the Linux kernel organization does not appear chaotic phenomenon, but appears very concise, and has the very good extensibility, the developer can easily add new content to the Linux kernel. One reason is that Linux uses a modular kernel configuration system to ensure kernel extensibility. This article first analyzes the configuration system structure in the Linux kernel, then explains the format of the Makefile and configuration file and the meaning of the configuration statement, finally, through a simple example--test Driver, specifically how to add the self-developed code to the Linux kernel. In the following article, it is not possible to explain all the functions and commands, only those that are commonly used to explain, for those not discussed, please refer to the following references. 1. Configuring the basic structure of the system the Linux kernel configuration system consists of three parts, namely:
    1. Makefile: Makefile, which is distributed in the source code of the Linux kernel, defines the compilation rules of the Linux kernel;
    2. Configuration file (config.in): Provides the user with the function of configuration selection;
    3. Configuration tools: Includes the configuration command interpreter (interpreted for configuration commands used in configuration scripts) and the user interface (which provides a character-based interface, a ncurses graphical interface, and a user-interface based on the Xwindows GUI, each corresponding to the make config, making Menuconfig and make Xconfig).
These configuration tools are written using scripting languages, such as TCL/TK, Perl (and some code written in C). This article does not analyze the configuration system itself, but rather describes how to use the configuration system. So, unless the maintainer of the configuration system, the general kernel developers do not need to understand their principles, just need to know how to write Makefile and configuration files can be. So, in this article, we only discuss Makefile and configuration files. In addition, when it comes to content related to specific CPU architectures, we take ARM as an example, not only to clarify the issues discussed, but also to have no impact on the content itself.

2. Makefile 2.1 Makefile OverviewThe role of Makefile is to construct a list of source files that need to be compiled, compile them separately, and link the target code together to form a Linux kernel binary file, depending on the configuration. Since the Linux kernel source code is organized according to the tree structure, Makefile is also distributed in the directory tree. The Makefile in the Linux kernel and the files directly related to Makefile are:
    1. Makefile: The top level Makefile, is the entire kernel configuration, compiles the overall control file.
    2. . config: A kernel configuration file that contains the configuration options selected by the user to store the results of the kernel configuration (such as make config).
    3. Arch/*/makefile: Makefile in various CPU system directories, such as Arch/arm/makefile, is a Makefile for a specific platform.
    4. Makefile under each subdirectory: such as Drivers/makefile, is responsible for the management of the source code in the sub-directory.
    5. Rules.make: Rules file, used by all Makefile.
When the user is configured with make config, a. config is generated. Top-level Makefile read into the configuration selection in. config. Top-level Makefile has two main tasks: generating vmlinux files and kernel modules (module). To achieve this, the top-level Makefile recursively enters the various subdirectories of the kernel, calling the Makefile located in these subdirectories, respectively. As to which subdirectories to enter, it depends on the configuration of the kernel. In the top-level Makefile, there is a sentence: include arch/$ (arch)/makefile, which contains the Makefile of a particular CPU architecture, which contains platform-related information. The Makefile under each subdirectory also constructs a list of the source files required under the current configuration, based on the configuration information given by. config, and has an include $ (topdir)/rules.make at the end of the file. The Rules.make file plays a very important role in defining the compilation rules that are common to all Makefile. For example, if you need to compile all C programs in this directory into assembly code, you need to have the following compilation rules in Makefile:
%.S:%.c$ (CC) $ (CFLAGS)-S $<-o [email protected]
There are many subdirectories that have the same requirements and need to include this compilation rule in their Makefile, which can be cumbersome. In the Linux kernel, the compilation rules of this class are uniformly placed in the rules.make and included in the respective Makefile rules.make (include Rules.make), which avoids repeating the same rules in multiple Makefile. For the above example, the corresponding rule in Rules.make is:
%.S:%.c$ (CC) $ (CFLAGS) $ (extra_cflags) $ (cflags_$ (*F)) $ ([email protected])-s $<-o [email protected]
2.2 Variables in the MakefileThe top-level Makefile defines and outputs many variables to the environment, passing some information for the Makefile under each subdirectory. Some variables, such as Subdirs, are not only defined in the top-level Makefile, but are also augmented in Arch/*/makefile. Common variables are the following: 1) version information
Version information: Version,patchlevel, Sublevel, Extraversion,kernelrelease. The version information defines the current kernel version, such as Version=2,patchlevel=4,sublevel=18,exataversion=-rmk7, Together they form the kernel's release version kernelrelease:2.4.18-rmk72) CPU Architecture: ARCH
At the beginning of the top-level Makefile, use ARCH to define the architecture of the target CPU, such as Arch:=arm. In the Makefile of many subdirectories, choose to compile a list of source files according to the definition of ARCH. 3) path information: Topdir, Subdirs
Topdir defines the root directory where the Linux kernel source code resides. For example, Makefile under each subdirectory can find the location of Rules.make through the $ (topdir)/rules.make.
Subdirs defines a list of directories that, when the kernel or module is compiled, the top-level Makefile is based on Subdirs to decide which subdirectories to enter. The value of the subdirs depends on the configuration of the kernel, subdirs assigned to kernel drivers mm FS Net IPC Lib in the top-level Makefile, and Arch/*/makefile values in subdirs based on the configuration of the kernel , see the example in 4). 4) Core composition information: HEAD, Core_files, NETWORKS, DRIVERS, LIBS
The Linux kernel file Vmlinux is generated by the following rules:
Vmlinux: $ (CONFIGURATION) init/main.o init/version.o linuxsubdirs$ (LD) $ (linkflags) $ (HEAD) INIT/MAIN.O INIT/VERSION.O --start-group $ (core_files) $ (DRIVERS) $ (NETWORKS) $ (LIBS)--end-group-o Vmlinux

As you can see, Vmlinux is made up of HEAD, MAIN.O, VERSION.O, Core_files, DRIVERS, NETWORKS and LIBS. These variables, such as HEAD, are used to define the list of target files and library files that the connection generates Vmlinux. Where head is defined in Arch/*/makefile to determine the list of files that are first linked into the vmlinux. For example, the Cpu,head for ARM series is defined as:
                   HEAD            : = arch/arm/kernel/head-$ (PROCESSOR). O                    arch/arm/kernel/init_task.o                   

Indicates that head-$ (PROCESSOR). O and INIT_TASK.O need to be first linked to Vmlinux. PROCESSOR is ARMV or Armo, depending on the target CPU. Core_files,network,drivers and LIBS are defined in the top-level Makefile and are augmented by the arch/*/makefile as needed. Core_files corresponds to the core of the kernel files, there are KERNEL/KERNEL.O,MM/MM.O,FS/FS.O,IPC/IPC.O, you can see, these are the most important components of the kernel files. At the same time, Arch/arm/makefile has expanded the core_files:
# arch/arm/makefile# If We have a machine-specific directory and then include it in the build. Machdir         : = arch/arm/mach-$ (Machine) ifeq ($ (Machdir), $ (wildcard $ (machdir))) Subdirs         + = $ (machdir) core_files      : = $ (Machdir)/$ (machine). O $ (core_files) endifhead            : = arch/arm/kernel/head-$ (PROCESSOR). O                    arch/arm/ Kernel/init_task.osubdirs         + = Arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpecore_files      : = arch/arm/ KERNEL/KERNEL.O ARCH/ARM/MM/MM.O $ (core_files) LIBS            : = ARCH/ARM/LIB/LIB.A $ (LIBS)

5) Compile information: CPP, CC, as, LD, ar,cflags,linkflags
The general rule of compiling is defined in Rules.make, and it is necessary to specify the compiler environment specifically for the specific situation, and the compilation environment is defined in the above variables. For cross-compilation requirements, Cross_compile is defined. Like what:
Cross_compile   = arm-linux-cc              = $ (cross_compile) GCCLD              = $ (cross_compile) ld ...

Cross_compile defines the cross compiler prefix arm-linux-, which indicates that all cross-compiler tools start with arm-linux-, so before each cross-compiler tool, the $ (cross_compile) is added, To form a complete cross-compiler tool file name, such as ARM-LINUX-GCC.
CFLAGS defines the parameters passed to the C compiler.
Linkflags is the parameter used by the linker when the link is delivered to vmlinux. Linkflags are defined in Arm/*/makefile, such as:
# arch/arm/makefilelinkflags       : =-p-x-T Arch/arm/vmlinux.lds

6) configuration Variable config_*
There are many configuration variable equations in the. config file that illustrate the results of user Configuration. For example, config_modules=y indicates that the user chooses the module function of the Linux kernel.
When the. config is included in the top-level Makefile, it forms many configuration variables, each with a determined value: Y indicates that the kernel code corresponding to this compilation option is statically compiled into the Linux kernel; m means that the kernel code corresponding to this compilation option is compiled into a module; n means that the compilation option is not selected If there is no choice at all, then the value of the configuration variable is empty. 2.3 rules.make VariableAs mentioned earlier, Rules.make is a compile rule file, and all Makefile will include Rules.make. The Rules.make file defines a number of variables, most importantly those compiled, linked list variables. O_OBJS,L_OBJS,OX_OBJS,LX_OBJS: This directory needs to be compiled into the list of target files for the Linux kernel vmlinux, where the "X" in Ox_objs and LX_OBJS indicates that the destination file uses the Export_symbol output symbol. M_OBJS,MX_OBJS: The list of target files that need to be compiled into a loadable module in this directory. Similarly, the "X" in MX_OBJS indicates that the target file uses the Export_symbol output symbol. O_target,l_target: Each subdirectory has a o_target or L_target,rules.make first compile all the target files from the source code for O_OBJS and OX_OBJS, and then use the $ (LD)-R to link them to a o_ TARGET or L_target. O_target ends with. O, and L_target ends with. A. 2.4 Sub-directory MakefileSubdirectory Makefile is used to control compilation rules for the following source code in this level directory. We explain the composition of subdirectory Makefile by an example:
# # Makefile for the Linux kernel.## all of the (potential) objects that export symbols.# This list comes from ' Grep-l EXP Ort_symbol *. [HC] '. export-objs:= tc.o# Object file lists.obj-y:=obj-m:=obj-n:=obj-:=obj-$ (CONFIG_TC) + = tc.oobj-$ (Config_zs) + = zs.oobj-$ (CONFIG_VT) + = LK201.O LK201-MAP.O lk201-remap.o# Files that is both resident and Modular:remove from MODULAR.O Bj-m:= $ (Filter-out $ (obj-y), $ (obj-m)) # Translate to Rules.make lists. L_target:= tc.al_objs:= $ (Sort $ (filter-out $ (EXPORT-OBJS), $ (obj-y))) lx_objs:= $ (Sort $ (Filter     $ (EXPORT-OBJS), $ ( OBJ-Y)) m_objs:= $ (Sort $ (filter-out $ (EXPORT-OBJS), $ (obj-m))) mx_objs:= $ (Sort $ (Filter     $ (EXPORT-OBJS), $ (obj-m) )) include $ (topdir)/rules.make

A) note
The description and explanation of the Makefile begins with the #. b) Compilation target definition
A statement similar to obj-$ (CONFIG_TC) + = TC.O is used to define the target of the compilation and is the most important part of the subdirectory Makefile. The compilation target defines the list of target files in the directory that need to be compiled into the Linux kernel. In order to compile only after the user has selected this feature, all target definitions are fused to determine the configuration variable.
As mentioned earlier, each configuration variable has a value range of: Y,n,m and null, obj-$ (CONFIG_TC) corresponds to obj-y,obj-n,obj-m,obj-. If CONFIG_TC is configured as Y, then TC.O enters the obj-y list. Obj-y is the list of target files that are included in the Linux kernel vmlinux, obj-m is the list of target files compiled into modules, and the list of files in Obj-n and obj-is ignored. The configuration system compiles and links based on the properties of these lists.
The target files in Export-objs all use Export_symbol () to define the common symbols so that the Loadable module can be used. In the last section of the tc.c file, there is "Export_symbol (Search_tc_card);", indicating that TC.O has a signed output.
It should be noted here that there are two formats for the definition of a compilation target, namely, the old definition and the new definition. The old definition is the variables used in the previous Rules.make, and the new definition is obj-y,obj-m,obj-n and obj-. The Linux kernel recommends the use of a new definition, but since Rules.make does not understand the new definition, it needs to be transformed into an old-fashioned definition in the adaptation segment in Makefile. c) Adaptation segment
The role of the adaptation segment is to transform the new definition into an old-fashioned definition. In the example above, the adaptation segment is the conversion of obj-y and obj-m to Rules.make understandable l_target,l_objs,lx_objs,m_objs,mx_objs.
L_OBJS: = $ (Sort $ (filter-out $ (EXPORT-OBJS), $ (obj-y))) defines how L_OBJS is generated: Filter out obj-y (EXPORT-OBJS) in the TC.O list, then sort and remove duplicate filenames 。 Some of the special features of GNU make are used here, which can be referred to the make documentation (info make). d) include $ (topdir)/rules.make

3. Configuration file 3.1 Configuration features OverviewIn addition to Makefile writing, another important task is to add new features to the Linux configuration options, providing a description of this feature, giving users the opportunity to choose this feature. All of these require a configuration script in the Config.in file to be written in the Config language.
In the Linux kernel, there are several ways to configure commands:
Configuration commands Interpreting scripts
Make config, make Oldconfig Scripts/configure
Make Menuconfig Scripts/menuconfig
Make Xconfig Scripts/tkparse
In the case of a character interface configuration (make config), the top-level Makefile calls Scripts/configure and is configured according to Arch/arm/config.in. When the command finishes, it produces a file. config, which holds the configuration information. Next time make config will produce a new. config file, and the original. config is renamed. config.old 3.2 Configuration Language1) Top level menu
mainmenu_name/prompt//prompt/is a string surrounded by ' or ', the difference between ' and ' is ' ... ' can use the value of the reference variable. Mainmenu_name sets the name of the top-level menu, which is only displayed when make xconfig. 2) Inquiry statement
            BOOL            /prompt//symbol/        hex             /prompt//symbol//word/        int             /prompt//symbol//word/        string          /prompt//symbol//word/        tristate        /prompt//symbol/        

The query statement first displays a list of prompt/prompt/, waits for user input, and assigns the result of the input to the configuration variable represented by/symbol/. The difference between the different query statements is that they accept different input data types, such as BOOL accepts the Boolean type (Y or N), and Hex accepts 16 binary data. Some of the query statements also have a third parameter,/word/, used to give the vacancy a value. 3) Defining statements
                Define_bool     /symbol//word/        define_hex      /symbol//word/        define_int      /symbol//word/        define_ String   /symbol//word/        define_tristate/symbol//word/        

Unlike the query statement, which waits for user input, the definition statement explicitly assigns/word/to the configuration variable/symbol/. 4) Dependent statements
                Dep_bool        /prompt//symbol//dep/...        Dep_mbool       /prompt//symbol//dep/...        Dep_hex         /prompt//symbol//word//dep/...        Dep_int         /prompt//symbol//word//dep/...        Dep_string      /prompt//symbol//word//dep/...        Dep_tristate    /prompt//symbol//dep/...        

Similar to the query statement, a dependency statement defines a new configuration variable. The difference is that the value range of the configuration variable/symbol/will depend on the configuration variable list/dep/.... This means that the choice of the function that the defined configuration variable corresponds to depends on the function of the dependent list. Take Dep_bool as an example, if/dep/... All of the configuration variables of the list are value Y, then the/prompt/is displayed, and the user can enter any value to the configuration variable/symbol/, but as long as there is a configuration variable with a value of N,/symbol/is forced to n.
The difference between the different dependent statements is that they are different from the range of values produced by the dependent conditions. 5) SELECT statement
Choice          /prompt//word//word/


The choice statement first gives a list of choices for the user to select. For example, Linux for ARM supports a variety of arm core-based cpu,linux that use the choice statement to provide a list of CPUs for users to choose from:

                  Choice ' ARM system type '         "Anakin                 config_arch_anakin          archimedes/a5000       config_arch_arca5k          Cirrus-cl-ps7500fe     config_arch_clps7500         ... sa1100-based           config_arch_sa1100          Shark                  config_arch_shark "Riscpc         

Choice first displays the/prompt/, then decomposes the/word/into front and back two parts, the first part is the corresponding selection of the prompt, the latter part of the corresponding selection of configuration variables. The user chooses a configuration variable of y and the rest is N. 6) If statement
                if [/expr/]; Then          /statement/...        Fi                if [/expr/]; then          /statement/          ...        Else          /statement/...        Fi        

The IF statement determines the configuration variables (or combinations of configuration variables) and makes different processing. The criteria/expr/can be a single configuration variable or a string, or an expression with an operator. Operators are: =,!=,-o,-a and so on. 7) Menu Block statement
Mainmenu_option next_commentcomment ' ... ... endmenu

Introduce a new menu. After adding new functionality to the kernel, you need to add a new menu and configure options for this feature under the new menu. The comment after the Comment is the name of the new menu. All configuration option statements that belong to this menu are written between comment and Endmenu. 8) Source Statement
source/word/
/word/is the file name, and the function of source is to transfer the new file. 3.3 Default configurationThe Linux kernel supports very many hardware platforms, and some configurations are required for specific hardware platforms, and some configurations are not required. In addition, the normal operation of the new added function often also requires a certain prerequisite, for the new features, must be configured accordingly. As a result, a specific hardware platform is functioning correctly and corresponds to a minimal basic configuration, which is the default configuration. The Linux kernel will have a default configuration for each ARCH. After adding new functionality to the kernel code, if the new feature is required for this arch, modify the default configuration of this arch. The method of modification is as follows (under the Linux kernel root directory):
    1. Back up the. config file
    2. CP arch/arm/deconfig. config
    3. Modify the. config
    4. cp. config Arch/arm/deconfig
    5. Restore. config
If the new features apply to many of the arch, just repeat the above steps for the specific arch. 3.4 Help FileEveryone has the experience that when configuring the Linux kernel, it is possible to view its help by looking at the configuration options that do not understand the meaning, and to get suggestions for selection. Let's take a look at how to give a configuration option to add help information. The Help information for all configuration options is in Documentation/configure.help, which is in the format:
<description><variable Name>

<description> gives the name of this configuration option, <variable name> corresponding configuration variable,

4. Instance for a developer, it takes three steps to add the kernel code that you have developed to the Linux kernel. First determine the location of your own development code into the kernel, and secondly, add your own development capabilities to the Linux kernel configuration options, so that users can choose this feature, and finally, build a subdirectory Makefile, according to the user's choice, the corresponding code compiled into the final generated Linux kernel. Below, we'll show you how to add new functionality to the Linux kernel with a simple example--test driver, combined with the knowledge we learned earlier. 4.1 directory StructureTest driver is placed under the drivers/test/directory:
$CD drivers/test$tree.| --config.in|--makefile|--cpu|   | --makefile|   '--cpu.c|--test.c|--test_client.c|--test_ioctl.c|--test_proc.c|--test_queue.c '--Test    |--Makefile    '-- TEST.c    

4.2 Configuration Files1) drivers/test/config.in
# test driver configuration#mainmenu_option next_commentcomment ' test driver ' bool ' test support ' config_testif ["$CONFI G_test "=" Y "]; Then  tristate ' Test User-space interface ' config_test_user  bool ' Test CPU ' Config_test_cpufiendmenu

Because test driver is a new feature for the kernel, first create a menu test driver. Then, display "test support", waiting for the user to choose, then determine whether the user selected TEST Driver, if it is (config_test=y), then further display sub-function: User interface and CPU function support, because the user interface function can be compiled into a kernel module, So the query statement here uses TriState (because TriState's range of values includes Y, N, and M,m, which corresponds to the module). 2) arch/arm/config.in
At the end of the file join: source drivers/test/config.in, the configuration of the test Driver sub-function is incorporated into the configuration of the Linux kernel. 4.3 Makefile1) drivers/test/makefile
        #       drivers/test/makefile##       Makefile for the test. #SUB_DIRS     : =mod_sub_dirs: = $ (sub_dirs) All_sub_dirs: = $ ( Sub_dirs) Cpul_target: = Test.aexport-objs: = TEST.O test_client.oobj-$ (config_test)              + = TEST.O test_queue.o test_ client.oobj-$ (config_test_user)         + = test_ioctl.oobj-$ (config_proc_fs)           + = test_proc.osubdir-$ (CONFIG_TEST_ CPU)       + = Cpuinclude $ (topdir)/rules.makeclean: For        dir in $ (all_sub_dirs), do make-c $ $dir clean;        *. [OA]. *.flags        

The final generated target file under the Drivers/test directory is test.a. Export_symbol output symbols are used in test.c and test-client.c, so TEST.O and TEST-CLIENT.O are located in the Export-objs list. Then, depending on the user's choice (specifically, the value of the configuration variable), the corresponding obj-* list is built. Because a subdirectory CPU is wrapped in TEST Driver, when Config_test_cpu=y (that is, the user chooses this feature), the CPU directory needs to be added to the Subdir-y list. 2) Drivers/test/cpu/makefile
        #       drivers/test/test/makefile##       Makefile for the test CPU #SUB_DIRS     : =mod_sub_dirs: = $ (sub_dirs) all_sub_ DIRS: = $ (sub_dirs) L_target: = test_cpu.aobj-$ (config_test_cpu)       + = Cpu.oinclude $ (topdir)/rules.makeclean:        Rm-f *. [OA]. *.flags        

3) Drivers/makefile
... subdir-$ (config_test) + = Test......include $ (topdir)/rules.make

Adding subdir-$ (config_test) + = Test in drivers/makefile allows the kernel to enter the test directory after the user chooses the test Driver function. 4) Makefile
...... drivers-$ (CONFIG_PLD) + = drivers/pld/pld.odrivers-$ (config_test) + = drivers/test/test.adrivers-$ (CONFIG_TEST_CPU) + = Drivers/test/cpu/test_cpu.adrivers: = $ (drivers-y) ...

Add drivers-$ (config_test) + drivers/test/test.a and drivers-$ (config_test_cpu) + = Drivers/test/cpu/test_ in the top-level Makefile Cpu.a. How the user selects TEST Driver, then both Config_test and CONFIG_TEST_CPU are both Y,TEST.A and test_cpu.a in the Drivers-y list and then placed in the DRIVERS list. As mentioned earlier, the composition of the Linux kernel file vmlinux includes DRIVERS, so test.a and TEST_CPU.A can eventually be linked to Vmlinux.

Linux Source makefile detailed (complete)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.