Difference between revisions of "Kernels/Traditional compilation"

From ArchWiki
Jump to: navigation, search
(use https for links to archlinux.org)
m (Had a correction in the Compilations sub heading.)
 
(125 intermediate revisions by 27 users not shown)
Line 1: Line 1:
 
[[Category:Kernel]]
 
[[Category:Kernel]]
 +
[[fr:Compiler un nouveau noyau]]
 
[[it:Kernels/Compilation/Traditional]]
 
[[it:Kernels/Compilation/Traditional]]
[[ru:Kernel Compilation without ABS]]
+
[[ja:カーネル/コンパイル/伝統的な方法]]
 +
[[ru:Kernels/Compilation/Traditional]]
 
[[zh-CN:Kernels/Compilation/Traditional]]
 
[[zh-CN:Kernels/Compilation/Traditional]]
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.  
+
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 is, of course, more complicated than compiling according to [[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.
+
For instance:
+
$ wget -c http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.9.tar.bz2
+
* 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 ===
 +
{{Note|<nowiki></nowiki>
 +
* It is a good idea to verify the signature for any downloaded tarball to ensure that it is legitimate. See [http://kernel.org/signature.html#using-gnupg-to-verify-kernel-signatures kernel.org/signature].
 +
* [[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]]. In the following command-line example, {{Pkg|wget}} has been installed and is used inside the {{ic|~/kernelbuild}} directory to obtain kernel 3.18:
  
* Unpack it and enter the source directory:
 
 
  $ cd ~/kernelbuild
 
  $ cd ~/kernelbuild
  $ tar -xvjf linux-3.2.9.tar.bz2
+
  $ wget https://kernel.org/pub/linux/kernel/v3.x/linux-3.18.28.tar.xz
$ cd linux-3.2.9
+
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 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.  
+
$ mv /path/to/linux-3.18.28.tar.xz ~/kernelbuild/
  
Use whichever method you feel more comfortable with.
+
=== Unpack the kernel source ===
  
== Build configuration ==
+
Within the build directory, unpack the kernel tarball:
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 ===
+
$ tar -xvJf linux-3.18.28.tar.xz
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 ===
+
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) 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:
+
  $ cd linux-3.18.28
==== Traditional menuconfig ====
+
  $ make clean && make mrproper
  $ 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 will likely be doing this multiple times until you get all the options right. 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 $ lspci -k #  from liveCD lists names of kernel modules in use.
+
== Configuration ==
 +
{{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.}}
  
==== localmodconfig ====
+
This is the most crucial step in customizing the kernel to reflect your computer's precise specifications. Kernel configuration is set in its {{ic|.config}} file, which includes the use of the [[Kernel modules]]. By setting the options in {{ic|.config}} properly, your kernel and computer will function most efficiently. Note that - again - it is not necessary to use the root account or root privileges for this stage.
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}}
+
# 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).  
+
# 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.
+
# 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 ====
+
=== Simple configuration ===
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.
+
{{Note|The custom kernel(s) being configured may support different features than the official Arch kernels. In this instance, you will be prompted to manually configure them. The configuration options should be {{ic|y}} to enable, {{ic|n}} to disable, and {{ic|m}} to enable when necessary.}}
  
  $ make menuconfig
+
Two options are available for ease and to save time:
General setup  --->
+
* Use the default Arch settings from an official kernel (recommended)
  (-ARCH) Local version - append to kernel release '3.n.n-RCn'
+
* Generate a configuration file by the modules and settings in use by a running kernel ''at that time''.
 +
 
 +
==== Default Arch settings ====
 +
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
 +
 
 +
==== Generated configuration file ====
 +
{{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 new hardware, peripherals, or other features. 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 interfaces 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. They are:
 +
 
 +
* {{ic|make menuconfig}}: Old command-line ncurses interface superceded 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}} 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 since you could be doing this multiple times until 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 ==
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}} (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.}}
{{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.)
+
=== Compile the kernel ===
or
+
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 -jN  (N = # of processors + 1) (This utilizes all CPUs at 100%.)
+
 
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.
+
$ 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 ===
 
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 3.18 installed above, they would be copied to {{ic|/lib/modules/3.18.28-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 seperately for your running system. See [[NVIDIA#Alternate install: 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 3.18 kernel has been copied over and renamed to {{ic|vmlinuz-linux318}}:
 +
 
 +
* 32-bit (i686) kernel:
 +
  # cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux318
 +
 
 +
* 64-bit (x86_64) kernel:
 +
# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux318
  
 
=== 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 'linux318' was given as '3' is the major revision and '18' is the minor revision of the 3.18 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 3.18, 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|linux318}}):
 +
 
 +
# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux318.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/linux318.preset|
 +
...
 +
ALL_kver<nowiki>=</nowiki>"/boot/vmlinuz-linux318"
 +
...
 +
default_image<nowiki>=</nowiki>"/boot/initramfs-linux318.img"
 +
...
 +
fallback_image<nowiki>=</nowiki>"/boot/initramfs-linux318-fallback.img"}}
 +
 
 +
Finally, generate the initramfs images for the custom kernel in the same way as for an official kernel:
 +
 
 +
# mkinitcpio -p linux318
 +
 
 +
==== 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 3.18 custom kernel installed above would be:
 +
 
 +
# mkinitcpio -k linux-3.18.28 -g /boot/initramfs-linux318.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]], [[Gummiboot]] or [[REFInd]] for examples.  
 
+
$ arch/i386/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 05:45, 1 May 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 is, of course, more complicated than compiling according to 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

Note:
  • It is a good idea to verify the signature for any downloaded tarball to ensure that it is legitimate. See kernel.org/signature.
  • 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. In the following command-line example, wget has been installed and is used inside the ~/kernelbuild directory to obtain kernel 3.18:

$ cd ~/kernelbuild
$ wget https://kernel.org/pub/linux/kernel/v3.x/linux-3.18.28.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-3.18.28.tar.xz ~/kernelbuild/

Unpack the kernel source

Within the build directory, unpack the kernel tarball:

$ tar -xvJf linux-3.18.28.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-3.18.28
$ make clean && make mrproper

Configuration

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.

This is the most crucial step in customizing the kernel to reflect your computer's precise specifications. Kernel configuration is set in its .config file, which includes the use of the Kernel modules. By setting the options in .config properly, your kernel and computer will function most efficiently. Note that - again - it is not necessary to use the root account or root privileges for this stage.

Simple configuration

Note: The custom kernel(s) being configured may support different features than the official Arch kernels. In this instance, you will be prompted to manually configure them. The configuration options should be y to enable, n to disable, and m to enable when necessary.

Two options are available for ease and to save time:

  • Use the default Arch settings from an official kernel (recommended)
  • Generate a configuration file by the modules and settings in use by a running kernel at that time.

Default Arch settings

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

Generated configuration file

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 new hardware, peripherals, or other features. 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 interfaces 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. They are:

  • make menuconfig: Old command-line ncurses interface superceded by nconfig
  • make nconfig: Newer ncurses interface for the command-line
  • make xconfig: User-friendly graphical interface that requires packagekit-qt4 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 since you could be doing this multiple times until 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 3.18 installed above, they would be copied to /lib/modules/3.18.28-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 seperately for your running system. See NVIDIA#Alternate install: 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 3.18 kernel has been copied over and renamed to vmlinuz-linux318:

  • 32-bit (i686) kernel:
# cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux318
  • 64-bit (x86_64) kernel:
# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux318

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 'linux318' was given as '3' is the major revision and '18' is the minor revision of the 3.18 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 3.18, 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, linux318):

# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux318.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/linux318.preset
...
ALL_kver="/boot/vmlinuz-linux318"
...
default_image="/boot/initramfs-linux318.img"
...
fallback_image="/boot/initramfs-linux318-fallback.img"

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

# mkinitcpio -p linux318

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 3.18 custom kernel installed above would be:

# mkinitcpio -k linux-3.18.28 -g /boot/initramfs-linux318.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, Gummiboot 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.