> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizing the Kernel

> Guide on how to customize the kernel used by Talos Linux.

export const release_branch_v1_13 = 'release-1.13';

export const VersionWarningBanner = () => {
  const latestVersion = "v1.13";
  const [latestUrl, setLatestUrl] = useState(null);
  const [currentVersion, setCurrentVersion] = useState(null);
  const [isBeta, setIsBeta] = useState(false);
  const parseVersion = v => v.replace("v", "").split(".").map(Number);
  const isGreaterVersion = (a, b) => {
    const [aMajor, aMinor] = parseVersion(a);
    const [bMajor, bMinor] = parseVersion(b);
    if (aMajor > bMajor) return true;
    if (aMajor === bMajor && aMinor > bMinor) return true;
    return false;
  };
  useEffect(() => {
    if (typeof window === "undefined") return;
    const {pathname, hash, search} = window.location;
    const match = pathname.match(/\/talos\/(v\d+\.\d+)\//);
    if (!match) return;
    const detectedVersion = match[1];
    if (detectedVersion === latestVersion) return;
    setCurrentVersion(detectedVersion);
    if (isGreaterVersion(detectedVersion, latestVersion)) {
      setIsBeta(true);
    }
    const newPath = pathname.replace(`/talos/${detectedVersion}/`, `/talos/${latestVersion}/`);
    setLatestUrl(`${newPath}${search}${hash}`);
  }, []);
  if (!latestUrl || !currentVersion) return null;
  return <div className="not-prose sticky top-6 z-50 my-6">
      <div className="border border-yellow-500/30 bg-yellow-500/10 px-4 py-3 rounded-xl">
        <div className="text-sm">
          {isBeta ? <>
              ⚠️ You are viewing a <strong>beta version</strong> of Talos ({currentVersion}).
              This version may be unstable.
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View latest stable version {latestVersion} →
              </a>
            </> : <>
              ⚠️ You are viewing an older version of Talos ({currentVersion}).
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View the latest version {latestVersion} →
              </a>
            </>}
        </div>
      </div>
    </div>;
};

<VersionWarningBanner />

Talos Linux configures the kernel to allow loading only cryptographically signed modules.
The signing key is generated during the build process, it is unique to each build, and it is not available to the user.
The public key is embedded in the kernel, and it is used to verify the signature of the modules.
So if you want to use a custom kernel module, you will need to build your own kernel, and all required kernel modules in order to get the signature in sync with the kernel.

## Overview

In order to build a custom kernel (or a custom kernel module), the following steps are required:

* build a new Linux kernel and modules, push the artifacts to a registry
* build a new Talos base artifacts: kernel and initramfs image
* produce a new Talos boot artifact (ISO, installer image, disk image, etc.)

We will go through each step in detail.

## Building a custom kernel

First, you might need to prepare the build environment, follow the [Building Custom Images](./building-images) guide.

Checkout the [`siderolabs/pkgs`](https://github.com/siderolabs/pkgs) repository:

<CodeBlock lang="sh">
  {`
    git clone https://github.com/siderolabs/pkgs.git
    cd pkgs
    git checkout ${release_branch_v1_13}
    `}
</CodeBlock>

The kernel configuration is located in the files `kernel/build/config-ARCH` files.
It can be modified using the text editor, or by using the Linux kernel `menuconfig` tool:

```shell theme={null}
make kernel-menuconfig
```

The kernel configuration can be cleaned up by running:

```shell theme={null}
make kernel-olddefconfig
```

Both commands will output the new configuration to the `kernel/build/config-ARCH` files.

Once ready, build the kernel any out-of-tree modules (if required, e.g. `zfs`) and push the artifacts to a registry:

```shell theme={null}
make kernel REGISTRY=127.0.0.1:5005 PUSH=true
```

By default, this command will compile and push the kernel both for `amd64` and `arm64` architectures, but you can specify a single architecture by overriding
a variable `PLATFORM`:

```shell theme={null}
make kernel REGISTRY=127.0.0.1:5005 PUSH=true PLATFORM=linux/amd64
```

This will create a container image `127.0.0.1:5005/siderolabs/kernel:$TAG` with the kernel and modules.

## Building Talos base artifacts

Follow the [Building Custom Images](./building-images) guide to set up the Talos source code checkout.

If some new kernel modules were introduced, adjust the list of the default modules compiled into the Talos `initramfs` by
editing the file `hack/modules-ARCH.txt`.

Try building base Talos artifacts:

```shell theme={null}
make kernel initramfs PKG_KERNEL=127.0.0.1:5005/siderolabs/kernel:$TAG PLATFORM=linux/amd64
```

This should create a new image of the kernel and initramfs in `_out/vmlinuz-amd64` and `_out/initramfs-amd64.xz` respectively.

> Note: if building for `arm64`, replace `amd64` with `arm64` in the commands above.

As a final step, produce the new `imager` container image which can generate Talos boot assets:

```shell theme={null}
make imager PKG_KERNEL=127.0.0.1:5005/siderolabs/kernel:$TAG PLATFORM=linux/amd64 INSTALLER_ARCH=targetarch
```

> Note: if you built the kernel for both `amd64` and `arm64`, a multi-arch `imager` container can be built as well by specifying `INSTALLER_ARCH=all` and `PLATFORM=linux/amd64,linux/arm64`.

## Building Talos boot assets

Follow the [Boot Assets](../../platform-specific-installations/boot-assets) guide to build Talos boot assets you might need to boot Talos: ISO, `installer` image, etc.
Replace the reference to the `imager` in guide with the reference to the `imager` container built above.

> Note: if you update the `imager` container, don't forget to `docker pull` it, as `docker` caches pulled images and won't pull the updated image automatically.
