Skip to content

Automated Linux kernel configuration and compilation script

Notifications You must be signed in to change notification settings

jiyuzh/kernel-compile

Repository files navigation

Compile HOWTO

Kernel Config Script

  1. Run configure.sh: ./configure.sh {localver_name} [{config_type}] {ext_args}

    🔀 You may override lsmod result with a lsmod.override file

    📋 See in-script help for usage

  2. Enable experiment-delicated kernel configs

  3. Do other config edits

  4. ln .config config.example

    🔀 You may skip this step

    📋 This command creates a hard link, allowing git to track current configs through config.example

    ⚠️ The committed config is for reference only, since module requirements may differ

  5. Use build script to compile

Kernel Build Script

  1. Run build.sh: ./build.sh

Kernel Installation Script

  1. Run install.sh: ./install.sh

  2. Reboot

Kernel List Installed Script

  1. Run where.sh: sudo ./where.sh

Kernel Uninstall Script

  1. Run uninstall.sh: sudo ./uninstall.sh {kernel_version}

Kernel Validator Script

Run validate.sh: ./validate.sh {ext_args}

Module Build Script

  1. Run modbuild.sh: ./modbuild.sh

Module Installation Script

  1. Run modinstall.sh: ./modinstall.sh

Distrubited Kernel Build Script

  1. Run distbuild.sh: ./distbuild.sh

Prepare LSMOD

# Also, you can preserve modules in certain folders
# or kconfig files by specifying their paths in
# parameter LMC_KEEP.

target$ lsmod > /tmp/mylsmod
target$ scp /tmp/mylsmod host:/tmp

host$ make LSMOD=/tmp/mylsmod \
           LMC_KEEP="drivers/usb:drivers/gpu:fs" \
           localmodconfig

Script Manual

configure.sh

The script will try to build a linux kernel configure file in current working directory.

It will only work when invoked at the root directory of a valid linux source tree.

The script will generate new config file at $PWD/.config

./configure.sh {localver_name} [{{config_template}}] [{config_type}] {ext_args}
Automatic kernel configuration generator for Linux 5.x
    localver_name: Value provided to CONFIG_LOCALVERSION, without leading dash
    config_template: The template file to use with this script, can be a URL, a file path relative to current folder, or default config folder
    config_type: The fullness of the config, the default value is 'lite'
        full: Do not remove unused modules
        lite: Remove modules that are not loaded
    ext_args: A series of arguments tweaking the extension options
              The default is to use all available extensions

This script will invoke extensions. See details below.

This script will also look for these files in $SCRIPT_DIR:

  • ubuntu-20.04-5.4.config: The base config file. The script will derive new config files from this file.

This script will also look for these files in $PWD:

  • lsmod.override: The lsmod override file. If this file exists, the script will source this file (instead of running lsmod command) when invoking make localmodconfig.

  • local-configure.sh: Local config modification script. If this file exists, the script will invoke it to modify the generated kernel config. This file will be invoked after all automated modification extensions.

  • .config: Generated config file. The script will write the result into this file. If this file already exists, the script will backup it first.

  • .config.newdef: Derived new definitions record file. If any config item is not described in the base config file, it's name and default value will be written to this file.

distcompile.sh

To use this script, you must have distcc installed on both client and server first.

It is strongly recommended to compile distcc from source. Here is a sample script to do this:

sudo apt install -y gcc make python3 python3-dev libiberty-dev autoconf checkinstall

wget https://github.com/distcc/distcc/releases/download/v3.4/distcc-3.4.tar.gz
tar xf distcc-3.4.tar.gz
cd distcc-3.4

./autogen.sh
./configure
make

sudo checkinstall
make installcheck
sudo update-distcc-symlinks

After that, please configure distcc host in ~/.ssh/config and ~/.distcc/hosts.

Please order the hosts in ~/.distcc/hosts from fastest to slowest. The syntax is @<ssh_host>/<parallel_allowance>.

Here are some examples:

# ~/.ssh/config

Host distcc.server1
    HostName 192.168.0.2
    User distcc
    IdentityFile ~/.ssh/id_rsa
# ~/.distcc/hosts

localhost/12
@distcc.server1/36

validate.sh

This script will validate current kernel config with a series of validator.

./validate.sh [nofail] {ext_args}
Automatic kernel configuration validator for Linux 5.x
    nofail: Indicate that the script shall not return with error code
    ext_args: A series of arguments tweaking the extension options
              The default is to use all available extensions

This script will validate the first config file encountered in this list:

$PWD/.config
/proc/config.gz
/boot/config-$(uname -r)
/usr/src/linux-$(uname -r)/.config
/usr/src/linux/.config

This script will invoke extensions. See details below.

This script will also look for these files in $PWD:

  • local-validate.sh: Local config validation script. If this file exists, the script will invoke it to validate the kernel config.

