Linux Kernel build system seven __linux

Source: Internet
Author: User
Tags function prototype

Turn from: http://www.juliantec.info/julblog/yihect/linux-kernel-build-system-7

From the previous analysis, we already know that in Linux, there are two types of modules: internal modules and external modules. What we're saying here about target modules is to compile those internal modules, and the processing of the external modules will be described later. We also know that both internal and external modules are compiled in two phases. Stages of life into modules of the corresponding. o files and. mod files, phase Two will use Scripts/mod/modpost to generate the. mod.c file and compile it into a. mod.o object file, and finally. MOD.O is linked to the. Ko module file along with the preceding. O. In addition, we know that in the process of generating vmlinux, a modules.symvers is generated in the top-level directory of the kernel, containing the symbols and CRC checksums that are exported by the base kernel for use by the module. The knowledge gained through the previous discussion may not be quite clear to you, it's okay, we'll go deep into the discussion of the internal module goal modules, which will give you a clearer idea.

OK, first in the top-level Makefile (the E1 part of the frame) to find the rule to handle the modules target:

All:modules
# Build       modules
#       A module can is listed more than once in obj-m resulting >#       Duplicate lines in modules.order files.  Those are removed
#       using awk while concatenating to the final file.
Phony + + Modules
Modules: $ (vmlinux-dirs) $ (if $ (kbuild_builtin), Vmlinux) $
        (Q) $ (AWK) '!x[$$0]++ ' $ ( vmlinux-dirs:%=$ (Objtree)/%/modules.order) > $ (objtree)/modules.order @$
        (kecho) '  building modules, Stage 2. ';
        $ (q) $ (make)-F $ (Srctree)/scripts/makefile.modpost
        $ (q) $ (make)-F $ (srctree)/scripts/makefile.fwinst obj= Firmware __fw_modbuild

The above shows that the modules target is dependent on $ (vmlinux-dirs). This dependency means that the first phase of internal module processing is already done in the process of processing vmlinux-dirs. The previous discussion of Vmlinux-dirs also said how to compile those. O object files that make up the module, and how to generate. mod files.

Obviously, since the first phase of the internal module has been completed, the command part that handles the modules goal rule is to complete the second phase of the internal module.

The first line in the command section uses an awk call to collect the contents of the Modules.order files in each subdirectory into the Modules.order file in the top-level directory. This file lists the order in which the build system builds the internal modules. If you study in depth, you will know that package Module-init-tools contains a tool: Depmod. The tool resolves the dependencies of each kernel module, and it saves dependencies in the file MODULES.DEP. The so-called dependencies between modules, for example, the code for module A uses the functions derived from module B, so we say that module A is dependent on module B. Obviously, since there is a dependency between modules, the loading order between the modules must be well defined. As in our example, module B must be loaded before module A is loaded, or there will be an error. The old version of Depmod is simply dependent on internal modules to determine the order in which the internal modules are loaded. But the first version of Depmod also takes into account the order in which the kernel build system builds each kernel module. For more modules.orders use information, you can refer to the contents of the Kernel development mailing list, where you can see: http://lkml.org/lkml/2007/12/7/96. Alternatively, you can view the Module-init-tools package Git's revision history:

http://git.kernel.org/?p=utils/kernel/module-init-tools/module-init-tools.git&a=search&h=HEAD&st= Commit&s=modules.order

The key in the above command section is the next line: $ (Q) $ (make)-F $ (srctree)/scripts/makefile.modpost. Because the command does not specify the target of make, it builds the default target _modpost in Makefile.modpost. In the same file, look at the rules for _modpost:

Phony: = _modpost
_modpost: __modpost
...
# Stop after building. o files if nofinal is set. Makes compile tests quicker
_modpost: $ (if $ (kbuild_modpost_nofinal), $ (MODULES:.KO:.O), $ (modules))

The code above shows that _modpost relies on __modpost. Also, if a kbuild_modpost_nofinal is defined, it depends on the. o file that corresponds to the module name. For example, if you have two object files part1.o and part2.o that make up a module Mymodule.ko, then it relies on MYMODULE.O object files. In addition, if not defined, it also relies on all internal modules. So the definition of variable kbuild_modpost_nofinal means we just generate MYMODULE.O, instead of continuing to generate Mymodule.ko modules from MYMODULE.O. The variable modules is defined as this:

