Difference between revisions of "Kernels/Traditional compilation"

From ArchWiki
Jump to: navigation, search
m (added ja)
(Brought installation steps up-to-date as of the Linux 4.8 kernel. If I missed anything or screwed something up, please correct it. :))
 
(102 intermediate revisions by 28 users not shown)
Line 1: Line 1:
 
[[Category:Kernel]]
 
[[Category:Kernel]]
 +
[[fr:Compiler un nouveau noyau]]
 
[[it:Kernels/Compilation/Traditional]]
 
[[it:Kernels/Compilation/Traditional]]
[[ja:Kernels/Compilation/Traditional]]
+
[[ja:カーネル/コンパイル/伝統的な方法]]
[[ru:Kernel Compilation without ABS]]
+
[[ru:Kernels/Compilation/Traditional]]
 
[[zh-CN:Kernels/Compilation/Traditional]]
 
[[zh-CN: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.  If this seems too complicated, see some alternatives at: [[Kernels#Compilation]]
+
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.
  
== Fetching source ==
+
== Preparation ==
* Fetch the kernel source from http://www.kernel.org.  This can be done with GUI or text-based tools that utilize: HTTP, [[Ftp#FTP|FTP]], [[Rsync|RSYNC]], or [[Git]].
+
For instance, using wget via http:
+
$ wget -c https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.4.tar.xz
+
* 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.:
+
It is not necessary (or recommended) to use the root account or root privileges (i.e. via [[Sudo]]) for kernel preparation.
  $ cp linux-3.10.4.tar.xz ~/kernelbuild/
+
 
 +
=== Install the core packages ===
 +
 
 +
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.11 and above (4.2 and above for unified [[cgroups]] hierarchy support). See {{ic|/usr/share/systemd/README}} for more information.}}
 +
 
 +
Download the kernel source from http://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 [http://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:
  
* Unpack it and enter the source directory:
 
 
  $ cd ~/kernelbuild
 
  $ cd ~/kernelbuild
  $ tar -xvJf linux-3.10.4.tar.xz
+
  $ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.6.tar.xz
$ cd linux-3.10.4
+
Prepare for compilation by running the following command:
+
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.
+
  
=== What about /usr/src/ ? ===
+
If {{ic|wget}} was not used inside the build directory, it will be necessary to move the tarball into it, e.g.
Using {{ic|/usr/src/}} for compilation as root, along with the creation of the corresponding symlink, has been the target of much debate.
+
  
* It is considered poor practice by some users. They consider the cleanest method to simply use your home directory for configuring and compiling. Then installing as root.  
+
$ mv /path/to/linux-4.8.6.tar.xz ~/kernelbuild/
  
* Other experienced users consider the practice of the entire compiling process as root to be completely safe, acceptable, and even preferable.
+
=== Unpack the kernel source ===
  
Use whichever method you feel more comfortable with.  The following instructions can be interchangeable for either method.
+
Within the build directory, unpack the kernel tarball:
  
== Build configuration ==
+
$ tar -xvJf linux-4.8.6.tar.xz
This is the most crucial step in customizing the kernel to reflect your computer's precise specifications. By setting the options in {{ic|.config}} properly, your kernel and computer will function most efficiently.
+
  
=== Configure your kernel ===
+
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:
{{Warning| If compiling the ''radeon'' driver into the kernel(>3.3.3) for early KMS 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]}}
+
{{Tip| It is possible, to configure a kernel without initramfs on '''''simple configurations'''''.  Ensure that all your modules required for video/input/disks/fs are compiled into the kernel.  As well as support for DEVTMPFS_MOUNT, TMPFS, AUTOFS4_FS at the very least. If in doubt, learn about these options and what they mean ''before'' attempting.}}
+
  
==== First-timers ====
+
$ cd linux-4.8.6/
Two options for beginners to ease use or save time:
+
$ make clean && make mrproper
* Copy the .config file from the running kernel, if you want to modify default Arch settings.
+
  $ zcat /proc/config.gz > .config
+
* '''localmodconfig''' Since kernel 2.6.32, this should only select those options which are currently being used.
+
*# Boot into stock {{ic|-ARCH}} kernel, and plug in all devices that you expect to use on the system.
+
*# {{ic|cd}} into your source directory and run: {{ic|$ make localmodconfig}}
+
*# The resulting configuration file will be written to {{ic|.config}}. You can then compile and install as stated below.
+
  
==== Traditional menuconfig ====
+
== Configuration ==
{{ic|$ make menuconfig}} 
+
  
This will start with a fresh {{ic|.config}}, unless one already exists (e.g. copied over).  Option dependencies are automatically selected. And new options (i.e. with an older kernel {{ic|.config}}) may or may not be automatically selected.
+
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]].  
  
Make your changes to the kernel and save your config file. It is a good idea to make a backup copy outside the source directory, 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 CGROUPS support.  This is necessary for [[systemd]].
+
{{Note| It is not necessary to use the root account or root privileges at this stage.}}
  
==== Versioning ====
+
By setting the options in {{ic|.config}} properly, your kernel and computer will function most efficiently.  
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
+
=== Kernel configuration ===
General setup  --->
+
 
  (-ARCH) Local version - append to kernel release '3.n.n-RCn'
