Build the Linux kernel from source¶
Get the Linux kernel source code¶
The source code for the Linux kernel consists of a set of directories and files, known as the kernel source tree, that will be configured and compiled to create the final kernel image in binary format.
Preparing a working directory¶
In order to compile the source code, first create a working directory to have a clean environment where to download the Linux source code and work inside.
$ mkdir linux
$ cd linux
Tip
You do not need to be root user or use sudo to compile the kernel. These privileges are only required to install the kernel image, later in the process.
Obtain the Linux kernel source tree¶
Download the preferred kernel release from https://www.kernel.org. For example, to get the long term stable release 4.19.91, issue:
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.14.91.tar.xz
Any other method to get the compressed tarball into the directory is right provided that, once obtained, you can uncompress the kernel source:
$ tar xvf linux-4.14.91.tar.xz
After uncompressing, enter into the main directory to work with the kernel source:
$ cd linux-4.14.91
Configure the Linux kernel¶
Before compiling the kernel a few steps are needed to set up everything correctly.
Clean the downloaded source tree¶
The Linux maintainers recommend to clean up the kernel source tree before any
compilation in order to get rid of any spourious files that could be included in
the released tarball. Use the make mrproper
command provided with the Linux
source code:
$ make mrproper
Now you have a clean source tree, also know as the vanilla source.
Tip
Always clean the source tree before any new attempt to build the kernel. The
only necessary file to preserve before cleaning the source tree is the
.config
file, if you have made some modifications that you want to save.
Prepare a .config
file¶
If you compile the kernel source code as provided in the source tree, a set of
default options for the kernel will be applied which depend on the choices made
by the kernel developers. These options are defined in the .config
file but
can be modified to customize the kernel image.
Get the right .config
file¶
There are several ways of getting a proper .config
file for your system.
From the /boot
directory¶
First, in some distributions a copy of the configuraton file used to build the
running kernel is saved in the /boot
directory. This file can be copied back
into the build directory. The exact name for the .config
file varies among
distributions. For example, in a Debian system, you could copy the file as:
$ cp /boot/config-4.14.32-2-amd64 .config
or, on a Fedora system:
$ cp /boot/config-4.18.16-300.fc29.x86_64 .config
while in a phyglos system you’ll need:
$ cp /boot/linux-4.14.32-x86_64-pc_generic.config .config
From the /proc/config.gz
file¶
Second, the image of the kernel now running in your system may have been
compiled with a copy of the .config
file preserved inside that binary image
file. This Kconfig file is available through the virtual file
/proc/config.gz
. You can uncompress and copy these data as the .config
file:
$ cat /proc/config.gz | gunzip > .config
Generated with make *config
commands¶
Third, the Linux kernel source tree provides commands like make defconfig
or
make localmodconfig
to help generate a new .config
files with some
specific configurations.
Tip
See the Linux kernel documentation for all the different commands available.
From the linux-configs collection¶
And fourth, in the context of the linux-configs collection, a set of preconfigured files are provided in order to choose one of them as a starting point with some expected configuration. You can download the file from the Github repository or download and uncompress the package from the FTP site.
For example, to clone the repository while in the working directory, run:
$ git clone https://github.com/phyglos/linux-configs ../linux-configs
To find a suitable .config
file, just browse the collection to find a file
to work with. Then copy the desired Kconfig file from the linux-configs
collection into the build directory and name it as .config
.
$ cp ../linux-configs/linux-4.19.21-x86_64-pc_generic.config .config
Configure the kernel options¶
In order to compile a kernel suitable for a specific system, the .config
file inside the source tree may need to be further customized.
To configure the options for the kernel, using the present configuration file, the kernel source tree provides some configuration tools. To use a text based interface in the console, issue:
$ make menuconfig
Tip
There are other configuration tools available for using a graphical
interface to modify the kernel options, like make xconfig
. See the Linux
documentation for these alternatives.
Now, edit the new kernel configuration, as desired, e.g.:
--> Remove not needed options as:
-> Unckeck: Profiling Support
-> Unckeck: OProfile system profiling
-> Uncheck: Kprobes
--> Optimize for speed:
-> Check: Optimize very unlikely/likely branches
--> Select Exit to save a new .config file
Backup this configuration file, if a lot of options are changed, in order to
preserve it for future use. Copy the .config
somewhere outside the build
directory:
$ cp .config ~/my-best-config-file.config
Compile the kernel and modules¶
Once the desired .config
file is ready in the build directory, the Linux
kernel can be compiled:
$ make
Tip
The compilation time can be quite long, even hours on some old machines. You
can use the -j
parameter of the make
command to control how many cores
of the CPU will be used working in parallel:
$ make -j5
When the compilation ends, the binary image bzImage
for the new kernel is
ready in the arch/x86/boot
directory, for both x86 and x86_64 architectures.
Install the kernel image and modules¶
If any of the options set in the .config
file were marked as modules, the
kernel compilation process has also created several additional binary files, the
kernel modules, that need to be properly installed along with the kernel
image.
Note
The following commands install binaries in the system and need to be run as a privileged user. Use the su or sudo command to get these privileges.
Install the kernel modules¶
In order to install these Linux modules, as a privileged user, issue:
# make modules_install
The modules are installed in the /lib/modules
directory, in a subdirectory
named after the release number of the kernel being installed.
# tree -L 1 /lib/modules/
/lib/modules/
|-- 4.14.32
`-- 4.19.21
Install the new kernel image¶
For the new kernel to be available at boot time, the binary image has to be
installed in the proper directory, usually in the main /boot
directory.
Note
You can install the kernel image using the command make install
, but you
will not have control on the naming of the image and other details. It is
recommend to install the kernel image and other files by following the steps
shown bellow.
Install the new Linux kernel image by copying the arch/<arch>/boot/bzImage
file into the top /boot
directory from the right architecture directory,
where <arch> corresponds to the target architecture for this kernel image.
Hint
The images for both 64 bits and 32 bits kernels are placed in the same
arch/boot/x86
directory. When compiling for the x86_64
architecture
the kernel is built in the x86
directory and a link is created in the
arch/x86_64/boot
to the arch/x86/boot/bzImage
file.
It is a convention that the name of the kernel image in the /boot
directory
starts with vmlinuz
and is followed by the numbers of the release used. The
final name depends on the choices of the distribution. For the linux-configs
collections, the information about the variant used can also be attached to the
name. Hence, as an example, for a 64 bits image for a physical PC compatible
system, the full command could be:
# cp arch/x86_64/boot/bzImage /boot/vmlinuz-4.19.21-x86_64-pc_generic
Although not necessary, it can be convenient to save a copy of the .config
file in the same /boot
directory. For example, using the phyglos naming
conventions for the final file:
# cp .config /boot/linux-4.19.21-x86_64-pc_generic.config
Finally, in order to allow debugging the kernel, a file called System.map
can be also saved in the /boot
directory:
# cp System.map /boot/System.map-4.19.21-x86_64-pc_generic
Tip
This last step is not really necessary if you do not intend to debug the
kernel. It can be omitted to simplify and save a few megabytes of space in
the boot
directory.