# step 1, find all modules listed in $ (modverdir)/
__modules: = $ (sort $ (Shell grep-h ' \.ko '/dev/null $ (wildcard $) ( Modverdir)/*.mod))
modules   : = $ (Patsubst%.o,%.ko, $ (wildcard $ (__MODULES:.KO=.O)))
 

This definition uses grep to search for all the *.mod files in the directory $ (modverdir)/, and to find the lines that contain the module file name suffix. ko. The effect is equivalent to finding all the internal module names, and composing the list to modules. You remember. As mentioned earlier, the directory $ (modverdir) is .../.tmp_version/, which contains all the. mod files generated in the first phase of the module processing.

Let's go back and take a look at the __modpost target, find the code as follows:

Phony + + __modpost
__modpost: $ (MODULES:.KO=.O) FORCE
        $ (call Cmd,modpost) $ (wildcard Vmlinux) $ (filter-out force,$^)
        $ (Q) echo ' cmd_$@: = (call Cmd,modpost) $ (wildcard Vmlinux) $ (filter-out force,$^) ' > $ (@D)/.$ (@F). cmd

Looking closely at the command section of the rule, it calls the cmd_modpost, and we look at its definition:

# step 2, Invoke Modpost
#  Includes step 3,4
modpost = scripts/mod/modpost                    \
 $ (if $ (config_ modversions),-m)                  \
 $ (if $ (config_module_srcversion_all),-A,)       \
 $ (if $ (kbuild_extmod),-i,-o) $ ( kernelsymfile)   \
 $ (if $ (kbuild_extmod), I $ (modulesymfile))      \
 $ (if $ (kbuild_extra_symbols), $ ( Patsubst%,-e%,$ (kbuild_extra_symbols)) \
 $ (if $ (kbuild_extmod),-O $ (modulesymfile))      \
 $ (if $ ( Config_debug_section_mismatch),,-S)      \
 $ (if $ (config_markers), K $ (kernelmarkersfile)) \
 $ (if $ ( Config_markers), M $ (markersfile))       \
 $ (if $ (kbuild_extmod) $ (Kbuild_modpost_warn), W) \
 $ (if $ (cross _build),-c)
quiet_cmd_modpost = Modpost $ (words $ (filter-out vmlinux, FORCE)) $^
      modules = $ (modpost)-S

Déjà vu, right. Yes, when we discussed VMLINUX.O's handling earlier, we already ran into the tool program .../scripts/mod/modpost. However, it was used at that time as variable cmd_kernel-mod rather than cmd_modpost. At that time, the build system was used to complete two actions: Mis-match section checking and generating the basic kernel export symbol file Module.symvers, which contains all the symbols and CRC checksums exported by the base kernel. What is the purpose of this call here?/scripts/mod/modpost. Let's first look at how the Modpost tool is invoked.

Because of our configuration (s3c2410_defcofig), there is no set Config_modversions,config_module_srcversion_all,config_debug_section_mismatch and Config_markers. At the same time we are not setting kbuild_extra_symbols, and we are currently working on the second phase of the internal module, so the commands in the __modpost rule above are actually:

Scripts/mod/modpost-o/home/yihect/linux-2.6.31/module.symvers-s-c-s vmlinux mymodule.o YouModule.o ....

The latter part of the command, which includes an ellipsis, represents an. o file that corresponds to each internal module name. This command is mainly to accomplish two tasks here:

A to parse out the symbols within the vmlinux and the corresponding. o files, and re-write them to the file modules.symvers in the top-level directory, along with their respective CRC checksums. Therefore, the final document not only contains the basic kernel of the symbol and CRC check, but also includes the internal modules derived from the symbol and CRC checksum, in the results of the previous processing VMLINUX.O generated by the modules.symvers superset;

b) For each internal module, generate the corresponding *.MOD.C file. The code that generates the *.MOD.C file is in the main function of the modpost.c file:

int main (int argc, char **argv)
{
        struct module *mod;
        struct buffer buf = {};
        //......
        for (mod = modules mod; mod = mod->next) {
                char Fname[strlen (mod->name) +];
                if (Mod->skip)
                        continue;
                Buf.pos = 0;
                add_header (&buf, mod);
                Add_staging_flag (&buf, mod->name);
                Err |= add_versions (&buf, mod);
                Add_depends (&BUF, mod, modules);
                Add_moddevtable (&buf, mod);
                Add_srcversion (&buf, mod);
                sprintf (fname, "%S.MOD.C", mod->name);
                Write_if_changed (&buf, fname);
        }
        //.......
        return err;
}

The specific generated code is distributed among the different add_* functions, and we do not elaborate on them here because they are beyond the scope of this topic. You can view the code yourself and participate in our discussion in the mail list. Here we look at the contents of the *.MOD.C file it generates, and we take the module Cfg80211.ko under/net/wireless/as an example (because S3c2410_defconfig's default configuration sets the variable config_cfg80211 to M, Therefore, according to the contents of the Makefile, the building system will generate module CFG80211.KO. To complete the description of the contents of the *.mod.c file, we have deliberately modified the .../.config configuration file to set the Config_modversions and Config_module_srcversion_all two variables to Y. That is, the module versioning function of the kernel is turned on. We list the contents of the document CFG80211.MOD.C (with exclusions):

Most of the code for this file is to define variables and place them in three different elf sections (the following build system compiles this. MOD.C Form object file, link into. ko):

A to define the struct module structure variable __this_module and place it in the. Gnu.linkonce.this_module section. When the module is loaded into the running kernel, the kernel is responsible for adding the object to the internal modules list. Modules list is a two-way list of kernel maintenance for all loaded modules (see: HTTP://LKML.ORG/LKML/2002/12/27/16).

b) defines an array of struct modversion_info structures ____versions and places them in the __versions Sectiong. The array holds all the symbols used in the module, but not defined, that is, the so-called unresolved symbol, either defined in the basic kernel or defined in other modules, which the kernel uses to make a module versioning. Note the module_layout symbol, which is a dummy symbol. The kernel uses it to track changes in the relevant data structures for module processing in different kernel versions. When a module is compiled in a version of the kernel and loaded in another B-version kernel, the kernel refuses to continue to do other module versioning work, which is to reject the module, if the definition of the data structures that handle modules in the two cores changes.

The symbol module_layout is defined as a function in the file .../kernel/module.c:

#ifdef config_modversions/
* Generate the signature for all relevant module structures here.
 * If These change, we don ' t want to try to parse the module. * *
void module_layout (struct module *mod,
                   struct modversion_info *ver
                   ,
                   struct Kernel_param *kp, struct Kernel_symbol *ks,
                   struct marker *marker,
                   struct tracepoint *tp)
{
}
Export_symbol ( Module_layout);
#endif

The function body is empty, but there are many parameter types. Why. This is because the kernel uses it to track structural changes such as module/modversion_info/kernel_param/kernel_symbol/marker/tracepoint. So how do you track this change? The kernel, like any other symbol, uses this function prototype to do a CRC checksum, generating a checksum. Place it in the __versions section as *.MOD.C, and when the module is loaded, compare it to the CRC stored in the running kernel, and, if different, refuse to load the module further. When the module is loaded, the kernel's check code for this item is .../kernel/module.c, as follows:

static inline int check_modstruct_version (ELF_SHDR *sechdrs,
                                          unsigned int versindex,
                                          struct module *mod)
{ 
        const unsigned long *CRC;
        if (!find_symbol (module_symbol_prefix "Module_layout", NULL,
                         &CRC, True, false))
                BUG ();
        Return Check_version (Sechdrs, Versindex, "Module_layout", MoD, CRC);
}

function Check_version do a real check, check does not pass, the kernel will report a well-known error message: Disagrees about version of symbol Module_layout.

b in the end,. MOD.C will cram a lot of information into the. Modinfo section, including: Vermagic string, module dependency information, srcversion information, etc. (and much more). We use Vermagic to illustrate the analysis.

Macro Module_info defined in .../include/linux/module.h:

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.