User:Pietinger/Tutorials/Manual kernel configuration

From Gentoo Wiki
Jump to:navigation Jump to:search
Note
Even though this page is in the user namespace, corrections and additions are much appreciated! This is simply wiki policy, this page can be moved to the main wiki as soon as it achieves critical mass more.

Here I gather all informations and links I miss in our AMD64 Handbook.

Tutorial: Manual kernel configuration

This tutorial gathers all links and informations needed for a manual kernel configuration.

Only our default sys-kernel/gentoo-sources will be used.

I present a link here at this prominent place because in my opinion every linux user should know this: https://www.youtube.com/watch?v=2TZe5EROFhE

It is named: "Demystifying the Linux kernel security process" from Greg KH. If you dont know Greg KH then read: [[1]] ;-)

This is an updated talk by Greg; the first 20 minutes are similar to the talk from a year ago; after that he goes into CVEs: https://www.youtube.com/watch?v=Rg_VPMT0XXw

Personal foreword

A first-time manual configuration of the kernel is not done in a few minutes. If you follow my advice to read the help, it may take a few hours. But this effort is unique. Later you will apply new kernel versions with make oldconfig, which is done in a few minutes (when switching to a new major version), or even instantaneously (if only changing the minor version).

Do not try to configure a “perfect” kernel at the first attempt. This will hardly be possible and is not even necessary. The most important thing to start with is that it boots at all. If the sound doesn't work yet, that's not a problem - you can make up for it later. The sound is also the most common problem with a kernel configuration; if it doesn't work straight away you're in good company and don't have to be frustrated; so far we've managed to get every exotic part to work. The more often you “visit” the kernel configuration, the greater your understanding of where, which parts and how they belong together.

One more word about security: The less software you use, the fewer potential attack surfaces a system offers. This also applies to the kernel, which we therefore want to keep as lean as possible. This means: If you are unsure whether you need a parameter, it is better to leave it out. If something is missing, you will notice immediately - because something will not work. But if you include something that will never be needed again, you won't even notice it. So: If in doubt, leave it out for now or only configure it as module <M> (if this is possible).

Big request: First read this article completely before you do anything. Then start from the beginning and look for all the links. Then read these linked articles. Only then really start with the configuration.

What you have to know / What you should read

Basics

Our AMD64 Handbook (currently) recommends make nconfig for kernel configuration. I recommend the old make menuconfig, as there are more options here, e.g. display invisible options with z.

You can search for kernel modules in make menuconfig by pressing /. Typing a leading "CONFIG_" is not necessary.

You must enable all modules which kernel needs to find its root partition static <*> into your kernel and not as <M>odule !

Many options in your kernel configuration depends on other options. Many options selects one or more other options. Sometimes a option is not visible whilst others are not enabled. My recommendation for later: Look into every <Help> of an option you want to enable or disable and read not only the help text ... moreover read also all information in the last section, where you can find something like "Selects:" and/or "Selected by:" and/or "Depends on:". These will show you the dependencies to (or from) other modules. One example:

Cannot deactivate an option

I want to disable an option marked with -*- but make menuconfig does not allow it.

But you can look in the <Help> and you will find the reason for this there. An example:

KERNEL
[*] Networking support  --->
    Networking options  --->
        -*-   The IPv6 protocol  --->

The <Help> says:

Selected by [y]:
  - GENTOO_LINUX_INIT_SYSTEMD [=y] && GENTOO_LINUX [=y] && GENTOO_LINUX_UDEV [=y]

If you now look in the <Help> of GENTOO_LINUX_INIT_SYSTEMD:

KERNEL
Gentoo Linux  --->
    Support for init systems, system and service managers  --->
        [*] systemd

... you will find the resaon:

Selects: AUTOFS_FS [=y] && ... IPV6 [=y]

But I need systemd and don't want IPv6 - what can I do? It's quite simple: You disable GENTOO_LINUX_INIT_SYSTEMD and can then also disable IPv6 ... but be careful: You now have to enable everything else that GENTOO_LINUX_INIT_SYSTEMD has enabled itself (see "Selects:"). An easier way to disable IPv6 is to use a kernel command line parameter: User:Pietinger/Tutorials/Kernel_Commandline_Parameter#Parameter:_ipv6.disable.3D1

Never edit .config

I quote from this thread: [2]

Horrible things happen if you use a text editor on the kernel .config file.

If you are lucky, you will get a kernel that won't build. If not, it may be broken in ways that nobody has ever seen before.

Use menuconfig and its search. Press / If the symbol you want is not found, press the 'z' key to toggle the display of hidden symbols. Search again.

