Monday, April 10, 2017

Kernel build


1.Make module

make -C $KDIR M=`pwd` modules
build an external module
make -C $KDIR M=`pwd` modules_install
default in /lib/modules/<kernel-version>/extra
make -C $KDIR M=$PWD clean
remove all generated files for the module
config MODVERSIONS
         bool "Set version information on all module symbols"
         depends MODULES
         help
           Usually, modules have to be recompiled whenever you switch to a new
           kernel.  ...
config
starts a new config entry
type definition
bool "/"tristate"/"string"/"hex"/"int
input prompt
"prompt" <prompt> ["if" <expr>]
default value
"default" <expr> ["if" <expr>]
dependencies
"depends on"/"requires" <expr>
reverse dependencies
"select" <symbol> ["if" <expr>]
numerical ranges
"range" <symbol> <symbol> ["if" <expr>]
help text
"help" or "---help---"
<expr> ::= <symbol>                       (1)
         <symbol> '=' <symbol>            (2)
         <symbol> '!=' <symbol>           (3)
         '(' <expr> ')'                     (4)
         '!' <expr>                       (5)
         <expr> '&&' <expr>              (6)
         <expr> '||' <expr>                (7)
(1) Convert the symbol into an expression. Boolean and tristate symbols are simply converted into the respective expression values. All other symbol types result in 'n'.
(2) If the values of both symbols are equal, it returns 'y', otherwise 'n'.
(3) If the values of both symbols are equal, it returns 'n', otherwise 'y'.
(4) Returns the value of the expression. Used to override precedence.
(5) Returns the result of (2-/expr/).
(6) Returns the result of min (/expr/, /expr/).
(7) Returns the result of max (/expr/, /expr/).
An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 respectively for calculations). A menu entry becomes visible when it's expression evaluates to 'm' or 'y'.
The Makefiles have five parts:
Makefile
top Makefile(build vmlinux&modules by descending into subdir)
.config
kernel configuration file
arch/$(ARCH)/Makefile
arch Makefile(supplies architecture-specific information)
scripts/Makefile.*
definitions/rules etc. for all kbuild Makefiles
kbuild Makefiles
which carries out the commands passed down from above
*Arch developers* are people who work on an entire architecture, such as sparc or arm. Arch developers need to know about the arch Makefile as well as kbuild Makefiles.

2.The kbuild files

Example: obj-y += foo.o
This tell kbuild there is one object in that directory named foo.o. foo.o will be built from foo.c or foo.S.
Example: obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module). If CONFIG_FOO is neither y nor m, then the file will not be compiled nor linked.
Kbuild compiles all the $(obj-y) files. It then calls "$(LD) -r" to merge these files into one built-in.o file. built-in.o is later linked into vmlinux by the parent Makefile. $(obj-m) specify object files which are built as loadable kernel modules. A module may be built from one source file or several source files. In the case of one source file, the kbuild makefile simply adds the file to $(obj-m).
Objects listed with obj-* are used for modules or combined in a built-in.o for that specific directory. There is also the possibility to list objects that will be included in a library, lib.a. All objects listed with lib-y are combined in a single   library for that directory.
A Makefile is only responsible for building objects in its own directory. Files in subdirectories should be taken care of by Makefiles in these subdirs. The build system will automatically invoke make recursively in subdirectories, provided you let it know of them.
Example: obj-$(CONFIG_EXT2_FS) += ext2/
If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular) the corresponding obj- variable will be set, and kbuild will descend down in the ext2 directory. Kbuild only uses this information to decide that it needs to visit the directory, it is the Makefile in the subdirectory that specifies what is modules and what is built-in.
All the EXTRA_ variables apply only to the kbuild makefile where they are assigned. The EXTRA_ variables apply to all commands executed in the kbuild makefile.
To do so arch/$(ARCH)/Makefile sets a number of variables, and defines a few targets.
When kbuild executes the following steps are followed (roughly):
1) Configuration of the kernel => produced .config
2) Store kernel version in include/linux/version.h
3) Symlink include/asm to include/asm-$(ARCH)
4) Updating all other prerequisites to target: prerequisites are specified in arch/$(ARCH)/Makefile
5) Recursively descend down in all directories listed in init-* core* drivers-* net-* libs-* and build all targets. The value of the above variables are extended in arch/$(ARCH)/Makefile.
6) All object files are then linked and the resulting file vmlinux is located at the root of the src tree.    The very first objects linked are listed in head-y, assigned by arch/$(ARCH)/Makefile.
7) Finally architecture specific part does any required post processing and builds final bootimage.
The top Makefile exports the following variables:
VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION

These variables define the current kernel version. A few arch Makefiles actually use these values directly; they should use $(KERNELRELEASE) instead.

$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic three-part version number, such as "2", "4", and "0".  These three values are always numeric.

$(EXTRAVERSION) defines an even tinier sublevel for pre-patches or additional patches. It is usually some non-numeric string such as "-pre4", and is often blank.

$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable for constructing installation directory names or showing in version strings. Some arch Makefiles use it for this purpose.

$(ARCH) defines the target architecture, such as "i386", "arm", or "sparc". Some kbuild Makefiles test $(ARCH) to determine which files to compile. By default, the top Makefile sets $(ARCH) to be the same as the host system architecture. For a cross build, a user may override the value of $(ARCH) on the command line: make ARCH=arm

$(INSTALL_PATH) defines a place for the arch Makefiles to install the resident kernel image and System.map file. Use this for architecture specific install targets.

$(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module installation. This variable is not defined in the Makefile but may be passed in by the user if desired.

$(MODLIB) specifies the directory for module installation. The top Makefile defines $(MODLIB) to $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE).  The user may override this value on the command line if desired.

GNU Make has two assignment operators, ":=" and "=".

":=" performs immediate evaluation of the right-hand side and stores an actual string into the left-hand side.

"=" is like a formula definition; it stores the right-hand side in an unevaluated form and then evaluates this form each time the left-hand side is used.


There are some cases where "=" is appropriate.  Usually, though, ":=" is the right choice.

No comments:

Post a Comment