diff --git a/base.nix b/base.nix index 7eaee32..f767d5e 100644 --- a/base.nix +++ b/base.nix @@ -27,6 +27,11 @@ with lib; description = "enable rngd"; default = false; }; + not-os.sd = mkOption { + type = types.bool; + default = false; + description = "enable sd image support"; + }; not-os.simpleStaticIp = mkOption { type = types.bool; default = false; diff --git a/stage-1.nix b/stage-1.nix index 331fecd..85fda30 100644 --- a/stage-1.nix +++ b/stage-1.nix @@ -164,7 +164,9 @@ let mkdir -p /mnt/nix/store/ - ${if config.not-os.nix then '' + ${if config.not-os.sd && config.not-os.nix then '' + mount $root /mnt + '' else if config.not-os.nix then '' # make the store writeable mkdir -p /mnt/nix/.ro-store /mnt/nix/.overlay-store /mnt/nix/store mount $root /mnt/nix/.ro-store -t squashfs @@ -190,6 +192,11 @@ let initialRamdisk = pkgs.makeInitrd { contents = [ { object = bootStage1; symlink = "/init"; } ]; }; + # Use for zynq_image + uRamdisk = pkgs.makeInitrd { + makeUInitrd = true; + contents = [ { object = bootStage1; symlink = "/init"; } ]; + }; in { options = { @@ -205,6 +212,7 @@ in config = { system.build.bootStage1 = bootStage1; system.build.initialRamdisk = initialRamdisk; + system.build.uRamdisk = uRamdisk; system.build.extraUtils = extraUtils; boot.initrd.availableKernelModules = [ ]; boot.initrd.kernelModules = [ "tun" "loop" "squashfs" ] ++ (lib.optional config.not-os.nix "overlay"); diff --git a/stage-2-init.sh b/stage-2-init.sh index 6cc08e2..0c854c4 100644 --- a/stage-2-init.sh +++ b/stage-2-init.sh @@ -19,4 +19,7 @@ mount -t tmpfs tmpfs /dev/shm $systemConfig/activate +# Run any user-specified commands. +@runtimeShell@ @postBootCommands@ + exec runit diff --git a/stage-2.nix b/stage-2.nix index c61f9d6..fbdf0fd 100644 --- a/stage-2.nix +++ b/stage-2.nix @@ -20,6 +20,19 @@ with lib; example = "256m"; type = types.str; }; + postBootCommands = mkOption { + default = ""; + example = "rm -f /var/log/messages"; + type = types.lines; + description = lib.mdDoc '' + Shell commands to be executed just before runit is started. + ''; + }; + }; + networking.hostName = mkOption { + default = ""; + type = types.strMatching + "^$|^[[:alnum:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$"; }; }; config = { @@ -28,6 +41,9 @@ with lib; isExecutable = true; path = config.system.path; inherit (pkgs) runtimeShell; + postBootCommands = pkgs.writeText "local-cmds" '' + ${config.boot.postBootCommands} + ''; }; }; } diff --git a/zynq_image.nix b/zynq_image.nix index 3fa23ab..b95e7f8 100644 --- a/zynq_image.nix +++ b/zynq_image.nix @@ -1,66 +1,90 @@ -{ config, pkgs, ... }: +{ lib, config, pkgs, ... }: +with lib; let - # dont use overlays for the qemu, it causes a lot of wasted time on recompiles - x86pkgs = import pkgs.path { system = "x86_64-linux"; }; - customKernel = pkgs.linux.override { + crosspkgs = import pkgs.path { + system = "x86_64-linux"; + crossSystem = { + system = "armv7l-linux"; + linux-kernel = { + name = "zynq"; + baseConfig = "multi_v7_defconfig"; + target = "uImage"; + installTarget = "uImage"; + autoModules = false; + DTB = true; + makeFlags = [ "LOADADDR=0x8000" ]; + }; + }; + }; + customKernel = (crosspkgs.linux.override { extraConfig = '' OVERLAY_FS y ''; - }; - customKernelPackages = pkgs.linuxPackagesFor customKernel; + }).overrideAttrs (oa: { + postInstall = '' + cp arch/arm/boot/uImage $out + ${oa.postInstall} + ''; + }); + customKernelPackages = crosspkgs.linuxPackagesFor customKernel; in { imports = [ ./arm32-cross-fixes.nix ]; boot.kernelPackages = customKernelPackages; nixpkgs.system = "armv7l-linux"; - system.build.zynq_image = let - cmdline = "root=/dev/mmcblk0 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext config.system.build.toplevel}"; - qemuScript = '' - #!/bin/bash -v - export PATH=${x86pkgs.qemu}/bin:$PATH - set -x - base=$(dirname $0) - - cp $base/root.squashfs /tmp/ - chmod +w /tmp/root.squashfs - truncate -s 64m /tmp/root.squashfs - - qemu-system-arm \ - -M xilinx-zynq-a9 \ - -serial /dev/null \ - -serial stdio \ - -display none \ - -dtb $base/zynq-zc702.dtb \ - -kernel $base/zImage \ - -initrd $base/initrd \ - -drive file=/tmp/root.squashfs,if=sd,format=raw \ - -append "${cmdline}" - ''; - in pkgs.runCommand "zynq_image" { - inherit qemuScript; - passAsFile = [ "qemuScript" ]; + networking.hostName = "zynq"; + not-os.sd = true; + not-os.simpleStaticIp = true; + system.build.zynq_image = pkgs.runCommand "zynq_image" { preferLocalBuild = true; } '' mkdir $out cd $out - cp -s ${config.system.build.squashfs} root.squashfs - cp -s ${config.system.build.kernel}/*zImage . - cp -s ${config.system.build.initialRamdisk}/initrd initrd - cp -s ${config.system.build.kernel}/dtbs/zynq-zc702.dtb . + cp -s ${config.system.build.kernel}/uImage . + cp -s ${config.system.build.uRamdisk}/initrd uRamdisk.image.gz + cp -s ${config.system.build.kernel}/dtbs/zynq-zc706.dtb devicetree.dtb ln -sv ${config.system.build.toplevel} toplevel - cp $qemuScriptPath qemu-script - chmod +x qemu-script - patchShebangs qemu-script - ls -ltrh ''; - system.build.rpi_image_tar = pkgs.runCommand "dist.tar" {} '' - mkdir -p $out/nix-support - tar -cvf $out/dist.tar ${config.system.build.rpi_image} - echo "file binary-dist $out/dist.tar" >> $out/nix-support/hydra-build-products - ''; - environment.systemPackages = [ pkgs.strace ]; - environment.etc."service/getty/run".source = pkgs.writeShellScript "getty" '' - agetty ttyPS0 115200 + environment = { + systemPackages = with pkgs; [ inetutils wget ]; + etc = { + "service/getty/run".source = pkgs.writeShellScript "getty" '' + hostname ${config.networking.hostName} + agetty ttyPS0 115200 + ''; + "pam.d/other".text = '' + auth sufficient pam_permit.so + account required pam_permit.so + password required pam_permit.so + session optional pam_env.so + ''; + "security/pam_env.conf".text = ""; + }; + }; + boot.postBootCommands = lib.mkIf config.not-os.sd '' + # On the first boot do some maintenance tasks + if [ -f /nix-path-registration ]; then + set -euo pipefail + set -x + # Figure out device names for the boot device and root filesystem. + rootPart=$(${pkgs.utillinux}/bin/findmnt -n -o SOURCE /) + bootDevice=$(lsblk -npo PKNAME $rootPart) + partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}') + + # Resize the root partition and the filesystem to fit the disk + echo ",+," | sfdisk -N$partNum --no-reread $bootDevice + ${pkgs.parted}/bin/partprobe + ${pkgs.e2fsprogs}/bin/resize2fs $rootPart + + # Register the contents of the initial Nix store + nix-store --load-db < /nix-path-registration + + # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag. + touch /etc/NIXOS + nix-env -p /nix/var/nix/profiles/system --set /run/current-system + + # Prevents this from running on later boots. + rm -f /nix-path-registration + fi ''; - environment.etc."pam.d/other".text = ""; }