The search will find it but you still can't select it. Read the help on the menu option. Pay attention to the Depends on: That boolean expression must be true before the item can be selected. Select other things so that your symbol can be selected.

Read the Selects: too. Now ask yourself if you would have got that right with your text editor?

The usual advice to someone who has used a text editor on the .config file is to throw it away and start it again.

More informations

If you have never done a manual kernel configuration you really should read all these before starting:

Before you start

1. Choose which kernel version you want and install it. This may help you: User:Pietinger/Tutorials/Selecting_a_convenient_kernel_version

2. Gather some informations: Boot with Handbook:AMD64/Installation/Media#The_Gentoo_LiveGUI (*), or simply with an unchanged Gentoo distribution-kernel if you have already installed it, and do (as user root):

root #lspci -nnk

Notice all modules from line Kernel driver in use: XXXX. Maybe read beforehand: User:Pietinger/Overview_of_System_Information#lspci_-nnk

root #lsmod | more

Notice all modules.

root #dmesg | grep firmware

Notice all firmware files (with directory).

For an INTEL or AMD system ask also:

root #dmesg | grep stepping

Notice family, model and stepping.

(*) It MUST be Gentoo LiveGUI (= don't use the minimalCD or any bootCD from other distributions) because we have a kernel patch (enabled by default in our bootCD; also enabled by default in our distribution kernel) which shows all loaded firmware:

KERNEL
Gentoo Linux  --->
    [*] Print firmware information that the kernel attempts to load

BIOS

For current reasons ... and because it is unfortunately not mentioned anywhere: No Linux likes "Fast Boot" activated in the BIOS ... check it and deactivate it. Other settings such as SecureBoot (must also be disabled) or CSM mode (also off) have already been mentioned in our AMD64 handbook.

Do I need a "make defconfig" before I start ?

The Kconfig system of the kernel is a bit tricky. There are dependencies and also defaults. But as soon as a created configuration is saved, there is no way back. What I mean: If a kernel module (A) requires another (B) and therefore selects it, B is automatically enabled as soon as you enable A. If you save this now, A and B are saved as enabled. If you now go back into the configuration and deactivate A again, B will NOT be disabled automatically. B REMAINS activated because it was saved as such. This behavior means that there is a clear difference whether you do a “make menuconfig” in a directory without an existing .config file (= freshly emerged gentoo-sources), or whether you do a “make menuconfig” after a “make defconfig” (because the "make defconfig" creates a .config file and already saves something). The same applies to all “defaults” specified by Kconfig. However, once saved, the defaults are no longer used. I also tried to explain this in a forum thread. So if you want to take a closer look, read this: https://forums.gentoo.org/viewtopic-t-1168856.html

The answer to the above question is therefore a definite NO.

On the contrary: A “make menuconfig” with a freshly emerged gentoo-sources is advantageous.

For example: If you switch off WLAN, all (now no longer) required crypto modules are automatically deactivated. This is no longer possible after a “make defconfig”, because the Crypto module is then already saved as enabled. I have also used this behavior here to configure something that is not actually intended: User:Pietinger/Tutorials/Kernel_Hardening_with_KSPP#But_I_need_Hibernation

Introduction

If you have never done a make menuconfig it can be confusing what do and where to start. Let me say some general words about the main menu (just read it - don't start yet):

The last line Gentoo Linux ---> exists only in our gentoo-sources. If you have other sources (e.g. vanilla) you will miss this option. If you are using OpenRC as init system you have nothing to do here. If you are using systemd you must enable one option - which is usually already enabled by your systemd-stage3. So we do only a check here if it is correct:

KERNEL Kernel
Gentoo Linux  --->
    Support for init systems, system and service managers  --->
        [*] OpenRC, runit and other script based systems and managers
        [ ] systemd

Although our AMD64 Handbook says: “It does not hurt to have support for both init systems enabled.” I do not recommend enabling "systemd" if you have an OpenRC system: Believe me, all the really important ones are already activated by default, or we will activate them here, and we don't want the additional ones (BPF_SYSCALL, CGROUP_BPF).

In the next last option Kernel hacking ---> you really should only change something with specific instructions !

Also you will never need Library routines ---> because all necessary modules here will be selected (=enabled) automatically by other options - with one exception: Here you can change the selected font. At the moment you are not able to do this because one other option is not enabled. If you press z in this menu you can see this is disabled at the moment:

KERNEL Kernel
Library routines  --->
    - - Select compiled-in fonts

Now look into the help of this option and you will see why it is not possible:

Depends on: FONT_SUPPORT [=y] && (FRAMEBUFFER_CONSOLE [=n] || STI_CONSOLE [=n])

Now leave the help, press z again (toggle function) and exit this menu. Yes, we really need FRAMEBUFFER_CONSOLE - it is a MUST HAVE - and we do this in the next chapter.

The same is true for Cryptographic API --->. Usually all necessary modules here will be selected automatically by enabling other kernel (*) modules (with one exception: dmcrypt; but you will find instructions in every description for dmcrypt). At the moment many options are enabled because some other options are still enabled (e.g. WLAN, IPSec). If we disable WLAN or IPv6 (or both) we can disable also some of these cryptographics modules later.

(*) This is not true for user applications. If an user application - like iwd - needs some crypto modules you will always need a description which crypto modules you have to enable. In most cases, at least this is required:

KERNEL Kernel
-*- Cryptographic API  --->
    Crypto core or helper  --->
        -*- Cryptographic algorithm manager
        <*> Userspace cryptographic algorithm configuration

    Userspace interface  --->
        <*> Hash algorithms
        <*> Symmetric key cipher algorithms
        [ ] Obsolete cryptographic algorithms

One option we have in the main menu you should think about at last when all is done: [*] Enable loadable module support ---> Why ? I recommend to configure all necessary modules static into the kernel - because you will need your ethernet and graphics module always ... If we do this then we dont need a loadable module support anymore and we can disable this ... and have now a monolithic kernel. Why we want do this ? Because it is more secure. Also KSPP recommends to disable module support or work with signed modules. But for the moment we dont change it and you can think about later.

We will get to know all the other menu items in the next chapter.

Configuration

Basic Settings

Start with our Handbook:AMD64/Installation/Kernel#Alternative:_Manual_configuration (just read it). I am missing some important options. In the past I had here some options for kernel version 5.15. I have separated it out so that I can differentiate between the latest stable (*) and the latest LTS kernel (* stable in the sense of the Linux kernel developers - not in the sense of Gentoo; in Gentoo the latest LTS kernel is labeled as stable).

Latest LTS kernel: User:Pietinger/Tutorials/Manual_Configuring_Kernel_Version_6.6

Latest stable kernel (currently 6.11): User:Pietinger/Experimental/Manual_Configuring_Current_Kernel

( Outdated link: User:Pietinger/Tutorials/Manual_Configuring_Kernel_Version_6.1 )

After this come back to this page, because you have to do a little bit more. In all Links you will get now, you will need only the chapter Kernel Configuration:

Graphics adapter

Choose from these links:

If you have a kernel of version 6.10 or higher, note that many settings for the graphics can now be found here (in DRM):

KERNEL Kernels 6.10+
Device Drivers  --->
    Graphics support  --->
        <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
            ...

Sound and others

Although we already have a wiki article about ALSA, I would like to present the complete menu here to get a minimal sound configuration. If your sound works with it, no further steps are necessary. If not, you have a system that needs either USB support or even ALSA for SoC audio support. Here you will need your “lsmod” query to load additional sound modules.

KERNEL Kernel
Device Drivers  --->
    <*> Sound card support  --->
        <*>   Advanced Linux Sound Architecture  --->

--- Advanced Linux Sound Architecture
[ ]   Enable OSS Emulation
[*]   PCM timer interface
<*>   HR-timer backend support
# You need UDEV for this. Read the <Help>
-*-   Dynamic device file minor numbers
(32)    Max number of sound cards
[ ]   Support old ALSA API
[*]   Sound Proc FS Support
[*]     Verbose procfs contents
[ ]   Verbose printk
[*]   Fast lookup of control elements
# Not absolutely necessary - there are some useful messages in “dmesg” - your decision
[*]   Debug
[ ]     More verbose debug
[ ]     Enable PCM ring buffer overrun/underrun debugging
[ ]   Validate input data to control API
[ ]   Enable debugging feature for control API
<*>   Sequencer support
<*>     Sequencer dummy client
[*]     Use HR-timer as default sequencer timer
[ ]     Support for UMP events
[ ]   Generic sound devices  ----
[*]   PCI sound devices  --->
      HD-Audio  --->
       <*> HD Audio PCI
       [*] Build hwdep interface for HD-audio driver
       [*] Allow dynamic codec reconfiguration
       <*> Build Realtek HD-audio codec support
# If you want to use your speakers in the monitor connected via HDMI or DisplayPort. This selects "Dynamic device file minor numbers"
       <*> Build HDMI/DisplayPort HD-audio codec support
       -*- Enable generic HD-audio codec parser
       (0) Default time-out for HD-audio power-save mode
[ ]   USB sound devices  ----
# If you have already deactivated PCMCIA, this option will no longer appear
[ ]   PCMCIA sound devices  ----
< >   ALSA for SoC audio support  ----
[ ]   X86 sound devices  ----
# if you have already deactivated every VRTIO module, this option will no longer appear
< >   Virtio sound driver

This should be done also:

Optional settings


At last you can check all other modules you have in your lists from lspci -k and lsmod by searching with /

And last but not least, you should read this:

Driver needs Firmware

Some kernel modules need firmware (mostly Graphics adapter, WLAN and some Ethernet). If you use one of these kernel modules you should emerge Linux_firmware#Emerge. Now you have two options for this module:

a) If you have configured your module as <M>odule, then the kernel is able to load firmware for this module at boot-time from /lib/firmware, because all <M>odules will be initalised after kernel has access to its root partition.

b) If you have configured your module static <*> into your kernel, then you must do a little bit more. These modules will be initalised before kernel has access to its root partition and therefore is not able to load firmware from /lib/firmware.

You would get an error message in your "dmesg" saying Direct firmware load for xxxx/xxx failed with error -2. Therefore you must compile all needed firmware also into your kernel (example):

KERNEL
Device Drivers  --->
    Generic Driver Options  --->
        Firmware Loader  --->
            [*] Firmware loading facility
            (i915/skl_dmc_ver1_27.bin intel-ucode/06-5e-03) Build named firmware blobs into the kernel binary

With these settings you will copy these firmware files "INTO" your kernel (when you compile your kernel with "make") and now the kernel is able to "load" these firmware files "from itself" without needing access to /lib/firmware at boot-time.

Yes, it is the same place where you can also define the microcode blob; if more than one firmware blobs must be loaded you separate them with a space.

Every Wiki article recommends to use option (a) because it is very easy. Option (b) is necessary if you want to build a monolithic kernel without module support, or if you have other reasons to build a module (which needs firmware) static into your kernel.

In some wiki pages you will find examples of necessary firmware files you need when using option (b), like this example:

amdgpu/oland_{uvd,smc,rlc,pfp,me,mc,ce}.bin

DONT try to put this into your path; it will not work because you can add only single files; many readers of the page AMDGPU dont notice the little sentence: "Use echo to expand the filenames" ... yes, you can only add:

amdgpu/oland_uvd.bin amdgpu/oland_smc.bin amdgpu/oland_rlc.bin amdgpu/oland_pfp.bin amdgpu/oland_me.bin amdgpu/oland_mc.bin amdgpu/oland_ce.bin

If you use option (b) you cannot use compressed firmware files. Read the <Help> of:

KERNEL
Device Drivers  --->
    Generic Driver Options  --->
        Firmware Loader  --->
            [ ]   Enable compressed firmware support

It says quite clearly: Compressed firmware support does not apply to firmware images that are built into the kernel image (CONFIG_EXTRA_FIRMWARE).

This also means that you must NOT emerge the package "linux-firmware" with the use-flags for compression (compress-xz, compress-zstd) !

Starting with a clean environment

If you have done already some configurations and want to start from beginning you can clean up all with

root #cd /usr/src/linux
root #make distclean
root #make menuconfig

The first command (distclean) deletes all old data - also your .config file !

Cheat Sheets

These are only valid for a completely (*) manually configured kernel according to our Handbook:AMD64/Installation/Kernel#Alternative:_Manual_configuration and you are using grub as bootmanager.

(*) means: You are not using an intramfs from genkernel or dracut !

Mounting (and unmounting) the boot partition is only necessary if you have an old installation where you mount your ESP to /boot instead of /efi. If you have questions about this then please read: https://forums.gentoo.org/viewtopic-t-1165115-highlight-.html

  • Updating to a new kernel version:
root #emerge -1uvDp gentoo-sources
root #( mount /boot )
root ## go into the directory of the new kernel:
root #cd /usr/src/linux-X.Y.Z-gentoo
root #cp /usr/src/linux/.config .
root #make oldconfig
root ## For X use nr. of your CPU cores:
root #make -j X
root #make install
root #make modules_install
root ## Maybe you want to backup your configuration. I do this into:
root #cp .config /etc/MY/config-X-Y-Z
root #grub-mkconfig -o /boot/grub/grub.cfg
root #eselect kernel list
root #eselect kernel set X
root #( umount /boot )
root #reboot
  • Changing the configuration of your used kernel:
root #( mount /boot )
root #cd /usr/src/linux
root #make menuconfig
root #make -j X
root #make install
root #make modules_install
root #cp .config /etc/MY/config-X-Y-Z-revA
root #grub-mkconfig -o /boot/grub/grub.cfg
root #( umount /boot )
root #reboot

