The summary below is helpful for building custom kernels from '''kernel.org sources'''. This method of compiling kernels is the traditional method common to all distros; however, an excellent method of cleanly installing the custom kernel with makepkg and pacman is also included.

+

[[zh-hans:Kernels/Compilation/Traditional]]

+

This article is an introduction to building custom kernels from '''kernel.org sources'''. This method of compiling kernels is the traditional method common to all distributions. It can be, depending on your background, more complicated than using the [[Kernels/Arch Build System]]. Consider the [[Arch Build System]] tools are developed and maintained to make repeatable compilation tasks efficient and safe.

−

Alternatively, you can use ABS to build and install your kernel; see: [[Kernels#Compilation]]. Using the existing {{Pkg|linux}} PKGBUILD will automate most of the process and will result in a package. However, some Arch users prefer the traditional way.

+

== Preparation ==

−

== Fetching source ==

+

It is not necessary (or recommended) to use the root account or root privileges (i.e. via [[Sudo]]) for kernel preparation.

−

* Fetch the kernel source from {{ic|ftp.xx.kernel.org/pub/linux/kernel/}}, where xx is your country key (e.g. 'us', 'uk', 'de', ... - Check [http://www.kernel.org/mirrors/] for a complete list of mirrors). If you have no ftp gui, you can use {{ic|wget}}. For this example, we will fetch and compile 3.2.9; you should need to change only the version to get a different kernel.

* It is always a good idea to verify the signature for any downloaded tarball. See [http://kernel.org/signature.html#using-gnupg-to-verify-kernel-signatures kernel.org/signature] for how this works and other details.

−

* Copy the kernel source to your build directory, e.g.:

+

=== Install the core packages ===

−

$ cp linux-3.2.9.tar.bz2 ~/kernelbuild/

+

+

Install the {{Grp|base-devel}} package group, which contains necessary packages such as {{Pkg|make}} and {{Pkg|gcc}}. It is also recommended to install the following packages, as listed in the default Arch kernel [https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/linux PKGBUILD]: {{Pkg|xmlto}}, {{Pkg|docbook-xsl}}, {{Pkg|kmod}}, {{Pkg|inetutils}}, {{Pkg|bc}}

+

+

=== Create a kernel compilation directory ===

+

+

It is recommended to create a separate build directory for your kernel(s). In this example, the directory {{ic|kernelbuild}} will be created in the {{ic|home}} directory:

+

+

$ mkdir ~/kernelbuild

+

+

=== Download the kernel source ===

+

+

{{Warning| [[systemd]] requires kernel version 3.12 at least (4.2 or greater for unified [[cgroups]] hierarchy support). See {{ic|/usr/share/doc/systemd/README}} for more information.}}

+

+

Download the kernel source from https://www.kernel.org. This should be the [[wikipedia:Tar (computing)|tarball]] ({{ic|tar.xz}}) file for your chosen kernel.

+

+

It can be downloaded by simply right-clicking the {{ic|tar.xz}} link in your browser and selecting {{ic|Save Link As...}}, or any other number of ways via alternative graphical or command-line tools that utilise HTTP, [[Ftp#FTP|FTP]], [[Rsync|RSYNC]], or [[Git]].

+

+

{{Note| It is a good idea to verify the PGP signature of any downloaded kernel tarball. This ensures that it is legitimate and helps to build the Web of Trust. See [https://kernel.org/signature.html#using-gnupg-to-verify-kernel-signatures kernel.org/signature].}}

+

+

In the following command-line example, {{Pkg|wget}} has been installed and is used inside the {{ic|~/kernelbuild}} directory to obtain kernel 4.8.6:

If {{ic|wget}} was not used inside the build directory, it will be necessary to move the tarball into it, e.g.

−

make mrproper

+

−

This ensures that the kernel tree is absolutely clean. The kernel team recommends that this command be issued prior to each kernel compilation. Do not rely on the source tree being clean after un-tarring.

+

$ mv /path/to/linux-4.8.6.tar.xz ~/kernelbuild/

+

+

=== Unpack the kernel source ===

+

+

Within the build directory, unpack the kernel tarball:

+

+

$ tar -xvJf linux-4.8.6.tar.xz

+

+

To finalise the preparation, ensure that the kernel tree is absolutely clean; do not rely on the source tree being clean after unpacking. To do so, first change into the new kernel source directory created, and then run the {{ic|make mrproper}} command:

+

+

$ cd linux-4.8.6/

+

$ make clean && make mrproper

+

+

== Configuration ==

+

+

This is the most crucial step in customizing the default kernel to reflect your computer's precise specifications. Kernel configuration is set in its {{ic|.config}} file, which includes the use of [[Kernel modules]].

+

+

{{Note| It is not necessary to use the root account or root privileges at this stage.}}

+

+

By setting the options in {{ic|.config}} properly, your kernel and computer will function most efficiently.

+

+

=== Kernel configuration ===

+

+

You can choose from two options to set your kernel configuration:

+

* A. Use the default Arch settings from an official kernel (recommended)

+

* B. Generate a configuration file which matches the currently running kernel's configuration. (useful if you want to customize your kernel settings further)

+

+

{{Note| Especially if you choose option **B**, you will be prompted to manually configure your kernel with tools described in {{ic|Advanced Configuration}}.}}

+

+

==== A. Default Arch configuration ====

+

+

This method will create a {{ic|.config}} file for the custom kernel using the default Arch kernel settings. Ensure that a stock Arch kernel is running and use the following command inside the custom kernel source directory:

+

+

$ zcat /proc/config.gz > .config

+

+

{{Warning|If you are compiling a kernel using your current {{ic|.config}} file, do not forget to rename your kernel version "CONFIG_LOCALVERSION" in the new .config or in the {{ic| General Setup --->}} option using one of the user interfaces listed under Advanced Configuration. If you skip this, there is the risk of overwriting one of your existing kernels by mistake.}}

+

+

==== B. Generated configuration ====

+

+

{{tip|Plug in all devices that you expect to use on the system if using this method.}}

−

=== What about /usr/src/ ? ===

+

Since kernel 2.6.32, the {{ic|localmodconfig}} command will create a {{ic|.config}} file for the custom kernel by disabling any and all options not currently in use by the running kernel ''at the time''. In other words, it will only enable the options currently being used.

−

Using the /usr/src/ directory for kernel compilation as root, along with the creation of the corresponding symlink, is considered poor practice by some kernel hackers. They consider the cleanest method to simply use your home directory. If you subscribe to this point of view, build and configure your kernel as normal user, and install as root, or [[Kernels/Compilation/Arch Build System|with makepkg and pacman]].

−

However, this concept has been the target of debate, and other very experienced hackers consider the practice of compiling as root under /usr/src/ to be completely safe, acceptable and even preferable.

+

While this minimalist approach will result in a highly streamlined and efficient configuration tailored specifically for your system, there are drawbacks, such as the potential inability of the kernel to support newer hardware, peripherals, or other features.

−

Use whichever method you feel more comfortable with.

+

{{Note|Again, ensure that all devices you expect to use have been connected to (and detected by) your system before running the following command}}

−

== Build configuration ==

+

$ make localmodconfig

−

This is the most crucial step in customizing the kernel to reflect your computer's precise specifications. By setting the configurations in 'menuconfig' properly, your kernel and computer will function most efficiently.

−

=== Pre-configuration ===

+

=== Advanced configuration ===

−

Optional, but strongly recommended for first-timers:

−

*Copy the .config file from the running kernel, if you want to modify default Arch settings.

−

$ zcat /proc/config.gz > .config

−

*Note the output of currently loaded modules with {{ic|lsmod}}. This will be specific to each system.

−

=== Configure your kernel ===

+

{{Tip|Unless you want to see a lot of extra messages when booting and shutting down with the custom kernel, it is a good idea to deactivate the relevant debugging options.}}

−

{{Warning| If compiling the ''radeon'' driver into the kernel(>3.3.3) with a newer video card, you '''must''' include the firmware files for your card. Otherwise acceleration will be crippled. See [http://wiki.x.org/wiki/radeonBuildHowTo#Missing_Extra_Firmware here]}}

−

There are two main choices:

+

There are several tools available to fine-tune the kernel configuration, which provide an alternative to otherwise spending hours manually configuring each and every one of the options available during compilation.

−

==== Traditional menuconfig ====

−

$ make menuconfig (Will start with a fresh '.config'. Option dependencies are usually automatically selected.)

−

Make your changes to the kernel and save your config file. It is a good idea to make a backup copy, since you could be doing this multiple times until you get all the options right. If unsure, only change a few options between compiles. If you cannot boot your newly built kernel, see the list of necessary config items [https://www.archlinux.org/news/users-of-unofficial-kernels-must-enable-devtmpfs-support/ here]. Running {{ic|$ lspci -k #}} from liveCD lists names of kernel modules in use. Most importantly, you must maintain {{ic|cgroup}} support. This is necessary for [[systemd]].

+

{{Note| Those tools listed below will provide you with three configuration options for each kernel feature: {{ic|y}} for enabled, {{ic|n}} for disabled, and {{ic|m}} for enabled as kernel module (loaded when necessary).}}

−

==== localmodconfig ====

+

Those tools are:

−

Since kernel 2.6.32, localmodconfig is provided to ease kernel configuration. To use this option:

# Boot the distribution kernel, and plug in any devices that you expect to use on the system, which will load the kernel drivers for them. # Go into your kernel source directory, and run {{bc|$make localmodconfig}}

+

* {{ic|make nconfig}}: Newer ncurses interface for the command-line

−

# That option will dig through your system and find the kernel configuration for the running kernel (which is usually at /proc/config.gz, but can sometimes be located in the boot partition, depending on the distribution).

+

* {{ic|make xconfig}}: User-friendly graphical interface that requires {{Pkg|packagekit-qt5}} to be installed as a dependency. This is the recommended method - especially for less experienced users - as it is easier to navigate, and information about each option is also displayed.

−

# Then, the script will remove all options for kernel modules that are not currently loaded, stripping down the number of drivers that will be built significantly.

+

* {{ic|make gconfig}}: Graphical configuration similar to xconfig but using gtk.

−

# The resulting configuration file will be written to the .config file, and then you can build the kernel and install it as normal.

−

==== Local version ====

+

The chosen method should be run inside the kernel source directory, and all will either create a new {{ic|.config}} file, or overwrite an existing one where present. All optional configurations will be automatically enabled, although any newer configuration options (i.e. with an older kernel {{ic|.config}}) may not be automatically selected.

−

If you are compiling a kernel using your current config file, do not forget to rename your kernel version, or you may replace your existing one by mistake.

−

$ make menuconfig

+

Once the changes have been made save the {{ic|.config}} file. It is a good idea to make a backup copy outside the source directory. You may need to do this multiple times before you get all the options right.

−

General setup --->

+

−

(-ARCH) Local version - append to kernel release '3.n.n-RCn'

+

If unsure, only change a few options between compilations. If you cannot boot your newly built kernel, see the list of necessary config items [https://www.archlinux.org/news/users-of-unofficial-kernels-must-enable-devtmpfs-support/ here].

+

+

Running {{ic|$ lspci -k #}} from liveCD lists names of kernel modules in use. Most importantly, you must maintain CGROUPS support. This is necessary for [[systemd]].

== Compilation and installation ==

== Compilation and installation ==

−

To compile kernel manually, follow these steps:

+

{{Tip|If you want to have {{Pkg|gcc}} optimize for your processor's instruction sets, edit {{ic|arch/x86/Makefile}} (both for 32 and 64 bits, see [https://lkml.org/lkml/2007/7/20/447]) within the kernel source directory:

+

* Look for {{ic|CONFIG_MK8,CONFIG_MPSC,CONFIG_MCORE2,CONFIG_MATOM,CONFIG_GENERIC_CPU}} that you have chosen in {{ic|Processor type and features > Processor Family}}

+

* Change the call cc-options flag from {{ic|-march<nowiki>=</nowiki>native}} to the one that you have selected in Processor Family, e.g. {{ic|cflags-$(CONFIG_MK8) +<nowiki>=</nowiki> $(call cc-option,-march<nowiki>=</nowiki>native)}}. This is probably the best way to compile with {{ic|-march<nowiki>=</nowiki>native}} as it works.

+

+

* Note: For 32bit Kernels, you need to edit {{ic|arch/x86/Makefile_32.cpu}} instead and set {{ic|-march<nowiki>=</nowiki>native}} for your processor.}}

+

+

=== Compile the kernel ===

+

Compilation time will vary from as little as fifteen minutes to over an hour, depending on your kernel configuration and processor capability. See [[Makepkg#MAKEFLAGS|Makeflags]] for details. Once the {{ic|.config}} file has been set for the custom kernel, within the source directory run the following command to compile:

+

+

$ make

+

+

=== Compile the modules ===

+

{{warning|From this step onwards, commands must be either run as root or with root privileges. If not, they will fail.}}

−

=== Compile ===

+

Once the kernel has been compiled, the modules for it must follow. As root or with root privileges, run the following command to do so:

−

{{Warning | Do not run {{ic|make all}} if you use GRUB and still have LILO installed; it will configure LILO in the end, and you may no longer be able to boot your machine! Remove LILO (pacman -R lilo) before running {{ic|make all}} if you use GRUB!}}

−

$ make (Same as make vmlinux && make modules && make bzImage - see 'make help' for more information on this.)

Compilation time will vary from 15 minutes to over an hour. This is largely based on how many options/modules are selected, as well as processor capability.

−

=== Install modules ===

−

This needs to be done as root.

# make modules_install

# make modules_install

−

This copies the compiled modules into <code>/lib/modules/</code>[kernel version + CONFIG_LOCALVERSION]. This way, modules can be kept separate from those used by other kernels on your machine.

+

This will copy the compiled modules into {{ic|/lib/modules/<kernel version>-<config local version>}}. For example, for kernel version 4.8 installed above, they would be copied to {{ic|/lib/modules/4.8.6-ARCH}}. This keeps the modules for individual kernels used separated.

+

+

{{Tip|If your system requires modules which are not distributed with the regular Linux kernel, you need to compile them for your custom kernel when it is finished. Such modules are typically those which you explicitly installed separately for your running system. See [[NVIDIA#Custom kernel]] for an example.}}

−

=== Copy kernel to /boot directory ===

+

=== Copy the kernel to /boot directory ===

−

# cp -v arch/x86/boot/bzImage /boot/vmlinuz-YourKernelName

+

{{Note|Ensure that the {{ic|bzImage}} kernel file has been copied from the appropriate directory for your system architecture. See below.}}

+

+

The kernel compilation process will generate a compressed {{ic|bzImage}} (big zImage) of that kernel, which must be copied to the {{ic|/boot}} directory and renamed in the process. Provided the name is prefixed with {{ic|vmlinuz-}}, you may name the kernel as you wish. In the examples below, the installed and compiled 4.8 kernel has been copied over and renamed to {{ic|vmlinuz-linux48}}:

+

+

* 32-bit (i686) kernel:

+

# cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux48

+

+

* 64-bit (x86_64) kernel:

+

# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux48

=== Make initial RAM disk ===

=== Make initial RAM disk ===

−

The initial RAM disk (initrd option in the GRUB menu, or, the file "initramfs-YourKernelName.img") is an initial root file system that is mounted prior to when the real root file system is available. The initrd is bound to the kernel and loaded as part of the kernel boot procedure. The kernel then mounts this initrd as part of the two-stage boot process to load the modules to make the real file systems available and get at the real root file system. The initrd contains a minimal set of directories and executables to achieve this, such as the insmod tool to install kernel modules into the kernel. In the case of desktop or server Linux systems, the initrd is a transient file system. Its lifetime is short, only serving as a bridge to the real root file system. In embedded systems with no mutable storage, the initrd is the permanent root file system.

+

{{Note|You are free to name the initramfs image file whatever you wish when generating it. However, it is recommended to use the {{ic|linux<major revision><minor revision>}} convention. For example, the name 'linux48' was given as '4' is the major revision and '8' is the minor revision of the 4.8 kernel. This convention will make it easier to maintain multiple kernels, regularly use mkinitcpio, and build third-party modules.}}

−

If you need any modules loaded in order to mount the root filesystem, build a ramdisk (most users need this). The -k parameter accepts the kernel version and appended string you set in menuconfig and is used to locate the corresponding modules directory in '/usr/lib/modules':

+

{{Tip|If you are using the LILO bootloader and it cannot communicate with the kernel device-mapper driver, you have to run {{ic|modprobe dm-mod}} first.}}

−

# mkinitcpio -k FullKernelName -g /boot/initramfs-YourKernelName.img

+

If you do not know what making an initial RAM disk is, see [[wikipedia:Initrd|Initramfs on Wikipedia]] and [[mkinitcpio]].

−

You are free to name the /boot files anything you want. However, using the [kernel-major-minor-revision] naming scheme helps to keep order if you: Keep multiple kernels/ Use mkinitcpio often/ Build third-party modules.

+

==== Automated preset method ====

−

{{Tip| If rebuilding images often, it might be helpful to create a separate preset file resulting in the command being something like:<code># mkinitcpio -p custom</code>. See [[mkinitcpio#Image_creation_and_activation| here]]}}

+

An existing [[Mkinitcpio#Image_creation_and_activation|mkinitcpio preset]] can be copied and modified so that the custom kernel initramfs images can be generated in the same way as for an official kernel. This is useful where intending to recompile the kernel (e.g. where updated). In the example below, the preset file for the stock Arch kernel will be copied and modified for kernel 4.8, installed above.

−

If you are using LILO and it cannot communicate with the kernel device-mapper driver, you have to run {{ic|modprobe dm-mod}} first.

+

First, copy the existing preset file, renaming it to match the name of the custom kernel specified as a suffix to {{ic|/boot/vmlinuz-}} when copying the {{ic|bzImage}} (in this case, {{ic|linux48}}):

+

+

# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux48.preset

+

+

Second, edit the file and amend for the custom kernel. Note (again) that the {{ic|ALL_kver<nowiki>=</nowiki>}} parameter also matches the name of the custom kernel specified when copying the {{ic|bzImage}}:

Finally, generate the initramfs images for the custom kernel in the same way as for an official kernel:

+

+

# mkinitcpio -p linux48

+

+

==== Manual method ====

+

Rather than use a preset file, mkinitcpio can also be used to generate an initramfs file manually. The syntax of the command is:

+

+

# mkinitcpio -k <kernelversion> -g /boot/initramfs-<file name>.img

+

+

* {{ic|-k}} (--kernel <kernelversion>): Specifies the modules to use when generating the initramfs image. The {{ic|<kernelversion>}} name will be the same as the name of the custom kernel source directory (and the modules directory for it, located in {{ic|/usr/lib/modules/}}).

+

* {{ic|-g}} (--generate <filename>): Specifies the name of the initramfs file to generate in the {{ic|/boot}} directory. Again, using the naming convention mentioned above is recommended.

+

+

For example, the command for the 4.8 custom kernel installed above would be:

+

+

# mkinitcpio -k linux-4.8.6 -g /boot/initramfs-linux48.img

=== Copy System.map ===

=== Copy System.map ===

−

The System.map file is not required for booting Linux. It is a type of "phone directory" list of functions in a particular build of a kernel. The System.map contains a list of kernel symbols (i.e function names, variable names etc) and their corresponding addresses. This "symbol-name to address mapping" is used by:

+

The {{ic|System.map}} file is not required for booting Linux. It is a type of "phone directory" list of functions in a particular build of a kernel. The {{ic|System.map}} contains a list of kernel symbols (i.e function names, variable names etc) and their corresponding addresses. This "symbol-name to address mapping" is used by:

* Some processes like klogd, ksymoops etc

* Some processes like klogd, ksymoops etc

* By OOPS handler when information has to be dumped to the screen during a kernel crash (i.e info like in which function it has crashed).

* By OOPS handler when information has to be dumped to the screen during a kernel crash (i.e info like in which function it has crashed).

−

Copy System.map to /boot and create symlink

+

{{Tip| UEFI partitions are formatted using FAT32, which does not support symlinks.}}

+

+

If your {{ic|/boot}} is on a filesystem which supports symlinks (i.e., not FAT32), copy {{ic|System.map}} to {{ic|/boot}}, appending your kernel's name to the destination file. Then create a symlink from {{ic|/boot/System.map}} to point to {{ic|/boot/System.map-YourKernelName}}:

# cp System.map /boot/System.map-YourKernelName

# cp System.map /boot/System.map-YourKernelName

+

# ln -sf /boot/System.map-YourKernelName /boot/System.map

−

After completing all steps above, you should have the following 3 files and 1 soft symlink in your /boot directory along with any other previously existing files:

+

After completing all steps above, you should have the following 3 files and 1 soft symlink in your {{ic|/boot}} directory along with any other previously existing files:

−

vmlinuz-YourKernelName (Kernel)

+

* Kernel: {{ic|vmlinuz-YourKernelName}}

−

initramfs-YourKernelName.img (Ramdisk)

+

* Initramfs: {{ic|Initramfs-YourKernelName.img}}

−

System.map-YourKernelName (System Map)

+

* System Map: {{ic|System.map-YourKernelName}}

+

* System Map kernel symlink

== Bootloader configuration ==

== Bootloader configuration ==

−

Add an entry for your amazing new kernel in your bootloader's configuration file - see [[GRUB]], [[LILO]], [[GRUB2]] or [[Syslinux]] for examples. Note that if you use LILO, the kernel sources include a script to automate the process:

+

Add an entry for your new kernel in your bootloader's configuration file - see [[GRUB]], [[LILO]], [[GRUB2]], [[Syslinux]], [[systemd-boot]] or [[REFInd]] for examples.

−

−

$ arch/x86/boot/install.sh

−

−

If you use LILO, remember to type {{ic|lilo}} as root at the prompt to update it.

−

−

If you use Grub 2, you will probably want to add a menuentry to '/etc/grub.d/40_custom'. The simplest way is to copy an existing menuentry found in your '/boot/grub/grub.cfg' file, modify the entry to include the name of the kernel and image you created, and update grub ('grub-mkconfig -o /boot/grub/grub.cfg').

−

== Using the NVIDIA video driver with your custom kernel ==

+

{{Tip| Kernel sources include a script to automate the process for LILO: {{ic|$ arch/x86/boot/install.sh}}. Remember to type {{ic|lilo}} as root at the prompt to update it.}}

−

To use the NVIDIA driver with your new custom kernel, see: [[NVIDIA#Alternate install: custom kernel|How to install nVIDIA driver with custom kernel]]. You can also install nvidia drivers from AUR.

Latest revision as of 09:05, 8 August 2017

This article is an introduction to building custom kernels from kernel.org sources. This method of compiling kernels is the traditional method common to all distributions. It can be, depending on your background, more complicated than using the Kernels/Arch Build System. Consider the Arch Build System tools are developed and maintained to make repeatable compilation tasks efficient and safe.

It can be downloaded by simply right-clicking the tar.xz link in your browser and selecting Save Link As..., or any other number of ways via alternative graphical or command-line tools that utilise HTTP, FTP, RSYNC, or Git.

Note: It is a good idea to verify the PGP signature of any downloaded kernel tarball. This ensures that it is legitimate and helps to build the Web of Trust. See kernel.org/signature.

In the following command-line example, wget has been installed and is used inside the ~/kernelbuild directory to obtain kernel 4.8.6:

If wget was not used inside the build directory, it will be necessary to move the tarball into it, e.g.

$ mv /path/to/linux-4.8.6.tar.xz ~/kernelbuild/

Unpack the kernel source

Within the build directory, unpack the kernel tarball:

$ tar -xvJf linux-4.8.6.tar.xz

To finalise the preparation, ensure that the kernel tree is absolutely clean; do not rely on the source tree being clean after unpacking. To do so, first change into the new kernel source directory created, and then run the make mrproper command:

$ cd linux-4.8.6/
$ make clean && make mrproper

Configuration

This is the most crucial step in customizing the default kernel to reflect your computer's precise specifications. Kernel configuration is set in its .config file, which includes the use of Kernel modules.

Note: It is not necessary to use the root account or root privileges at this stage.

By setting the options in .config properly, your kernel and computer will function most efficiently.

Kernel configuration

You can choose from two options to set your kernel configuration:

A. Use the default Arch settings from an official kernel (recommended)

B. Generate a configuration file which matches the currently running kernel's configuration. (useful if you want to customize your kernel settings further)

Note: Especially if you choose option **B**, you will be prompted to manually configure your kernel with tools described in Advanced Configuration.

A. Default Arch configuration

This method will create a .config file for the custom kernel using the default Arch kernel settings. Ensure that a stock Arch kernel is running and use the following command inside the custom kernel source directory:

$ zcat /proc/config.gz > .config

Warning: If you are compiling a kernel using your current .config file, do not forget to rename your kernel version "CONFIG_LOCALVERSION" in the new .config or in the General Setup ---> option using one of the user interfaces listed under Advanced Configuration. If you skip this, there is the risk of overwriting one of your existing kernels by mistake.

B. Generated configuration

Tip: Plug in all devices that you expect to use on the system if using this method.

Since kernel 2.6.32, the localmodconfig command will create a .config file for the custom kernel by disabling any and all options not currently in use by the running kernel at the time. In other words, it will only enable the options currently being used.

While this minimalist approach will result in a highly streamlined and efficient configuration tailored specifically for your system, there are drawbacks, such as the potential inability of the kernel to support newer hardware, peripherals, or other features.

Note: Again, ensure that all devices you expect to use have been connected to (and detected by) your system before running the following command

$ make localmodconfig

Advanced configuration

Tip: Unless you want to see a lot of extra messages when booting and shutting down with the custom kernel, it is a good idea to deactivate the relevant debugging options.

There are several tools available to fine-tune the kernel configuration, which provide an alternative to otherwise spending hours manually configuring each and every one of the options available during compilation.

Note: Those tools listed below will provide you with three configuration options for each kernel feature: y for enabled, n for disabled, and m for enabled as kernel module (loaded when necessary).

Those tools are:

make menuconfig: Command-line ncurses interface superseded by nconfig

make nconfig: Newer ncurses interface for the command-line

make xconfig: User-friendly graphical interface that requires packagekit-qt5 to be installed as a dependency. This is the recommended method - especially for less experienced users - as it is easier to navigate, and information about each option is also displayed.

make gconfig: Graphical configuration similar to xconfig but using gtk.

The chosen method should be run inside the kernel source directory, and all will either create a new .config file, or overwrite an existing one where present. All optional configurations will be automatically enabled, although any newer configuration options (i.e. with an older kernel .config) may not be automatically selected.

Once the changes have been made save the .config file. It is a good idea to make a backup copy outside the source directory. You may need to do this multiple times before you get all the options right.

If unsure, only change a few options between compilations. If you cannot boot your newly built kernel, see the list of necessary config items here.

Running $ lspci -k # from liveCD lists names of kernel modules in use. Most importantly, you must maintain CGROUPS support. This is necessary for systemd.

Compilation and installation

Tip: If you want to have gcc optimize for your processor's instruction sets, edit arch/x86/Makefile (both for 32 and 64 bits, see [1]) within the kernel source directory:

Look for CONFIG_MK8,CONFIG_MPSC,CONFIG_MCORE2,CONFIG_MATOM,CONFIG_GENERIC_CPU that you have chosen in Processor type and features > Processor Family

Change the call cc-options flag from -march=native to the one that you have selected in Processor Family, e.g. cflags-$(CONFIG_MK8) += $(call cc-option,-march=native). This is probably the best way to compile with -march=native as it works.

Note: For 32bit Kernels, you need to edit arch/x86/Makefile_32.cpu instead and set -march=native for your processor.

Compile the kernel

Compilation time will vary from as little as fifteen minutes to over an hour, depending on your kernel configuration and processor capability. See Makeflags for details. Once the .config file has been set for the custom kernel, within the source directory run the following command to compile:

$ make

Compile the modules

Warning: From this step onwards, commands must be either run as root or with root privileges. If not, they will fail.

Once the kernel has been compiled, the modules for it must follow. As root or with root privileges, run the following command to do so:

# make modules_install

This will copy the compiled modules into /lib/modules/<kernel version>-<config local version>. For example, for kernel version 4.8 installed above, they would be copied to /lib/modules/4.8.6-ARCH. This keeps the modules for individual kernels used separated.

Tip: If your system requires modules which are not distributed with the regular Linux kernel, you need to compile them for your custom kernel when it is finished. Such modules are typically those which you explicitly installed separately for your running system. See NVIDIA#Custom kernel for an example.

Copy the kernel to /boot directory

Note: Ensure that the bzImage kernel file has been copied from the appropriate directory for your system architecture. See below.

The kernel compilation process will generate a compressed bzImage (big zImage) of that kernel, which must be copied to the /boot directory and renamed in the process. Provided the name is prefixed with vmlinuz-, you may name the kernel as you wish. In the examples below, the installed and compiled 4.8 kernel has been copied over and renamed to vmlinuz-linux48:

32-bit (i686) kernel:

# cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux48

64-bit (x86_64) kernel:

# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux48

Make initial RAM disk

Note: You are free to name the initramfs image file whatever you wish when generating it. However, it is recommended to use the linux<major revision><minor revision> convention. For example, the name 'linux48' was given as '4' is the major revision and '8' is the minor revision of the 4.8 kernel. This convention will make it easier to maintain multiple kernels, regularly use mkinitcpio, and build third-party modules.

Tip: If you are using the LILO bootloader and it cannot communicate with the kernel device-mapper driver, you have to run modprobe dm-mod first.

Automated preset method

An existing mkinitcpio preset can be copied and modified so that the custom kernel initramfs images can be generated in the same way as for an official kernel. This is useful where intending to recompile the kernel (e.g. where updated). In the example below, the preset file for the stock Arch kernel will be copied and modified for kernel 4.8, installed above.

First, copy the existing preset file, renaming it to match the name of the custom kernel specified as a suffix to /boot/vmlinuz- when copying the bzImage (in this case, linux48):

# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux48.preset

Second, edit the file and amend for the custom kernel. Note (again) that the ALL_kver= parameter also matches the name of the custom kernel specified when copying the bzImage:

Finally, generate the initramfs images for the custom kernel in the same way as for an official kernel:

# mkinitcpio -p linux48

Manual method

Rather than use a preset file, mkinitcpio can also be used to generate an initramfs file manually. The syntax of the command is:

# mkinitcpio -k <kernelversion> -g /boot/initramfs-<file name>.img

-k (--kernel <kernelversion>): Specifies the modules to use when generating the initramfs image. The <kernelversion> name will be the same as the name of the custom kernel source directory (and the modules directory for it, located in /usr/lib/modules/).

-g (--generate <filename>): Specifies the name of the initramfs file to generate in the /boot directory. Again, using the naming convention mentioned above is recommended.

For example, the command for the 4.8 custom kernel installed above would be:

# mkinitcpio -k linux-4.8.6 -g /boot/initramfs-linux48.img

Copy System.map

The System.map file is not required for booting Linux. It is a type of "phone directory" list of functions in a particular build of a kernel. The System.map contains a list of kernel symbols (i.e function names, variable names etc) and their corresponding addresses. This "symbol-name to address mapping" is used by:

Some processes like klogd, ksymoops etc

By OOPS handler when information has to be dumped to the screen during a kernel crash (i.e info like in which function it has crashed).

Tip: UEFI partitions are formatted using FAT32, which does not support symlinks.

If your /boot is on a filesystem which supports symlinks (i.e., not FAT32), copy System.map to /boot, appending your kernel's name to the destination file. Then create a symlink from /boot/System.map to point to /boot/System.map-YourKernelName: