Merge pull request #272029 from blitz/rust-for-linux
In-kernel Rust on Linux (Optional) (2nd Attempt)
This commit is contained in:
@@ -92,6 +92,24 @@ To use your custom kernel package in your NixOS configuration, set
|
|||||||
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
|
boot.kernelPackages = pkgs.linuxPackagesFor yourCustomKernel;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Rust
|
||||||
|
|
||||||
|
The Linux kernel does not have Rust language support enabled by
|
||||||
|
default. For kernel versions 6.7 or newer, experimental Rust support
|
||||||
|
can be enabled. In a NixOS configuration, set:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
boot.kernelPatches = [
|
||||||
|
{
|
||||||
|
name = "Rust Support";
|
||||||
|
patch = null;
|
||||||
|
features = {
|
||||||
|
rust = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
## Developing kernel modules {#sec-linux-config-developing-modules}
|
## Developing kernel modules {#sec-linux-config-developing-modules}
|
||||||
|
|
||||||
This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#sec-linux-kernel-developing-modules).
|
This section was moved to the [Nixpkgs manual](https://nixos.org/nixpkgs/manual#sec-linux-kernel-developing-modules).
|
||||||
|
|||||||
@@ -448,6 +448,7 @@ in {
|
|||||||
kerberos = handleTest ./kerberos/default.nix {};
|
kerberos = handleTest ./kerberos/default.nix {};
|
||||||
kernel-generic = handleTest ./kernel-generic.nix {};
|
kernel-generic = handleTest ./kernel-generic.nix {};
|
||||||
kernel-latest-ath-user-regd = handleTest ./kernel-latest-ath-user-regd.nix {};
|
kernel-latest-ath-user-regd = handleTest ./kernel-latest-ath-user-regd.nix {};
|
||||||
|
kernel-rust = runTestOn ["x86_64-linux"] ./kernel-rust.nix;
|
||||||
keter = handleTest ./keter.nix {};
|
keter = handleTest ./keter.nix {};
|
||||||
kexec = handleTest ./kexec.nix {};
|
kexec = handleTest ./kexec.nix {};
|
||||||
keycloak = discoverTests (import ./keycloak.nix);
|
keycloak = discoverTests (import ./keycloak.nix);
|
||||||
|
|||||||
30
nixos/tests/kernel-rust.nix
Normal file
30
nixos/tests/kernel-rust.nix
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{ pkgs, ... }: {
|
||||||
|
name = "kernel-rust";
|
||||||
|
meta = with pkgs.lib.maintainers; {
|
||||||
|
maintainers = [ blitz ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.machine = { config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_testing;
|
||||||
|
|
||||||
|
boot.extraModulePackages = [
|
||||||
|
config.boot.kernelPackages.rust-out-of-tree-module
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernelPatches = [
|
||||||
|
{
|
||||||
|
name = "Rust Support";
|
||||||
|
patch = null;
|
||||||
|
features = {
|
||||||
|
rust = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("default.target")
|
||||||
|
machine.succeed("modprobe rust_out_of_tree")
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -381,6 +381,16 @@ let
|
|||||||
DRM_VC4_HDMI_CEC = yes;
|
DRM_VC4_HDMI_CEC = yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Enables Rust support in the Linux kernel. This is currently not enabled by default, because it occasionally requires
|
||||||
|
# patching the Linux kernel for the specific Rust toolchain in nixpkgs. These patches usually take a bit
|
||||||
|
# of time to appear and this would hold up Linux kernel and Rust toolchain updates.
|
||||||
|
#
|
||||||
|
# Once Rust in the kernel has more users, we can reconsider enabling it by default.
|
||||||
|
rust = optionalAttrs ((features.rust or false) && versionAtLeast version "6.7") {
|
||||||
|
RUST = yes;
|
||||||
|
GCC_PLUGINS = no;
|
||||||
|
};
|
||||||
|
|
||||||
sound = {
|
sound = {
|
||||||
SND_DYNAMIC_MINORS = yes;
|
SND_DYNAMIC_MINORS = yes;
|
||||||
SND_AC97_POWER_SAVE = yes; # AC97 Power-Saving Mode
|
SND_AC97_POWER_SAVE = yes; # AC97 Power-Saving Mode
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
, pahole
|
, pahole
|
||||||
, lib
|
, lib
|
||||||
, stdenv
|
, stdenv
|
||||||
|
, rustc
|
||||||
|
, rustPlatform
|
||||||
|
, rust-bindgen
|
||||||
|
|
||||||
, # The kernel source tarball.
|
, # The kernel source tarball.
|
||||||
src
|
src
|
||||||
@@ -117,6 +120,8 @@ let
|
|||||||
map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
|
map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
|
||||||
in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
|
in lib.concatStringsSep "\n" ([baseConfigStr] ++ configFromPatches);
|
||||||
|
|
||||||
|
withRust = ((configfile.moduleStructuredConfig.settings.RUST or {}).tristate or null) == "y";
|
||||||
|
|
||||||
configfile = stdenv.mkDerivation {
|
configfile = stdenv.mkDerivation {
|
||||||
inherit ignoreConfigErrors autoModules preferBuiltin kernelArch extraMakeFlags;
|
inherit ignoreConfigErrors autoModules preferBuiltin kernelArch extraMakeFlags;
|
||||||
pname = "linux-config";
|
pname = "linux-config";
|
||||||
@@ -130,7 +135,11 @@ let
|
|||||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||||
nativeBuildInputs = [ perl gmp libmpc mpfr ]
|
nativeBuildInputs = [ perl gmp libmpc mpfr ]
|
||||||
++ lib.optionals (lib.versionAtLeast version "4.16") [ bison flex ]
|
++ lib.optionals (lib.versionAtLeast version "4.16") [ bison flex ]
|
||||||
++ lib.optional (lib.versionAtLeast version "5.2") pahole;
|
++ lib.optional (lib.versionAtLeast version "5.2") pahole
|
||||||
|
++ lib.optionals withRust [ rust-bindgen rustc ]
|
||||||
|
;
|
||||||
|
|
||||||
|
RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc;
|
||||||
|
|
||||||
platformName = stdenv.hostPlatform.linux-kernel.name;
|
platformName = stdenv.hostPlatform.linux-kernel.name;
|
||||||
# e.g. "defconfig"
|
# e.g. "defconfig"
|
||||||
@@ -202,7 +211,7 @@ let
|
|||||||
inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile;
|
inherit kernelPatches randstructSeed extraMakeFlags extraMeta configfile;
|
||||||
pos = builtins.unsafeGetAttrPos "version" args;
|
pos = builtins.unsafeGetAttrPos "version" args;
|
||||||
|
|
||||||
config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
|
config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; } // lib.optionalAttrs withRust { CONFIG_RUST = "y"; };
|
||||||
} // lib.optionalAttrs (modDirVersion != null) { inherit modDirVersion; });
|
} // lib.optionalAttrs (modDirVersion != null) { inherit modDirVersion; });
|
||||||
|
|
||||||
passthru = basicArgs // {
|
passthru = basicArgs // {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{ lib, stdenv, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
|
{ lib, stdenv, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl
|
||||||
, libelf, cpio, elfutils, zstd, python3Minimal, zlib, pahole, kmod, ubootTools
|
, libelf, cpio, elfutils, zstd, python3Minimal, zlib, pahole, kmod, ubootTools
|
||||||
, fetchpatch
|
, fetchpatch
|
||||||
|
, rustc, rust-bindgen, rustPlatform
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
@@ -56,15 +57,6 @@ let
|
|||||||
inherit (lib)
|
inherit (lib)
|
||||||
hasAttr getAttr optional optionals optionalString optionalAttrs maintainers platforms;
|
hasAttr getAttr optional optionals optionalString optionalAttrs maintainers platforms;
|
||||||
|
|
||||||
# Dependencies that are required to build kernel modules
|
|
||||||
moduleBuildDependencies = [
|
|
||||||
pahole
|
|
||||||
perl
|
|
||||||
libelf
|
|
||||||
# module makefiles often run uname commands to find out the kernel version
|
|
||||||
(buildPackages.deterministic-uname.override { inherit modDirVersion; })
|
|
||||||
] ++ optional (lib.versionAtLeast version "5.13") zstd;
|
|
||||||
|
|
||||||
drvAttrs = config_: kernelConf: kernelPatches: configfile:
|
drvAttrs = config_: kernelConf: kernelPatches: configfile:
|
||||||
let
|
let
|
||||||
config = let attrName = attr: "CONFIG_" + attr; in {
|
config = let attrName = attr: "CONFIG_" + attr; in {
|
||||||
@@ -84,14 +76,27 @@ let
|
|||||||
} // config_;
|
} // config_;
|
||||||
|
|
||||||
isModular = config.isYes "MODULES";
|
isModular = config.isYes "MODULES";
|
||||||
|
withRust = config.isYes "RUST";
|
||||||
|
|
||||||
buildDTBs = kernelConf.DTB or false;
|
buildDTBs = kernelConf.DTB or false;
|
||||||
|
|
||||||
|
# Dependencies that are required to build kernel modules
|
||||||
|
moduleBuildDependencies = [
|
||||||
|
pahole
|
||||||
|
perl
|
||||||
|
libelf
|
||||||
|
# module makefiles often run uname commands to find out the kernel version
|
||||||
|
(buildPackages.deterministic-uname.override { inherit modDirVersion; })
|
||||||
|
]
|
||||||
|
++ optional (lib.versionAtLeast version "5.13") zstd
|
||||||
|
++ optionals withRust [ rustc rust-bindgen ]
|
||||||
|
;
|
||||||
|
|
||||||
in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // {
|
in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // {
|
||||||
passthru = rec {
|
passthru = rec {
|
||||||
inherit version modDirVersion config kernelPatches configfile
|
inherit version modDirVersion config kernelPatches configfile
|
||||||
moduleBuildDependencies stdenv;
|
moduleBuildDependencies stdenv;
|
||||||
inherit isZen isHardened isLibre;
|
inherit isZen isHardened isLibre withRust;
|
||||||
isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
|
isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
|
||||||
baseVersion = lib.head (lib.splitString "-rc" version);
|
baseVersion = lib.head (lib.splitString "-rc" version);
|
||||||
kernelOlder = lib.versionOlder baseVersion;
|
kernelOlder = lib.versionOlder baseVersion;
|
||||||
@@ -100,6 +105,16 @@ let
|
|||||||
|
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
|
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||||
|
nativeBuildInputs = [ perl bc nettools openssl rsync gmp libmpc mpfr zstd python3Minimal kmod ubootTools ]
|
||||||
|
++ optional (lib.versionOlder version "5.8") libelf
|
||||||
|
++ optionals (lib.versionAtLeast version "4.16") [ bison flex ]
|
||||||
|
++ optionals (lib.versionAtLeast version "5.2") [ cpio pahole zlib ]
|
||||||
|
++ optional (lib.versionAtLeast version "5.8") elfutils
|
||||||
|
++ optionals withRust [ rustc rust-bindgen ];
|
||||||
|
|
||||||
|
RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc;
|
||||||
|
|
||||||
patches =
|
patches =
|
||||||
map (p: p.patch) kernelPatches
|
map (p: p.patch) kernelPatches
|
||||||
# Required for deterministic builds along with some postPatch magic.
|
# Required for deterministic builds along with some postPatch magic.
|
||||||
@@ -363,14 +378,6 @@ stdenv.mkDerivation ((drvAttrs config stdenv.hostPlatform.linux-kernel kernelPat
|
|||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
|
||||||
nativeBuildInputs = [ perl bc nettools openssl rsync gmp libmpc mpfr zstd python3Minimal kmod ubootTools ]
|
|
||||||
++ optional (lib.versionOlder version "5.8") libelf
|
|
||||||
++ optionals (lib.versionAtLeast version "4.16") [ bison flex ]
|
|
||||||
++ optionals (lib.versionAtLeast version "5.2") [ cpio pahole zlib ]
|
|
||||||
++ optional (lib.versionAtLeast version "5.8") elfutils
|
|
||||||
;
|
|
||||||
|
|
||||||
hardeningDisable = [ "bindnow" "format" "fortify" "stackprotector" "pic" "pie" ];
|
hardeningDisable = [ "bindnow" "format" "fortify" "stackprotector" "pic" "pie" ];
|
||||||
|
|
||||||
# Absolute paths for compilers avoid any PATH-clobbering issues.
|
# Absolute paths for compilers avoid any PATH-clobbering issues.
|
||||||
|
|||||||
28
pkgs/os-specific/linux/rust-out-of-tree-module/default.nix
Normal file
28
pkgs/os-specific/linux/rust-out-of-tree-module/default.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{ lib, fetchFromGitHub, kernel }:
|
||||||
|
kernel.stdenv.mkDerivation {
|
||||||
|
name = "rust-out-of-tree-module";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Rust-for-linux";
|
||||||
|
repo = "rust-out-of-tree-module";
|
||||||
|
|
||||||
|
rev = "7addf9dafba795524f6179a557f7272ecbe1b165";
|
||||||
|
hash = "sha256-Bj7WonZ499W/FajbxjM7yBkU9iTxTW7CrRbCSzWbsSc=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = kernel.moduleBuildDependencies;
|
||||||
|
makeFlags = kernel.makeFlags ++ [ "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" ];
|
||||||
|
|
||||||
|
installFlags = [ "INSTALL_MOD_PATH=${placeholder "out"}" ];
|
||||||
|
installTargets = [ "modules_install" ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
broken = !kernel.withRust;
|
||||||
|
description = "A basic template for an out-of-tree Linux kernel module written in Rust";
|
||||||
|
homepage = "https://github.com/Rust-for-Linux/rust-out-of-tree-module";
|
||||||
|
license = lib.licenses.gpl2Only;
|
||||||
|
maintainers = [ lib.maintainers.blitz ];
|
||||||
|
platforms = lib.platforms.linux;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -458,6 +458,8 @@ in {
|
|||||||
|
|
||||||
facetimehd = callPackage ../os-specific/linux/facetimehd { };
|
facetimehd = callPackage ../os-specific/linux/facetimehd { };
|
||||||
|
|
||||||
|
rust-out-of-tree-module = if lib.versionAtLeast kernel.version "6.7" then callPackage ../os-specific/linux/rust-out-of-tree-module { } else null;
|
||||||
|
|
||||||
tuxedo-keyboard = if lib.versionAtLeast kernel.version "4.14" then callPackage ../os-specific/linux/tuxedo-keyboard { } else null;
|
tuxedo-keyboard = if lib.versionAtLeast kernel.version "4.14" then callPackage ../os-specific/linux/tuxedo-keyboard { } else null;
|
||||||
|
|
||||||
jool = callPackage ../os-specific/linux/jool { };
|
jool = callPackage ../os-specific/linux/jool { };
|
||||||
|
|||||||
Reference in New Issue
Block a user