From d75cff2ee3bb6d91c818d43d1ba7603bb6dacd59 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 17 Mar 2023 18:40:11 +0000 Subject: [PATCH 1/4] linuxManualConfig: don't build inside source tree We can avoid the need to explicitly exclude it later if we just put it somewhere else to begin with. --- pkgs/os-specific/linux/kernel/manual-config.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index b01805e83da9..8386a555311d 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -156,8 +156,7 @@ let configurePhase = '' runHook preConfigure - mkdir build - export buildRoot="$(pwd)/build" + export buildRoot=$(mktemp -d) echo "manual-config configurePhase buildRoot=$buildRoot pwd=$PWD" @@ -275,8 +274,8 @@ let mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} # To save space, exclude a bunch of unneeded stuff when copying. - (cd .. && rsync --archive --prune-empty-dirs \ - --exclude='/build/' \ + (cd "$NIX_BUILD_TOP" && cd "$sourceRoot" && + rsync --archive --prune-empty-dirs \ * $dev/lib/modules/${modDirVersion}/source/) cd $dev/lib/modules/${modDirVersion}/source From 7de3f08ce38aca9fddb5db7bcb7741fd389be9ef Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 17 Mar 2023 18:41:07 +0000 Subject: [PATCH 2/4] linuxManualConfig: unpack directly into $dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit linux is unusual in that we include its sources in an output. There's no point unpacking into /build when we're going to copy the sources into $dev later. Let's unpack directly into the final destination of the code, and save copying a whole kernel source tree (often across filesystems!). This also means that Kbuild knows the location of the sources, which will allow us to install the GDB scripts — some scripts are generated, and some are not, so the generated ones end up in the build directory, accompanied by symlinks to the non-generated ones in the source directory. --- .../linux/kernel/manual-config.nix | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index 8386a555311d..babc7607b94f 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -115,6 +115,20 @@ let hash = "sha256-bBOyJcP6jUvozFJU0SPTOf3cmnTQ6ZZ4PlHjiniHXLU="; }); + preUnpack = '' + # The same preUnpack is used to build the configfile, + # which does not have $dev. + if [ -n "$dev" ]; then + mkdir -p $dev/lib/modules/${modDirVersion} + cd $dev/lib/modules/${modDirVersion} + fi + ''; + + postUnpack = '' + mv -Tv "$sourceRoot" source 2>/dev/null || : + export sourceRoot=$PWD/source + ''; + postPatch = '' sed -i Makefile -e 's|= depmod|= ${buildPackages.kmod}/bin/depmod|' @@ -185,6 +199,12 @@ let buildFlags = [ "KBUILD_BUILD_VERSION=1-NixOS" + + # Set by default in the kernel since a73619a845d5, + # replicated here to apply to older versions. + # Makes __FILE__ relative to the build directory. + "KCPPFLAGS=-fmacro-prefix-map=$(sourceRoot)/=" + kernelConf.target "vmlinux" # for "perf" and things like that ] ++ optional isModular "modules" @@ -261,7 +281,6 @@ let ]; postInstall = optionalString isModular '' - mkdir -p $dev cp vmlinux $dev/ if [ -z "''${dontStrip-}" ]; then installFlagsArray+=("INSTALL_MOD_STRIP=1") @@ -271,12 +290,7 @@ let unlink $out/lib/modules/${modDirVersion}/build unlink $out/lib/modules/${modDirVersion}/source - mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} - - # To save space, exclude a bunch of unneeded stuff when copying. - (cd "$NIX_BUILD_TOP" && cd "$sourceRoot" && - rsync --archive --prune-empty-dirs \ - * $dev/lib/modules/${modDirVersion}/source/) + mkdir $dev/lib/modules/${modDirVersion}/build cd $dev/lib/modules/${modDirVersion}/source From 41f788b1217b05d8661ebb77bfc9d9f3f65b5dd2 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 19 Mar 2023 23:55:12 +0000 Subject: [PATCH 3/4] linuxManualConfig: use the default make target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've basically been reimplementing this — by default it contains vmlinux, dtbs (on applicable architectures), modules, and architecture specific stuff like $(KBUILD_IMAGE) and a couple of other miscellaneous files. --- pkgs/os-specific/linux/kernel/manual-config.nix | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index babc7607b94f..fa21ab3b6155 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -198,18 +198,14 @@ let ''; buildFlags = [ + "DTC_FLAGS=-@" "KBUILD_BUILD_VERSION=1-NixOS" # Set by default in the kernel since a73619a845d5, # replicated here to apply to older versions. # Makes __FILE__ relative to the build directory. "KCPPFLAGS=-fmacro-prefix-map=$(sourceRoot)/=" - - kernelConf.target - "vmlinux" # for "perf" and things like that - ] ++ optional isModular "modules" - ++ optionals buildDTBs ["dtbs" "DTC_FLAGS=-@"] - ++ extraMakeFlags; + ] ++ extraMakeFlags; installFlags = [ "INSTALL_PATH=$(out)" From d57568fcad7e3a9364850cb1c25d7a34693c02d5 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 17 Mar 2023 18:44:06 +0000 Subject: [PATCH 4/4] linuxManualConfig: install GDB scripts These are required to debug kernel modules. Since we're now able to do that, there's another reason besides BTF to enable DEBUG_INFO, so I've done that for pre-BTF kernel modules as well here. For GDB to get configured correctly, vmlinux-gdb.py has to be two directories up from scripts/gdb, and vmlinux has to be next to vmlinux-gdb.py. The least invasive way to satisfy these constraints is to make vmlinux a symlink, which GDB will resolve before looking for vmlinux-gdb.py. Tested both ways of getting the scripts into GDB that I know of: gdb /nix/store/7n77ijlxkxr6d613h02lr707kvjx6j1k-linux-6.1.19-dev/vmlinux \ -iex 'add-auto-load-safe-path /nix/store/7n77ijlxkxr6d613h02lr707kvjx6j1k-linux-6.1.19-dev/lib/modules/6.1.19/build/vmlinux-gdb.py' \ -ex 'lx-version' \ -ex 'q' gdb /nix/store/7n77ijlxkxr6d613h02lr707kvjx6j1k-linux-6.1.19-dev/vmlinux \ -ex 'source /nix/store/7n77ijlxkxr6d613h02lr707kvjx6j1k-linux-6.1.19-dev/lib/modules/6.1.19/build/vmlinux-gdb.py' \ -ex 'lx-version' \ -ex 'q' Also tested that the strip changes don't result in meaningful output size changes (there's some small variation due to BTF data not always coming out the same size, which is unrelated), and built every kernel I can on x86_64 to make sure I'm not relying on build system behaviour specific to newer kernels. --- .../os-specific/linux/kernel/common-config.nix | 7 +++---- .../os-specific/linux/kernel/manual-config.nix | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/pkgs/os-specific/linux/kernel/common-config.nix b/pkgs/os-specific/linux/kernel/common-config.nix index 4b1318d91159..77efa268d3ef 100644 --- a/pkgs/os-specific/linux/kernel/common-config.nix +++ b/pkgs/os-specific/linux/kernel/common-config.nix @@ -36,10 +36,7 @@ let debug = { # Necessary for BTF - DEBUG_INFO = mkMerge [ - (whenOlder "5.2" (if (features.debug or false) then yes else no)) - (whenBetween "5.2" "5.18" yes) - ]; + DEBUG_INFO = yes; DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT = whenAtLeast "5.18" yes; # Reduced debug info conflict with BTF and have been enabled in # aarch64 defconfig since 5.13 @@ -62,6 +59,8 @@ let SUNRPC_DEBUG = yes; # Provide access to tunables like sched_migration_cost_ns SCHED_DEBUG = yes; + + GDB_SCRIPTS = yes; }; power-management = { diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index fa21ab3b6155..4c5ec86b1e6a 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -277,7 +277,6 @@ let ]; postInstall = optionalString isModular '' - cp vmlinux $dev/ if [ -z "''${dontStrip-}" ]; then installFlagsArray+=("INSTALL_MOD_STRIP=1") fi @@ -297,12 +296,16 @@ let # from a `try-run` call from the Makefile rm -f $dev/lib/modules/${modDirVersion}/build/.[0-9]*.d - # Keep some extra files on some arches (powerpc, aarch64) - for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o; do - if [ -f "$buildRoot/$f" ]; then - cp $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f + # Keep some extra files + for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o \ + scripts/gdb/linux vmlinux vmlinux-gdb.py + do + if [ -e "$buildRoot/$f" ]; then + mkdir -p "$(dirname "$dev/lib/modules/${modDirVersion}/build/$f")" + cp -HR $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f fi done + ln -s $dev/lib/modules/${modDirVersion}/build/vmlinux $dev # !!! No documentation on how much of the source tree must be kept # If/when kernel builds fail due to missing files, you can add @@ -345,6 +348,11 @@ let sed -i Makefile -e 's|= ${buildPackages.kmod}/bin/depmod|= depmod|' ''; + preFixup = '' + # Don't strip $dev/lib/modules/*/vmlinux + stripDebugList="$(cd $dev && echo lib/modules/*/build/*/)" + ''; + requiredSystemFeatures = [ "big-parallel" ]; meta = {