- Compile kernel module
- Build environment
- Traditional compilation
- Arch Build System
- Source configuration
- Module compilation
- out-of-tree module compilation
- Module installation
- possible errors
- Building External ModulesВ¶
- 1. IntroductionВ¶
- 2. How to Build External ModulesВ¶
- 2.1 Command SyntaxВ¶
- 2.2 OptionsВ¶
- 2.3 TargetsВ¶
- 2.4 Building Separate FilesВ¶
- 3. Creating a Kbuild File for an External ModuleВ¶
- 3.1 Shared MakefileВ¶
- 3.2 Separate Kbuild File and MakefileВ¶
- 3.3 Binary BlobsВ¶
- 3.4 Building Multiple ModulesВ¶
- 4. Include FilesВ¶
- 4.1 Kernel IncludesВ¶
- 4.2 Single SubdirectoryВ¶
- 4.3 Several SubdirectoriesВ¶
- 5. Module InstallationВ¶
- 5.1 INSTALL_MOD_PATHВ¶
- 5.2 INSTALL_MOD_DIRВ¶
- 6. Module VersioningВ¶
- 6.1 Symbols From the Kernel (vmlinux + modules)В¶
- 6.2 Symbols and External ModulesВ¶
- 6.3 Symbols From Another External ModuleВ¶
- 7. Tips & TricksВ¶
- 7.1 Testing for CONFIG_FOO_BARВ¶
Compile kernel module
Sometimes you may wish to compile Linux’s Kernel module without recompiling the whole kernel.
Firstly you will need to install build dependencies such as a compiler ( base-devel ) and linux-headers .
Next you will need to get the source code for the kernel version the module is intended to run on. You may try using newer kernel sources but most likely the compiled module will not load.
In case the intended kernel version is the installed kernel, find its version with
There are two main options to acquire the required source. Each option has slightly different usage methods and directory structure.
See Kernels/Traditional compilation#Download the kernel source. If you fetch latest source using Git you will need to checkout needed version using tag (eg. v4.1).
Arch Build System
For a general overview on Arch Build System read ABS. See Kernel/Arch Build System for acquiring the kernel source, as well as the directory structure, and other details.
When you have the source code, enter its directory. For the #Arch Build System case, that directory would be src/archlinux-linux/ down from where the PKGBUILD is.
The output from make help is beneficial here. Start by cleaning with
An appropriate .config file is now required. If none is nearby, perhaps from a saved .config , and the intended kernel version is the running kernel, you can use its configuration file:
Next ensure the .config file is adjusted for the kernel version. If you are using kernel sources for the exact current version then it should not ask anything. But for another version than the current kernel you might be asked about some options. In any case, for the #Arch Build System option, you might want to examine the PKGBUILD::prepare() function.
If the module you want to compile have some compilation options such as debug build, or it was not compiled before, you can also, possibly must, adjust the kernel configuration. You can do this with one of the many configuration targets mentioned by make help.
In order to compile and load our module cleanly, we must find the value of the EXTRAVERSION component of the current kernel version number so we can match the version number exactly in our kernel source. EXTRAVERSION is a variable set in the kernel top-level Makefile, but the Makefile in a vanilla kernel source will have EXTRAVERSION empty; it is set only as part of the Arch kernel build process. If relevant, the value of the current kernel’s EXTRAVERSION can be found by looking at the output of the uname -r command. In general, the kernel version is the concatenation of three components. Namely, the numeric version, the EXTRAVERSION, and the LOCALVERSION. The numeric version itself is a concatenation of three numbers. If built by a PKGBUILD file, the LOCALVERSION will be taken from the pkgrel variable, prefixed by a hyphen. And the EXTRAVERSION will be the suffix of the pkgver variable, where the period character to the right of the third numeric number of the numeric version is replaced by a hyphen. For example, with the linux package linux 5.5.8.arch1-1 , the LOCALVERSION is -1 . The EXTRAVERSION is -arch1 . The output of uname -r will be 5.5.8-arch1-1 in that example.
Once the EXTRAVERSION value is known, we prepare the source for module compilation:
Alternatively, if you are happy to load modules with modprobe using the —force-vermagic option to ignore mismatches in the kernel version number, you can simply run:
Finally, compile wanted module by specifying its directory name. You can find the module location, thus also its directory name, with modinfo or find.
As a last resort, if nothing else has worked, you can
Which will build all the modules from the kernel configuration.
out-of-tree module compilation
get the official source code of the current running linux kernel as described in Kernel/Arch Build System:
then point to the checked out source when compiling the module:
Now after successful compilation you just need to gzip and copy it over for your current kernel.
If you are replacing some existing module you will need to overwrite it (and remember that reinstalling linux will replace it with default module)
Or alternatively, you can place the updated module in the updates folder (create it if it does not already exist).
However if you are adding a new module you can just copy it to extramodules (note, this is just example as btrfs will not get loaded from here)
You need to rebuild the module dependency tree with «depmod» to use installed modules.
If you are compiling a module for early boot (e.g. updated module) which is copied to Initramfs then you must remember to regenerate it with (otherwise your compiled module will not be loaded).
If EXTRAVERSION is not set correctly the following errors may occur
adding force-vermagic makes it ignore the version mismatch
Building External ModulesВ¶
This document describes how to build an out-of-tree kernel module.
вЂњkbuildвЂќ is the build system used by the Linux kernel. Modules must use kbuild to stay compatible with changes in the build infrastructure and to pick up the right flags to вЂњgcc.вЂќ Functionality for building modules both in-tree and out-of-tree is provided. The method for building either is similar, and all modules are initially developed and built out-of-tree.
Covered in this document is information aimed at developers interested in building out-of-tree (or вЂњexternalвЂќ) modules. The author of an external module should supply a makefile that hides most of the complexity, so one only has to type вЂњmakeвЂќ to build the module. This is easily accomplished, and a complete example will be presented in section 3.
2. How to Build External ModulesВ¶
To build external modules, you must have a prebuilt kernel available that contains the configuration and header files used in the build. Also, the kernel must have been built with modules enabled. If you are using a distribution kernel, there will be a package for the kernel you are running provided by your distribution.
An alternative is to use the вЂњmakeвЂќ target вЂњmodules_prepare.вЂќ This will make sure the kernel contains the information required. The target exists solely as a simple way to prepare a kernel source tree for building external modules.
NOTE: вЂњmodules_prepareвЂќ will not build Module.symvers even if CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be executed to make module versioning work.
2.1 Command SyntaxВ¶
The command to build an external module is:
The kbuild system knows that an external module is being built due to the вЂњM= вЂќ option given in the command.
To build against the running kernel use:
Then to install the module(s) just built, add the target вЂњmodules_installвЂќ to the command:
($KDIR refers to the path of the kernel source directory.)
make -C $KDIR M=$PWD
The directory where the kernel source is located. вЂњmakeвЂќ will actually change to the specified directory when executing and will change back when finished.
Informs kbuild that an external module is being built. The value given to вЂњMвЂќ is the absolute path of the directory where the external module (kbuild file) is located.
When building an external module, only a subset of the вЂњmakeвЂќ targets are available.
make -C $KDIR M=$PWD [target]
The default will build the module(s) located in the current directory, so a target does not need to be specified. All output files will also be generated in this directory. No attempts are made to update the kernel source, and it is a precondition that a successful вЂњmakeвЂќ has been executed for the kernel.
The default target for external modules. It has the same functionality as if no target was specified. See description above.
Install the external module(s). The default location is /lib/modules/ /extra/, but a prefix may be added with INSTALL_MOD_PATH (discussed in section 5).
Remove all generated files in the module directory only.
List the available targets for external modules.
2.4 Building Separate FilesВ¶
It is possible to build single files that are part of a module. This works equally well for the kernel, a module, and even for external modules.
Example (The module foo.ko, consist of bar.o and baz.o):
3. Creating a Kbuild File for an External ModuleВ¶
In the last section we saw the command to build a module for the running kernel. The module is not actually built, however, because a build file is required. Contained in this file will be the name of the module(s) being built, along with the list of requisite source files. The file may be as simple as a single line:
The kbuild system will build .o from .c, and, after linking, will result in the kernel module .ko. The above line can be put in either a вЂњKbuildвЂќ file or a вЂњMakefile.вЂќ When the module is built from multiple sources, an additional line is needed listing the files:
NOTE: Further documentation describing the syntax used by kbuild is located in Linux Kernel Makefiles .
The examples below demonstrate how to create a build file for the module 8123.ko, which is built from the following files:
3.1 Shared MakefileВ¶
An external module always includes a wrapper makefile that supports building the module using вЂњmakeвЂќ with no arguments. This target is not used by kbuild; it is only for convenience. Additional functionality, such as test targets, can be included but should be filtered out from kbuild due to possible name clashes.
The check for KERNELRELEASE is used to separate the two parts of the makefile. In the example, kbuild will only see the two assignments, whereas вЂњmakeвЂќ will see everything except these two assignments. This is due to two passes made on the file: the first pass is by the вЂњmakeвЂќ instance run on the command line; the second pass is by the kbuild system, which is initiated by the parameterized вЂњmakeвЂќ in the default target.
3.2 Separate Kbuild File and MakefileВ¶
In newer versions of the kernel, kbuild will first look for a file named вЂњKbuild,вЂќ and only if that is not found, will it then look for a makefile. Utilizing a вЂњKbuildвЂќ file allows us to split up the makefile from example 1 into two files:
The split in example 2 is questionable due to the simplicity of each file; however, some external modules use makefiles consisting of several hundred lines, and here it really pays off to separate the kbuild part from the rest.
The next example shows a backward compatible version.
Here the вЂњKbuildвЂќ file is included from the makefile. This allows an older version of kbuild, which only knows of makefiles, to be used when the вЂњmakeвЂќ and kbuild parts are split into separate files.
3.3 Binary BlobsВ¶
Some external modules need to include an object file as a blob. kbuild has support for this, but requires the blob file to be named _shipped. When the kbuild rules kick in, a copy of _shipped is created with _shipped stripped off, giving us . This shortened filename can be used in the assignment to the module.
Throughout this section, 8123_bin.o_shipped has been used to build the kernel module 8123.ko; it has been included as 8123_bin.o:
Although there is no distinction between the ordinary source files and the binary file, kbuild will pick up different rules when creating the object file for the module.
3.4 Building Multiple ModulesВ¶
kbuild supports building multiple modules with a single build file. For example, if you wanted to build two modules, foo.ko and bar.ko, the kbuild lines would be:
It is that simple!
4. Include FilesВ¶
Within the kernel, header files are kept in standard locations according to the following rule:
If the header file only describes the internal interface of a module, then the file is placed in the same directory as the source files.
If the header file describes an interface used by other parts of the kernel that are located in different directories, then the file is placed in include/linux/.
There are two notable exceptions to this rule: larger subsystems have their own directory under include/, such as include/scsi; and architecture specific headers are located under arch/$(SRCARCH)/include/.
4.1 Kernel IncludesВ¶
To include a header file located under include/linux/, simply use:
kbuild will add options to вЂњgccвЂќ so the relevant directories are searched.
4.2 Single SubdirectoryВ¶
External modules tend to place header files in a separate include/ directory where their source is located, although this is not the usual kernel style. To inform kbuild of the directory, use either ccflags-y or CFLAGS_ .o.
Using the example from section 3, if we moved 8123_if.h to a subdirectory named include, the resulting kbuild file would look like:
Note that in the assignment there is no space between -I and the path. This is a limitation of kbuild: there must be no space present.
4.3 Several SubdirectoriesВ¶
kbuild can handle files that are spread over several directories. Consider the following example:
To build the module complex.ko, we then need the following kbuild file:
As you can see, kbuild knows how to handle object files located in other directories. The trick is to specify the directory relative to the kbuild fileвЂ™s location. That being said, this is NOT recommended practice.
For the header files, kbuild must be explicitly told where to look. When kbuild executes, the current directory is always the root of the kernel tree (the argument to вЂњ-CвЂќ) and therefore an absolute path is needed. $(src) provides the absolute path by pointing to the directory where the currently executing kbuild file is located.
5. Module InstallationВ¶
Modules which are included in the kernel are installed in the directory:
And external modules are installed in:
Above are the default directories but as always some level of customization is possible. A prefix can be added to the installation path using the variable INSTALL_MOD_PATH:
INSTALL_MOD_PATH may be set as an ordinary shell variable or, as shown above, can be specified on the command line when calling вЂњmake.вЂќ This has effect when installing both in-tree and out-of-tree modules.
External modules are by default installed to a directory under /lib/modules/$(KERNELRELEASE)/extra/, but you may wish to locate modules for a specific functionality in a separate directory. For this purpose, use INSTALL_MOD_DIR to specify an alternative name to вЂњextra.вЂќ:
6. Module VersioningВ¶
Module versioning is enabled by the CONFIG_MODVERSIONS tag, and is used as a simple ABI consistency check. A CRC value of the full prototype for an exported symbol is created. When a module is loaded/used, the CRC values contained in the kernel are compared with similar values in the module; if they are not equal, the kernel refuses to load the module.
Module.symvers contains a list of all exported symbols from a kernel build.
6.1 Symbols From the Kernel (vmlinux + modules)В¶
During a kernel build, a file named Module.symvers will be generated. Module.symvers contains all exported symbols from the kernel and compiled modules. For each symbol, the corresponding CRC value is also stored.
The syntax of the Module.symvers file is:
The fields are separated by tabs and values may be empty (e.g. if no namespace is defined for an exported symbol).
For a kernel build without CONFIG_MODVERSIONS enabled, the CRC would read 0x00000000.
Module.symvers serves two purposes:
It lists all exported symbols from vmlinux and all modules.
It lists the CRC if CONFIG_MODVERSIONS is enabled.
6.2 Symbols and External ModulesВ¶
When building an external module, the build system needs access to the symbols from the kernel to check if all external symbols are defined. This is done in the MODPOST step. modpost obtains the symbols by reading Module.symvers from the kernel source tree. During the MODPOST step, a new Module.symvers file will be written containing all exported symbols from that external module.
6.3 Symbols From Another External ModuleВ¶
Sometimes, an external module uses exported symbols from another external module. Kbuild needs to have full knowledge of all symbols to avoid spitting out warnings about undefined symbols. Two solutions exist for this situation.
NOTE: The method with a top-level kbuild file is recommended but may be impractical in certain situations.
Use a top-level kbuild file
If you have two modules, foo.ko and bar.ko, where foo.ko needs symbols from bar.ko, you can use a common top-level kbuild file so both modules are compiled in the same build. Consider the following directory layout:
The top-level kbuild file would then look like:
will then do the expected and compile both modules with full knowledge of symbols from either module.
Use вЂњmakeвЂќ variable KBUILD_EXTRA_SYMBOLS
If it is impractical to add a top-level kbuild file, you can assign a space separated list of files to KBUILD_EXTRA_SYMBOLS in your build file. These files will be loaded by modpost during the initialization of its symbol tables.
7. Tips & TricksВ¶
7.1 Testing for CONFIG_FOO_BARВ¶
Modules often need to check for certain CONFIG_ options to decide if a specific feature is included in the module. In kbuild this is done by referencing the CONFIG_ variable directly:
External modules have traditionally used вЂњgrepвЂќ to check for specific CONFIG_ settings directly in .config. This usage is broken. As introduced before, external modules should use kbuild for building and can therefore use the same methods as in-tree modules when testing for CONFIG_ definitions.
© Copyright The kernel development community.