Skip to content

Commit

Permalink
Merge pull request #207095 from ncfavier/linux-custom-kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
ncfavier authored Dec 27, 2022
2 parents b25ad6c + a8fd50b commit 3fc528f
Show file tree
Hide file tree
Showing 22 changed files with 189 additions and 160 deletions.
15 changes: 15 additions & 0 deletions lib/tests/misc.nix
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ runTests {
expected = [ "1" "2" "3" ];
};

testPadVersionLess = {
expr = versions.pad 3 "1.2";
expected = "1.2.0";
};

testPadVersionLessExtra = {
expr = versions.pad 3 "1.3-rc1";
expected = "1.3.0-rc1";
};

testPadVersionMore = {
expr = versions.pad 3 "1.2.3.4";
expected = "1.2.3";
};

testIsStorePath = {
expr =
let goodPath =
Expand Down
15 changes: 15 additions & 0 deletions lib/versions.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,19 @@ rec {
builtins.concatStringsSep "."
(lib.take 2 (splitVersion v));

/* Pad a version string with zeros to match the given number of components.
Example:
pad 3 "1.2"
=> "1.2.0"
pad 3 "1.3-rc1"
=> "1.3.0-rc1"
pad 3 "1.2.3.4"
=> "1.2.3"
*/
pad = n: version: let
numericVersion = lib.head (lib.splitString "-" version);
versionSuffix = lib.removePrefix numericVersion version;
in lib.concatStringsSep "." (lib.take n (lib.splitVersion numericVersion ++ lib.genList (_: "0") n)) + versionSuffix;

}
83 changes: 45 additions & 38 deletions nixos/doc/manual/configuration/linux-kernel.chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,61 +82,68 @@ boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
sets the kernel's TCP keepalive time to 120 seconds. To see the
available parameters, run `sysctl -a`.

## Customize your kernel {#sec-linux-config-customizing}
## Building a custom kernel {#sec-linux-config-customizing}

The first step before compiling the kernel is to generate an appropriate
`.config` configuration. Either you pass your own config via the
`configfile` setting of `linuxKernel.manualConfig`:
You can customize the default kernel configuration by overriding the arguments for your kernel package:

```nix
custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
in super.linuxKernel.manualConfig {
inherit (super) stdenv hostPlatform;
inherit (base_kernel) src;
version = "${base_kernel.version}-custom";
configfile = /home/me/my_kernel_config;
allowImportFromDerivation = true;
};
pkgs.linux_latest.override {
ignoreConfigErrors = true;
autoModules = false;
kernelPreferBuiltin = true;
extraStructuredConfig = with lib.kernel; {
DEBUG_KERNEL = yes;
FRAME_POINTER = yes;
KGDB = yes;
KGDB_SERIAL_CONSOLE = yes;
DEBUG_INFO = yes;
};
}
```

You can edit the config with this snippet (by default `make
menuconfig` won\'t work out of the box on nixos):
See `pkgs/os-specific/linux/kernel/generic.nix` for details on how these arguments
affect the generated configuration. You can also build a custom version of Linux by calling
`pkgs.buildLinux` directly, which requires the `src` and `version` arguments to be specified.

```ShellSession
nix-shell -E 'with import <nixpkgs> {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
To use your custom kernel package in your NixOS configuration, set

```nix
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
```

or you can let nixpkgs generate the configuration. Nixpkgs generates it
via answering the interactive kernel utility `make config`. The answers
depend on parameters passed to
`pkgs/os-specific/linux/kernel/generic.nix` (which you can influence by
overriding `extraConfig, autoModules,
modDirVersion, preferBuiltin, extraConfig`).
Note that this method will use the common configuration defined in `pkgs/os-specific/linux/kernel/common-config.nix`,
which is suitable for a NixOS system.

If you already have a generated configuration file, you can build a kernel that uses it with `pkgs.linuxManualConfig`:

```nix
mptcp93.override ({
name="mptcp-local";
let
baseKernel = pkgs.linux_latest;
in pkgs.linuxManualConfig {
inherit (baseKernel) src modDirVersion;
version = "${baseKernel.version}-custom";
configfile = ./my_kernel_config;
allowImportFromDerivation = true;
}
```

ignoreConfigErrors = true;
autoModules = false;
kernelPreferBuiltin = true;
::: {.note}
The build will fail if `modDirVersion` does not match the source's `kernel.release` file,
so `modDirVersion` should remain tied to `src`.
:::

enableParallelBuilding = true;
To edit the `.config` file for Linux X.Y, proceed as follows:

extraConfig = ''
DEBUG_KERNEL y
FRAME_POINTER y
KGDB y
KGDB_SERIAL_CONSOLE y
DEBUG_INFO y
'';
});
```ShellSession
$ nix-shell '<nixpkgs>' -A linuxKernel.kernels.linux_X_Y.configEnv
$ unpackPhase
$ cd linux-*
$ make nconfig
```

## Developing kernel modules {#sec-linux-config-developing-modules}

When developing kernel modules it\'s often convenient to run
When developing kernel modules it's often convenient to run
edit-compile-run loop as quickly as possible. See below snippet as an
example of developing `mellanox` drivers.

Expand Down
105 changes: 61 additions & 44 deletions nixos/doc/manual/from_md/configuration/linux-kernel.chapter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,65 +96,82 @@ boot.kernel.sysctl.&quot;net.ipv4.tcp_keepalive_time&quot; = 120;
available parameters, run <literal>sysctl -a</literal>.
</para>
<section xml:id="sec-linux-config-customizing">
<title>Customize your kernel</title>
<title>Building a custom kernel</title>
<para>
The first step before compiling the kernel is to generate an
appropriate <literal>.config</literal> configuration. Either you
pass your own config via the <literal>configfile</literal> setting
of <literal>linuxKernel.manualConfig</literal>:
You can customize the default kernel configuration by overriding
the arguments for your kernel package:
</para>
<programlisting language="bash">
custom-kernel = let base_kernel = linuxKernel.kernels.linux_4_9;
in super.linuxKernel.manualConfig {
inherit (super) stdenv hostPlatform;
inherit (base_kernel) src;
version = &quot;${base_kernel.version}-custom&quot;;

configfile = /home/me/my_kernel_config;
allowImportFromDerivation = true;
};
pkgs.linux_latest.override {
ignoreConfigErrors = true;
autoModules = false;
kernelPreferBuiltin = true;
extraStructuredConfig = with lib.kernel; {
DEBUG_KERNEL = yes;
FRAME_POINTER = yes;
KGDB = yes;
KGDB_SERIAL_CONSOLE = yes;
DEBUG_INFO = yes;
};
}
</programlisting>
<para>
You can edit the config with this snippet (by default
<literal>make menuconfig</literal> won't work out of the box on
nixos):
See <literal>pkgs/os-specific/linux/kernel/generic.nix</literal>
for details on how these arguments affect the generated
configuration. You can also build a custom version of Linux by
calling <literal>pkgs.buildLinux</literal> directly, which
requires the <literal>src</literal> and <literal>version</literal>
arguments to be specified.
</para>
<programlisting>
nix-shell -E 'with import &lt;nixpkgs&gt; {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkg-config ncurses ];})'
<para>
To use your custom kernel package in your NixOS configuration, set
</para>
<programlisting language="bash">
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
</programlisting>
<para>
or you can let nixpkgs generate the configuration. Nixpkgs
generates it via answering the interactive kernel utility
<literal>make config</literal>. The answers depend on parameters
passed to
<literal>pkgs/os-specific/linux/kernel/generic.nix</literal>
(which you can influence by overriding
<literal>extraConfig, autoModules, modDirVersion, preferBuiltin, extraConfig</literal>).
Note that this method will use the common configuration defined in
<literal>pkgs/os-specific/linux/kernel/common-config.nix</literal>,
which is suitable for a NixOS system.
</para>
<para>
If you already have a generated configuration file, you can build
a kernel that uses it with
<literal>pkgs.linuxManualConfig</literal>:
</para>
<programlisting language="bash">
mptcp93.override ({
name=&quot;mptcp-local&quot;;

ignoreConfigErrors = true;
autoModules = false;
kernelPreferBuiltin = true;

enableParallelBuilding = true;

extraConfig = ''
DEBUG_KERNEL y
FRAME_POINTER y
KGDB y
KGDB_SERIAL_CONSOLE y
DEBUG_INFO y
'';
});
let
baseKernel = pkgs.linux_latest;
in pkgs.linuxManualConfig {
inherit (baseKernel) src modDirVersion;
version = &quot;${baseKernel.version}-custom&quot;;
configfile = ./my_kernel_config;
allowImportFromDerivation = true;
}
</programlisting>
<note>
<para>
The build will fail if <literal>modDirVersion</literal> does not
match the source’s <literal>kernel.release</literal> file, so
<literal>modDirVersion</literal> should remain tied to
<literal>src</literal>.
</para>
</note>
<para>
To edit the <literal>.config</literal> file for Linux X.Y, proceed
as follows:
</para>
<programlisting>
$ nix-shell '&lt;nixpkgs&gt;' -A linuxKernel.kernels.linux_X_Y.configEnv
$ unpackPhase
$ cd linux-*
$ make nconfig
</programlisting>
</section>
<section xml:id="sec-linux-config-developing-modules">
<title>Developing kernel modules</title>
<para>
When developing kernel modules it's often convenient to run
When developing kernel modules its often convenient to run
edit-compile-run loop as quickly as possible. See below snippet as
an example of developing <literal>mellanox</literal> drivers.
</para>
Expand Down
3 changes: 2 additions & 1 deletion nixos/lib/testing/legacy.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ let
inherit (lib) mkIf mkOption types;
in
{
# This needs options.warnings, which we don't have (yet?).
# This needs options.warnings and options.assertions, which we don't have (yet?).
# imports = [
# (lib.mkRenamedOptionModule [ "machine" ] [ "nodes" "machine" ])
# (lib.mkRemovedOptionModule [ "minimal" ] "The minimal kernel module was removed as it was broken and not used any more in nixpkgs.")
# ];

options = {
Expand Down
10 changes: 1 addition & 9 deletions nixos/lib/testing/nodes.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let
nixpkgs.config.allowAliases = false;
})
testModuleArgs.config.extraBaseModules
] ++ optional config.minimal ../../modules/testing/minimal-kernel.nix;
];
};


Expand Down Expand Up @@ -78,14 +78,6 @@ in
'';
};

minimal = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
Enable to configure all [{option}`nodes`](#test-opt-nodes) to run with a minimal kernel.
'';
};

nodesCompat = mkOption {
internal = true;
description = mdDoc ''
Expand Down
28 changes: 0 additions & 28 deletions nixos/modules/testing/minimal-kernel.nix

This file was deleted.

20 changes: 15 additions & 5 deletions pkgs/os-specific/linux/kernel/generic.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
structuredExtraConfig ? {}

, # The version number used for the module directory
modDirVersion ? version
# If unspecified, this is determined automatically from the version.
modDirVersion ? null

, # An attribute set whose attributes express the availability of
# certain features in this kernel. E.g. `{iwlwifi = true;}'
Expand Down Expand Up @@ -194,17 +195,26 @@ let
};
}; # end of configfile derivation

kernel = (callPackage ./manual-config.nix { inherit buildPackages; }) (basicArgs // {
inherit modDirVersion kernelPatches randstructSeed lib stdenv extraMakeFlags extraMeta configfile;
kernel = (callPackage ./manual-config.nix { inherit lib stdenv buildPackages; }) (basicArgs // {
inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile;
pos = builtins.unsafeGetAttrPos "version" args;

config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
});
} // lib.optionalAttrs (modDirVersion != null) { inherit modDirVersion; });

passthru = basicArgs // {
features = kernelFeatures;
inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre modDirVersion;
inherit commonStructuredConfig structuredExtraConfig extraMakeFlags isZen isHardened isLibre;
isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;

# Adds dependencies needed to edit the config:
# nix-shell '<nixpkgs>' -A linux.configEnv --command 'make nconfig'
configEnv = kernel.overrideAttrs (old: {
nativeBuildInputs = old.nativeBuildInputs or [] ++ (with buildPackages; [
pkg-config ncurses
]);
});

passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
tests = let
overridableKernel = finalKernel // {
Expand Down
4 changes: 2 additions & 2 deletions pkgs/os-specific/linux/kernel/linux-4.14.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:

with lib;

buildLinux (args // rec {
version = "4.14.302";

# modDirVersion needs to be x.y.z, will automatically add .0 if needed
modDirVersion = if (modDirVersionArg == null) then concatStringsSep "." (take 3 (splitVersion "${version}.0")) else modDirVersionArg;
modDirVersion = versions.pad 3 version;

# branchVersion needs to be x.y
extraMeta.branch = versions.majorMinor version;
Expand Down
Loading

0 comments on commit 3fc528f

Please sign in to comment.