about summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorK900 <me@0upti.me>2022-08-19 23:55:28 +0300
committerK900 <me@0upti.me>2022-08-20 00:06:13 +0300
commit5f45f2506d196a5bc969bd7da9ed6511a4764854 (patch)
treebfefef4218c264dc2478fd0d76189afc3767fec0 /pkgs
parent907b497d7e7669f3c2794ab313f8c42f80929bd6 (diff)
downloadnixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar.gz
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar.bz2
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar.lz
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar.xz
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.tar.zst
nixlib-5f45f2506d196a5bc969bd7da9ed6511a4764854.zip
linux: better note
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/os-specific/linux/kernel/manual-config.nix63
1 files changed, 52 insertions, 11 deletions
diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index a7d31de6eb75..2fcd39bf596a 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -59,14 +59,6 @@ let
     ++ optional (lib.versionAtLeast version "4.14") libelf
     ++ optional (lib.versionAtLeast version "5.13") zstd;
 
-
-  installkernel = buildPackages.writeShellScriptBin "installkernel" ''
-    set -e
-    mkdir -p $4
-    cp -av $2 $4
-    cp -av $3 $4
-  '';
-
   drvAttrs = config_: kernelConf: kernelPatches: configfile:
     let
       config = let attrName = attr: "CONFIG_" + attr; in {
@@ -195,10 +187,59 @@ let
       ++ optional installsFirmware "INSTALL_FW_PATH=$(out)/lib/firmware"
       ++ optionals buildDTBs ["dtbs_install" "INSTALL_DTBS_PATH=$(out)/dtbs"];
 
-      preInstall = ''
+      preInstall = let
+        # All we really need to do here is copy the final image and System.map to $out,
+        # and use the kernel's modules_install, firmware_install, dtbs_install, etc. targets
+        # for the rest. Easy, right?
+        #
+        # Unfortunately for us, the obvious way of getting the built image path,
+        # make -s image_name, does not work correctly, because some architectures
+        # (*cough* aarch64 *cough*) change KBUILD_IMAGE on the fly in their install targets,
+        # so we end up attempting to install the thing we didn't actually build.
+        #
+        # Thankfully, there's a way out that doesn't involve just hardcoding everything.
+        #
+        # The kernel has an install target, which runs a pretty simple shell script
+        # (located at scripts/install.sh or arch/$arch/boot/install.sh, depending on
+        # which kernel version you're looking at) that tries to do something sensible.
+        #
+        # (it would be great to hijack this script immediately, as it has all the
+        #   information we need passed to it and we don't need it to try and be smart,
+        #   but unfortunately, the exact location of the scripts differs between kernel
+        #   versions, and they're seemingly not considered to be public API at all)
+        #
+        # One of the ways it tries to discover what "something sensible" actually is
+        # is by delegating to what's supposed to be a user-provided install script
+        # located at ~/bin/installkernel.
+        #
+        # (the other options are:
+        #   - a distribution-specific script at /sbin/installkernel,
+        #        which we can't really create in the sandbox easily
+        #   - an architecture-specific script at arch/$arch/boot/install.sh,
+        #        which attempts to guess _something_ and usually guesses very wrong)
+        #
+        # More specifically, the install script exec's into ~/bin/installkernel, if one
+        # exists, with the following arguments:
+        #
+        # $1: $KERNELRELEASE - full kernel version string
+        # $2: $KBUILD_IMAGE - the final image path
+        # $3: System.map - path to System.map file, seemingly hardcoded everywhere
+        # $4: $INSTALL_PATH - path to the destination directory as specified in installFlags
+        #
+        # $2 is exactly what we want, so hijack the script and use the knowledge given to it
+        # by the makefile overlords for our own nefarious ends.
+        #
+        # Note that the makefiles specifically look in ~/bin/installkernel, and
+        # writeShellScriptBin writes the script to <store path>/bin/installkernel,
+        # so HOME needs to be set to just the store path.
+        #
+        # FIXME: figure out a less roundabout way of doing this.
+        installkernel = buildPackages.writeShellScriptBin "installkernel" ''
+          cp -av $2 $4
+          cp -av $3 $4
+        '';
+      in ''
         installFlagsArray+=("-j$NIX_BUILD_CORES")
-
-        # the install scripts expect to find installkernel in ~/bin/installkernel
         export HOME=${installkernel}
       '';