+
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 in the {{ic| General Setup --->}} option using one of the user interfaces listed later. 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 {{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.
 +
 
 +
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: {{ic|y}}  for enabled, {{ic|n}} for disabled, and {{ic|m}} for enabled as kernel module (loaded when necessary).}}
 +
 
 +
Those tools are:
 +
* {{ic|make menuconfig}}: Command-line ncurses interface superseded by {{ic|nconfig}}
 +
* {{ic|make nconfig}}: Newer ncurses interface for the command-line
 +
* {{ic|make xconfig}}: User-friendly graphical interface that requires {{Pkg|packagekit-qt4}}{{Broken package link|package not found}} 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.
 +
* {{ic|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 {{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.
 +
 
 +
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.
 +
 
 +
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 ==
 +
{{Tip|If you want to have {{Pkg|gcc}} optimize for your processor's instruction sets, edit {{ic|arch/x86/Makefile}} (i686) or {{ic|arch/x86_64/Makefile}} (86_64) 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 to {{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.
  
=== Compile ===
+
* 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.}}
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. See [[Makepkg#MAKEFLAGS|Makeflags]] for details.
+
  
{{Warning | If you use GRUB and still have LILO installed; {{ic|make all}} will configure LILO, and may result in an unbootable system.}}
+
=== Compile the kernel ===
Run {{ic| $ make }}.
+
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.}}
 +
 
 +
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:
  
=== Install modules ===
 
 
  # make modules_install
 
  # make modules_install
  
This copies the compiled modules into {{ic|/lib/modules/[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.
  
=== Copy kernel to /boot directory ===
+
{{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.}}
  # cp -v arch/x86/boot/bzImage /boot/vmlinuz-YourKernelName
+
 
 +
=== Copy the kernel to /boot directory ===
 +
{{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 ===
If you do not know what this is, please see: [[wikipedia:Initrd| Initramfs on Wikipedia]] and [[mkinitcpio]].
+
{{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.}}
# mkinitcpio -k FullKernelName -c /etc/mkinitcpio.conf -g /boot/initramfs-YourKernelName.img
+
  
You are free to name the {{ic|/boot}} files anything you want.  However, using the [kernel-major-minor-revision] naming scheme helps to keep order if you:
+
{{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.}}
* Keep multiple kernels
+
* Use mkinitcpio often
+
* Build third-party modules.
+
{{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]]}}
+
  
If you are using LILO and it cannot communicate with the kernel device-mapper driver, you have to run {{ic|modprobe dm-mod}} first.
+
If you do not know what making an initial RAM disk is, see [[wikipedia:Initrd|Initramfs on Wikipedia]] and [[mkinitcpio]].
 +
 
 +
==== Automated preset method ====
 +
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.
 +
 
 +
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}}:
 +
 
 +
{{hc|/etc/mkinitcpio.d/linux48.preset|
 +
...
 +
ALL_kver<nowiki>=</nowiki>"/boot/vmlinuz-linux48"
 +
...
 +
default_image<nowiki>=</nowiki>"/boot/initramfs-linux48.img"
 +
...
 +
fallback_image<nowiki>=</nowiki>"/boot/initramfs-linux48-fallback.img"}}
 +
 
 +
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 ===
Line 96: Line 189:
 
* 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 {{ic|/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:
* Kernel: vmlinuz-YourKernelName
+
* Kernel: {{ic|vmlinuz-YourKernelName}}
* Initramfs-YourKernelName.img
+
* Initramfs: {{ic|Initramfs-YourKernelName.img}}
* System Map: System.map-YourKernelName
+
* 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.  
+
Add an entry for your new kernel in your bootloader's configuration file - see [[GRUB]], [[LILO]], [[GRUB2]], [[Syslinux]], [[systemd-boot]] or [[REFInd]] for examples.  
  
 
{{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.}}
 
{{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.}}
 
== Using the NVIDIA video driver with your custom kernel ==
 
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 21:07, 7 November 2016

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.

Preparation

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

Install the core packages

Install the base-devel package group, which contains necessary packages such as make and gcc. It is also recommended to install the following packages, as listed in the default Arch kernel PKGBUILD: xmlto, docbook-xsl, kmod, inetutils, bc

Create a kernel compilation directory

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

$ mkdir ~/kernelbuild

Download the kernel source

Warning: systemd requires kernel version 3.11 and above (4.2 and above for unified cgroups hierarchy support). See /usr/share/systemd/README for more information.

Download the kernel source from http://www.kernel.org. This should be the tarball (tar.xz) file for your chosen kernel.

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:

$ cd ~/kernelbuild
$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.8.6.tar.xz

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 in the General Setup ---> option using one of the user interfaces listed later. 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-qt4[broken link: package not found] 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 (i686) or arch/x86_64/Makefile (86_64) 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 to -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.

If you do not know what making an initial RAM disk is, see Initramfs on Wikipedia and mkinitcpio.

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:

/etc/mkinitcpio.d/linux48.preset
...
ALL_kver="/boot/vmlinuz-linux48"
...
default_image="/boot/initramfs-linux48.img"
...
fallback_image="/boot/initramfs-linux48-fallback.img"

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:

# 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:

  • Kernel: vmlinuz-YourKernelName
  • Initramfs: Initramfs-YourKernelName.img
  • System Map: System.map-YourKernelName
  • System Map kernel symlink

Bootloader configuration

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

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