If you ever have problems with a make install, then read Installkernel (because this package creates some routines that are then started by a make install"), OR simply copy the kernel yourself to /boot (=instead using make install):

root #cp arch/x86/boot/bzImage /boot/vmlinuz-X.Y.Z-gentoo

(Yes, actually you don't need the *map* and config* file in /boot).

What is "make oldconfig" ?

This will do three things:

1. Remove elements that are not any more in the new kernel (i.e. kernel developers have removed an option in the new kernel).

2. Keep the settings that are valid for the new kernel (takeover).

3. Ask about all the new settings (only it there are new options; seldom with a change of the minor version; almost always with a new major version).

The prompt for new settings will show y/m/n/?

Yes makes the option built in, M makes it a module, No leaves it out and ? shows the help.

Not all four options are shown every time. If an option cannot be a module then of course M is missing.

One of y/n/m will be a capital letter. This is the default, it may or may not be what the system needs. If you are unsure, accept the default with <Return> or read the corresponding articles in: User:Pietinger/Experimental.

Kconfig / KSPP ?

View the content of /usr/src/linux/distro/Kconfig ... and examine if you have really enabled some security options. Take a look into User:Pietinger/Tutorials/Kernel_Hardening_with_KSPP

CONFIG_DEBUG ?

If you do this search you will see many lines:

root #grep DEBUG /usr/src/linux/.config

Most of them are disabled with # CONFIG_* is not set - some are enabled. If experienced users tell you "dont enable debugging", they are usually correct. But not in every case, because for some settings you dont have an influence like all CONFIG_ARCH_* and CONFIG_HAVE_*. An Intel X86_64 system gives you these enabled:

FILE /usr/src/linux/.config
CONFIG_X86_DEBUGCTLMSR=y (6.1)
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_PNP_DEBUG_MESSAGES=y  (default in 6.1)
CONFIG_DEBUG_INFO_NONE=y  (default in 6.1)
CONFIG_ARCH_HAS_DEBUG_WX=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_STACK_USAGE (default in 6.6 but unnecessary => disable it)
CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y  (6.1)
CONFIG_DEBUG_PREEMPT=y  (default in 6.1) (no default in 6.6 anymore => disable it ;-)
CONFIG_LOCK_DEBUGGING_SUPPORT=y (default in 6.1)
CONFIG_DEBUG_BUGVERBOSE=y (default in 6.1)

Two more options depends on:

FILE /usr/src/linux/.config
# Enabled by selecting CONFIG_EXPERT
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y

And if you hopefully harden your kernel with KSPP you will get automatically these (example X86_64 system):

FILE /usr/src/linux/.config
# KSPP: Allow allocator validation checking to be enabled (see "slub_debug=P" below).
CONFIG_SLUB_DEBUG=y

# KSPP: Report any dangerous memory permissions (not available on all archs).
CONFIG_DEBUG_WX=y

# KSPP: Perform additional validation of various commonly targeted structures.
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CREDENTIALS=y

Now you have 13 (20 with 6.1) (19 with 6.6) DEBUG-options enabled and this is completely fine ! If you find any other lines with enabled DEBUG you should ask yourself why you have enabled them. Okay, enabling CONFIG_SND_DEBUG doesnt hurt ... you will get more informations about your sound. But all others should be enabled only for special investigations (== if you know what you are doing). A really bad example (because of security risk) is:

FILE /usr/src/linux/.config
CONFIG_DEBUG_FS=y

It is only necessary if you want do special operations, e.g. using PowerTOP to examine your machine. Dont worry if you get messages about a missing DEBUG_FS in your dmesg ... I have also some:

intel-lpss 0000:00:15.0: Failed to create debugfs entries

Comparison between two kernel configuration files

Of course you can use "diff" or any other grapical tool like "kompare" (from KDE), but a really great tool you will find here: [[4]]

Compare the log of your system startup

You can do this by using the -t parameter with "dmesg" when redirecting the output of "dmesg" to a file. Example:

root #dmesg -t > kernel-log-6.1.46

This way no timestamps are logged at the beginning of the line and you can compare your different logs of a system boot. Use this also when you change BIOS options (just try to disable or enable VT-D and check the changes in the log). I found this simple and ingenious approach here: https://forums.gentoo.org/viewtopic-p-8517143.html#8517143

Useful links


Note
This is my second try for creating a wiki article. Maybe some formatting is wrong. Because it is a tutorial and not a reference guide I ignored the standard of not writing in first or second person. Yes, my english is very poor.