Extension arguments (ext_args)

The extension argument list is a list of rules on which extension to enable/disable.

The argument list is always interperted from left to right. When conflicts observed, the rightmost option shall prevail.

The extension manager will ignore any unrecognized arguments and extension names.

Extension names are case sensitive.

The default behavior is to include all extensions, except those which declared # ext-default-enabled: no in their extension script.

Available arguments:

--no-all: Disable all extensions
--with-all: Enable all extensions
--no-{ext_name}: Disable the extension named {ext_name}
--with-{ext_name}: Enable the extension named {ext_name}

Example:

#   Enable all default extensions except libvirt
--no-libvirt

# Overwrite rule
#   Enable all extensions except docker and hyperv
--with-all --no-docker --no-hyperv

#   Enable docker only
--no-all --with-docker

#   Enable libvirt only
--with-docker --with-hyperv --no-all --with-libvirt

Extensions

The scripts are extensible through different extensions.

Extensions shall be placed in ./extension/ of the script folders, with specific naming convention.

The name shall be {ext_name}-{invoker_name}.sh. For example, a docker extension to be invoked by validate.sh shall named docker-validate.sh.

Extension names are case sensitive.

Reserved ext_names:

These values are reserved and shall not be ext_name:
    <empty>, all, base, local
configure.sh

enable_flags {flag_list}: Enable a list of flags

module_flags {flag_list}: Make module a list of flags

disable_flags {flag_list}: Disable a list of flags

set_flag_str {flag} {value}: Set flag value to a double-quoted string

set_flag_num {flag} {value}: Set flag value to a number

kern_ver_ge {maj} [{min}] [{pth}] [{exa}]: Evaluate to true when the kernel version is greater than or equal to the given value

$KERNEL_MAJOR: Major version of the kernel

$KERNEL_MINOR: Minor version of the kernel

$KERNEL_PATCH: Patch level of the kernel

$KERNEL_EXTRA: Extra part of the version string of the kernel before configuration start

validate.sh

This script provides the following special global variables and functions:

check_flags {flag_list}: Require a list of flags to be enabled (or as module) in the checking kernel.

check_yes_flags {flag_list}: Require a list of flags to be enabled (and not as module) in the checking kernel.

check_no_flags {flag_list}: Require a list of flags to be not enabled in the checking kernel.

check_num_eq {flag} {value}: Require a numeric flags equal to the given value in the checking kernel.

check_str {flag} {value}: Require a string flags equal to the given value in the checking kernel.

check_arch {arch}: Require the architecture of the running environment.

check_command {command}: Require a command to present in the running environment.

check_device {path}: Require a device to present in the running environment.

kern_ver_ge {maj} [{min}] [{pth}] [{exa}]: Evaluate to true when the checking kernel version is greater than or equal to the given value.

$KERNEL_MAJOR: Major version of the checking kernel.

$KERNEL_MINOR: Minor version of the checking kernel.

$KERNEL_PATCH: Patch level of the checking kernel.

$KERNEL_EXTRA: Extra part of the version string of the checking kernel.

$EXITCODE: The return code of current validator. A non-zero value indicates error. All check_* provided by this script will set $EXITCODE to 1 upon failure.

Appendix

Manual Configuration Steps

  1. Download standard config (local copy)

  2. make listnewconfig | tee .config.newdiff

    📋 List and track newly added configs and their default value

  3. make olddefconfig

    🔀 Or make oldconfig to tweak each config manually

    📋 Apply default values to newly added configs

  4. make localmodconfig

    📋 Remove uncessary modules

    ⚠️ Make sure all necessary system functionalities are used at least once before, or prepare a LSMOD file

  5. echo '+' > .scmversion

    📋 Force append + to version number, i.e. 5.18.0+

    ⚠️ Will also nullify CONFIG_LOCALVERSION_AUTO

  6. make menuconfig

    🔀 Or make xconfig for graphic interface

    1. CONFIG_SYSTEM_TRUSTED_KEYS=""

      CONFIG_SYSTEM_REVOCATION_KEYS=""

      📋 Remove cert requirment

    2. CONFIG_SECURITY_DMESG_RESTRICT=n

      📋 Allow non-sudo dmesg

    3. CONFIG_LOCALVERSION="<VALUE>"

      📋 Add kernel version suffix, e.g. -custom

    4. Adapt config for special software

      📋 libvirt and docker requirements

    5. Enable experiment-delicated kernel configs

    6. Do other config edits

  7. ln .config config.example

    🔀 You may skip this step

    📋 This command creates a hard link, allowing git to track current configs through config.example

    ⚠️ The committed config is for reference only, since module requirements may differ

  8. Use build script to compile

About

Automated Linux kernel configuration and compilation script

Resources

Stars

Watchers

Forks