-
- {
- mountScript ? "/bin/sh -i;",
- pkgs ? (import <nixpkgs> {}),
- kernelPackages ? pkgs: pkgs.linuxPackagesFor pkgs.linux_latest,
- udevPackages ? pkgs: [],
- kernelModulePackages ? kp: [],
- firmwarePackages ? pkgs: [pkgs.firmwareLinuxNonfree],
- tools ? pkgs: [],
- modprobeConfig ? "",
- qemu ? pkgs: pkgs.kvm,
- qemuArgs ? "--enable-kvm -m 2G -bios ${pkgs.OVMF.fd}/FV/OVMF.fd"
- }:
- rec {
- maybeCall = f: arg: if builtins.isFunction f then f arg else f;
-
- kernel = (maybeCall kernelPackages pkgs).kernel;
- bzImage = kernel + "/bzImage";
-
- firmwareSet = pkgs.buildEnv {
- name = "firmware-set";
- paths = maybeCall firmwarePackages pkgs;
- pathsToLink = ["/lib/firmware"];
- };
- _kernelPackages = maybeCall kernelPackages pkgs;
- _kernelModulePackages = [_kernelPackages.kernel] ++
- maybeCall kernelModulePackages _kernelPackages;
- kernelModules = pkgs.aggregateModules _kernelModulePackages;
-
- _udevPackages = maybeCall udevPackages pkgs ++ [
- pkgs.eudev pkgs.lvm2 pkgs.libinput
- ];
-
- udevRules = pkgs.runCommand "udev-rules" {} ''
- mkdir -p "$out"/etc/udev/{rules.d,hwdb.d}
- for i in ${toString _udevPackages}; do
- test -d "$i"/etc/udev/rules.d/ && ln -sf "$i"/etc/udev/rules.d/* "$out"/etc/udev/rules.d
- test -d "$i"/var/lib/udev/rules.d/ && ln -sf "$i"/var/lib/udev/rules.d/* "$out"/etc/udev/rules.d
- test -d "$i"/etc/udev/hwdb.d/ && ln -sf "$i"/etc/udev/hwdb.d/* "$out"/etc/udev/hwdb.d
- test -d "$i"/var/lib/udev/hwdb.d/ && ln -sf "$i"/var/lib/udev/hwdb.d/* "$out"/etc/udev/hwdb.d
- done
- ${pkgs.eudev}/bin/udevadm hwdb -u -r "$out"
- '';
-
- modprobeConf = pkgs.writeText "modprobe.conf" ''
- blacklist evbug
- '' + modprobeConfig;
-
- initTools = pkgs.buildEnv {
- name = "init-tools";
- paths =
- (with pkgs; [
- busybox utillinux kmod bashInteractive lvm2 cryptsetup coreutils
- gnugrep gnused eudev
- ])
- ++ (maybeCall tools pkgs);
- ignoreCollisions = true;
- pathsToLink = ["/"];
- extraOutputsToInstall = ["bin" "out"];
- };
-
- initScript = ''
- export PATH="/init-tools/bin"
-
- mkdir -p /new-root /proc /sys /dev /run /tmp /etc
-
- mount proc -t proc /proc
- mount sysfs -t sysfs /sys
- mount run-tmpfs -t tmpfs /run
- mount dev-tmpfs -t devtmpfs /dev
-
- mkdir -p /dev/shm /dev/pts /run/user /run/lock /run/nix
-
- mount shm -t tmpfs /dev/shm
- mount /devpts -t devpts /dev/pts
-
- chmod a+rwt /dev/shm
-
- echo -n /init-tools/bin/modprobe > /proc/sys/kernel/modprobe
- echo -n /firmware > /sys/module/firmware_class/parameters/path
-
- ln -sfT /proc/mounts /etc/mtab
- touch /etc/fstab
-
- echo "Ready to start udev"
-
- udevd &
- udevadm trigger --action=add
- udevadm settle
-
- vgchange -ay
-
- udevadm trigger --action=add
- udevadm settle
-
- ${mountScript}
-
- cd /new-root/
-
- udevadm control -e
-
- lsmod
-
- mkdir -p ./{proc,sys,dev,run}
- mount --move /proc ./proc
- mount --move /sys ./sys
- mount --move /dev ./dev
- mount --move /run ./run
-
- echo "Ready for switch_root"
-
- exec switch_root . ./"$targetInit"
- '';
-
- init = pkgs.writeScript "init" ("#!/bin/sh\n" + initScript);
-
- initrd = pkgs.makeInitrd {
- contents = [
- { object = init; symlink = "/init";}
- { object = kernelModules + "/lib/modules"; symlink = "/lib/modules"; }
- { object = initTools; symlink = "/init-tools"; }
- { object = pkgs.busybox; symlink = "/busybox"; }
- { object = initTools + "/bin/bash"; symlink = "/bin/sh"; }
- { object = initTools + "/bin/env"; symlink = "/usr/bin/env"; }
- { object = firmwareSet + "/lib/firmware"; symlink = "/firmware"; }
- { object = modprobeConf; symlink = "/etc/modprobe.d/modprobe.conf"; }
- { object = udevRules + "/etc/udev"; symlink = "/etc/udev"; }
- ];
- };
-
- qemuScript = pkgs.writeScript "qemu-script" ''#! /bin/sh
- ${maybeCall qemu pkgs}/bin/qemu-system-$(echo "${builtins.currentSystem}" | sed -e "s/-.*//") \
- ${qemuArgs} -kernel ${bzImage} -initrd ${initrd}/initrd "$@"
- '';
- qemuScriptTextMode = pkgs.writeScript "qemu-script" ''#! /bin/sh
- ${maybeCall qemu pkgs}/bin/qemu-system-$(echo "${builtins.currentSystem}" | sed -e "s/-.*//") \
- ${qemuArgs} -kernel ${bzImage} -initrd ${initrd}/initrd \
- -nographic -append "console=ttyS0" "$@"
- '';
- }
-