uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,50 @@
# Provide an initial copy of the NixOS channel so that the user
# doesn't need to run "nix-channel --update" first.
{ config, lib, pkgs, ... }:
with lib;
let
nixpkgs = lib.cleanSource pkgs.path;
# We need a copy of the Nix expressions for Nixpkgs and NixOS on the
# CD. These are installed into the "nixos" channel of the root
# user, as expected by nixos-rebuild/nixos-install. FIXME: merge
# with make-channel.nix.
channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}"
{ preferLocalBuild = true; }
''
mkdir -p $out
cp -prd ${nixpkgs.outPath} $out/nixos
chmod -R u+w $out/nixos
if [ ! -e $out/nixos/nixpkgs ]; then
ln -s . $out/nixos/nixpkgs
fi
${optionalString (config.system.nixos.revision != null) ''
echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision
''}
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
echo ${config.system.nixos.versionSuffix} | sed -e s/pre// > $out/nixos/svn-revision
'';
in
{
# Provide the NixOS/Nixpkgs sources in /etc/nixos. This is required
# for nixos-install.
boot.postBootCommands = mkAfter
''
if ! [ -e /var/lib/nixos/did-channel-init ]; then
echo "unpacking the NixOS/Nixpkgs sources..."
mkdir -p /nix/var/nix/profiles/per-user/root
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/per-user/root/channels \
-i ${channelSources} --quiet --option build-use-substitutes false \
${optionalString config.boot.initrd.systemd.enable "--option sandbox false"} # There's an issue with pivot_root
mkdir -m 0700 -p /root/.nix-defexpr
ln -s /nix/var/nix/profiles/per-user/root/channels /root/.nix-defexpr/channels
mkdir -m 0755 -p /var/lib/nixos
touch /var/lib/nixos/did-channel-init
fi
'';
}

View file

@ -0,0 +1,50 @@
# This module contains the basic configuration for building a NixOS
# installation CD.
{ config, lib, options, pkgs, ... }:
with lib;
{
imports =
[ ./iso-image.nix
# Profiles of this basic installation CD.
../../profiles/all-hardware.nix
../../profiles/base.nix
../../profiles/installation-device.nix
];
# Adds terminus_font for people with HiDPI displays
console.packages = options.console.packages.default ++ [ pkgs.terminus_font ];
# ISO naming.
isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.iso";
# EFI booting
isoImage.makeEfiBootable = true;
# USB booting
isoImage.makeUsbBootable = true;
# Add Memtest86+ to the CD.
boot.loader.grub.memtest86.enable = true;
# An installation media cannot tolerate a host config defined file
# system layout on a fresh machine, before it has been formatted.
swapDevices = mkImageMediaOverride [ ];
fileSystems = mkImageMediaOverride config.lib.isoFileSystems;
boot.postBootCommands = ''
for o in $(</proc/cmdline); do
case "$o" in
live.nixos.passwd=*)
set -- $(IFS==; echo $o)
echo "nixos:$2" | ${pkgs.shadow}/bin/chpasswd
;;
esac
done
'';
system.stateVersion = lib.mkDefault lib.trivial.release;
}

View file

@ -0,0 +1,69 @@
# This module contains the basic configuration for building a graphical NixOS
# installation CD.
{ lib, pkgs, ... }:
with lib;
{
imports = [ ./installation-cd-base.nix ];
# Whitelist wheel users to do anything
# This is useful for things like pkexec
#
# WARNING: this is dangerous for systems
# outside the installation-cd and shouldn't
# be used anywhere else.
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
'';
services.xserver.enable = true;
# Provide networkmanager for easy wireless configuration.
networking.networkmanager.enable = true;
networking.wireless.enable = mkForce false;
# KDE complains if power management is disabled (to be precise, if
# there is no power management backend such as upower).
powerManagement.enable = true;
# Enable sound in graphical iso's.
hardware.pulseaudio.enable = true;
# VM guest additions to improve host-guest interaction
services.spice-vdagentd.enable = true;
services.qemuGuest.enable = true;
virtualisation.vmware.guest.enable = true;
virtualisation.hypervGuest.enable = true;
services.xe-guest-utilities.enable = true;
# The VirtualBox guest additions rely on an out-of-tree kernel module
# which lags behind kernel releases, potentially causing broken builds.
virtualisation.virtualbox.guest.enable = false;
# Enable plymouth
boot.plymouth.enable = true;
environment.defaultPackages = with pkgs; [
# Include gparted for partitioning disks.
gparted
# Include some editors.
vim
nano
# Include some version control tools.
git
rsync
# Firefox for reading the manual.
firefox
glxinfo
];
}

View file

@ -0,0 +1,59 @@
# This module defines a NixOS installation CD that contains GNOME.
{ pkgs, ... }:
{
imports = [ ./installation-cd-graphical-calamares.nix ];
isoImage.edition = "gnome";
services.xserver.desktopManager.gnome = {
# Add Firefox and other tools useful for installation to the launcher
favoriteAppsOverride = ''
[org.gnome.shell]
favorite-apps=[ 'firefox.desktop', 'nixos-manual.desktop', 'org.gnome.Console.desktop', 'org.gnome.Nautilus.desktop', 'gparted.desktop', 'io.calamares.calamares.desktop' ]
'';
# Override GNOME defaults to disable GNOME tour and disable suspend
extraGSettingsOverrides = ''
[org.gnome.shell]
welcome-dialog-last-shown-version='9999999999'
[org.gnome.settings-daemon.plugins.power]
sleep-inactive-ac-type='nothing'
sleep-inactive-battery-type='nothing'
'';
extraGSettingsOverridePackages = [ pkgs.gnome.gnome-settings-daemon ];
enable = true;
};
# Theme calamares with GNOME theme
qt5 = {
enable = true;
platformTheme = "gnome";
};
# Fix scaling for calamares on wayland
environment.variables = {
QT_QPA_PLATFORM = "$([[ $XDG_SESSION_TYPE = \"wayland\" ]] && echo \"wayland\")";
};
services.xserver.displayManager = {
gdm = {
enable = true;
# autoSuspend makes the machine automatically suspend after inactivity.
# It's possible someone could/try to ssh'd into the machine and obviously
# have issues because it's inactive.
# See:
# * https://github.com/NixOS/nixpkgs/pull/63790
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
autoSuspend = false;
};
autoLogin = {
enable = true;
user = "nixos";
};
};
}

View file

@ -0,0 +1,49 @@
# This module defines a NixOS installation CD that contains X11 and
# Plasma 5.
{ pkgs, ... }:
{
imports = [ ./installation-cd-graphical-calamares.nix ];
isoImage.edition = "plasma5";
services.xserver = {
desktopManager.plasma5 = {
enable = true;
};
# Automatically login as nixos.
displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "nixos";
};
};
};
environment.systemPackages = with pkgs; [
# Graphical text editor
kate
];
system.activationScripts.installerDesktop = let
# Comes from documentation.nix when xserver and nixos.enable are true.
manualDesktopFile = "/run/current-system/sw/share/applications/nixos-manual.desktop";
homeDir = "/home/nixos/";
desktopDir = homeDir + "Desktop/";
in ''
mkdir -p ${desktopDir}
chown nixos ${homeDir} ${desktopDir}
ln -sfT ${manualDesktopFile} ${desktopDir + "nixos-manual.desktop"}
ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop ${desktopDir + "gparted.desktop"}
ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop ${desktopDir + "org.kde.konsole.desktop"}
ln -sfT ${pkgs.calamares-nixos}/share/applications/io.calamares.calamares.desktop ${desktopDir + "io.calamares.calamares.desktop"}
'';
}

View file

@ -0,0 +1,20 @@
# This module adds the calamares installer to the basic graphical NixOS
# installation CD.
{ pkgs, ... }:
let
calamares-nixos-autostart = pkgs.makeAutostartItem { name = "io.calamares.calamares"; package = pkgs.calamares-nixos; };
in
{
imports = [ ./installation-cd-graphical-base.nix ];
environment.systemPackages = with pkgs; [
# Calamares for graphical installation
libsForQt5.kpmcore
calamares-nixos
calamares-nixos-autostart
calamares-nixos-extensions
# Needed for calamares QML module packagechooserq
libsForQt5.full
];
}

View file

@ -0,0 +1,36 @@
# This module defines a NixOS installation CD that contains GNOME.
{ ... }:
{
imports = [ ./installation-cd-graphical-base.nix ];
isoImage.edition = "gnome";
services.xserver.desktopManager.gnome = {
# Add Firefox and other tools useful for installation to the launcher
favoriteAppsOverride = ''
[org.gnome.shell]
favorite-apps=[ 'firefox.desktop', 'nixos-manual.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.Nautilus.desktop', 'gparted.desktop' ]
'';
enable = true;
};
services.xserver.displayManager = {
gdm = {
enable = true;
# autoSuspend makes the machine automatically suspend after inactivity.
# It's possible someone could/try to ssh'd into the machine and obviously
# have issues because it's inactive.
# See:
# * https://github.com/NixOS/nixpkgs/pull/63790
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
autoSuspend = false;
};
autoLogin = {
enable = true;
user = "nixos";
};
};
}

View file

@ -0,0 +1,7 @@
{ pkgs, ... }:
{
imports = [ ./installation-cd-graphical-plasma5.nix ];
boot.kernelPackages = pkgs.linuxPackages_latest;
}

View file

@ -0,0 +1,48 @@
# This module defines a NixOS installation CD that contains X11 and
# Plasma 5.
{ pkgs, ... }:
{
imports = [ ./installation-cd-graphical-base.nix ];
isoImage.edition = "plasma5";
services.xserver = {
desktopManager.plasma5 = {
enable = true;
};
# Automatically login as nixos.
displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "nixos";
};
};
};
environment.systemPackages = with pkgs; [
# Graphical text editor
kate
];
system.activationScripts.installerDesktop = let
# Comes from documentation.nix when xserver and nixos.enable are true.
manualDesktopFile = "/run/current-system/sw/share/applications/nixos-manual.desktop";
homeDir = "/home/nixos/";
desktopDir = homeDir + "Desktop/";
in ''
mkdir -p ${desktopDir}
chown nixos ${homeDir} ${desktopDir}
ln -sfT ${manualDesktopFile} ${desktopDir + "nixos-manual.desktop"}
ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop ${desktopDir + "gparted.desktop"}
ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop ${desktopDir + "org.kde.konsole.desktop"}
'';
}

View file

@ -0,0 +1,7 @@
{ pkgs, ... }:
{
imports = [ ./installation-cd-minimal.nix ];
boot.kernelPackages = pkgs.linuxPackages_latest;
}

View file

@ -0,0 +1,14 @@
# This module defines a small NixOS installation CD. It does not
# contain any graphical stuff.
{ ... }:
{
imports =
[ ./installation-cd-base.nix
];
isoImage.edition = "minimal";
fonts.fontconfig.enable = false;
}

View file

@ -0,0 +1,820 @@
# This module creates a bootable ISO image containing the given NixOS
# configuration. The derivation for the ISO image will be placed in
# config.system.build.isoImage.
{ config, lib, pkgs, ... }:
with lib;
let
/**
* Given a list of `options`, concats the result of mapping each options
* to a menuentry for use in grub.
*
* * defaults: {name, image, params, initrd}
* * options: [ option... ]
* * option: {name, params, class}
*/
menuBuilderGrub2 =
defaults: options: lib.concatStrings
(
map
(option: ''
menuentry '${defaults.name} ${
# Name appended to menuentry defaults to params if no specific name given.
option.name or (if option ? params then "(${option.params})" else "")
}' ${if option ? class then " --class ${option.class}" else ""} {
linux ${defaults.image} \''${isoboot} ${defaults.params} ${
option.params or ""
}
initrd ${defaults.initrd}
}
'')
options
)
;
/**
* Given a `config`, builds the default options.
*/
buildMenuGrub2 = config:
buildMenuAdditionalParamsGrub2 config ""
;
/**
* Given a `config` and params to add to `params`, build a set of default options.
* Use this one when creating a variant (e.g. hidpi)
*/
buildMenuAdditionalParamsGrub2 = config: additional:
let
finalCfg = {
name = "NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}";
params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}";
image = "/boot/${config.system.boot.loader.kernelFile}";
initrd = "/boot/initrd";
};
in
menuBuilderGrub2
finalCfg
[
{ class = "installer"; }
{ class = "nomodeset"; params = "nomodeset"; }
{ class = "copytoram"; params = "copytoram"; }
{ class = "debug"; params = "debug"; }
]
;
# Timeout in syslinux is in units of 1/10 of a second.
# 0 is used to disable timeouts.
syslinuxTimeout = if config.boot.loader.timeout == null then
0
else
max (config.boot.loader.timeout * 10) 1;
max = x: y: if x > y then x else y;
# The configuration file for syslinux.
# Notes on syslinux configuration and UNetbootin compatiblity:
# * Do not use '/syslinux/syslinux.cfg' as the path for this
# configuration. UNetbootin will not parse the file and use it as-is.
# This results in a broken configuration if the partition label does
# not match the specified config.isoImage.volumeID. For this reason
# we're using '/isolinux/isolinux.cfg'.
# * Use APPEND instead of adding command-line arguments directly after
# the LINUX entries.
# * COM32 entries (chainload, reboot, poweroff) are not recognized. They
# result in incorrect boot entries.
baseIsolinuxCfg = ''
SERIAL 0 115200
TIMEOUT ${builtins.toString syslinuxTimeout}
UI vesamenu.c32
MENU BACKGROUND /isolinux/background.png
${config.isoImage.syslinuxTheme}
DEFAULT boot
LABEL boot
MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
LINUX /boot/${config.system.boot.loader.kernelFile}
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
INITRD /boot/${config.system.boot.loader.initrdFile}
# A variant to boot with 'nomodeset'
LABEL boot-nomodeset
MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (nomodeset)
LINUX /boot/${config.system.boot.loader.kernelFile}
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} nomodeset
INITRD /boot/${config.system.boot.loader.initrdFile}
# A variant to boot with 'copytoram'
LABEL boot-copytoram
MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (copytoram)
LINUX /boot/${config.system.boot.loader.kernelFile}
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} copytoram
INITRD /boot/${config.system.boot.loader.initrdFile}
# A variant to boot with verbose logging to the console
LABEL boot-debug
MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (debug)
LINUX /boot/${config.system.boot.loader.kernelFile}
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} loglevel=7
INITRD /boot/${config.system.boot.loader.initrdFile}
# A variant to boot with a serial console enabled
LABEL boot-serial
MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (serial console=ttyS0,115200n8)
LINUX /boot/${config.system.boot.loader.kernelFile}
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} console=ttyS0,115200n8
INITRD /boot/${config.system.boot.loader.initrdFile}
'';
isolinuxMemtest86Entry = ''
LABEL memtest
MENU LABEL Memtest86+
LINUX /boot/memtest.bin
APPEND ${toString config.boot.loader.grub.memtest86.params}
'';
isolinuxCfg = concatStringsSep "\n"
([ baseIsolinuxCfg ] ++ optional config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
refindBinary = if targetArch == "x64" || targetArch == "aa64" then "refind_${targetArch}.efi" else null;
# Setup instructions for rEFInd.
refind =
if refindBinary != null then
''
# Adds rEFInd to the ISO.
cp -v ${pkgs.refind}/share/refind/${refindBinary} $out/EFI/boot/
''
else
"# No refind for ${targetArch}"
;
grubPkgs = if config.boot.loader.grub.forcei686 then pkgs.pkgsi686Linux else pkgs;
grubMenuCfg = ''
#
# Menu configuration
#
# Search using a "marker file"
search --set=root --file /EFI/nixos-installer-image
insmod gfxterm
insmod png
set gfxpayload=keep
set gfxmode=${concatStringsSep "," [
# GRUB will use the first valid mode listed here.
# `auto` will sometimes choose the smallest valid mode it detects.
# So instead we'll list a lot of possibly valid modes :/
#"3840x2160"
#"2560x1440"
"1920x1080"
"1366x768"
"1280x720"
"1024x768"
"800x600"
"auto"
]}
# Fonts can be loaded?
# (This font is assumed to always be provided as a fallback by NixOS)
if loadfont (\$root)/EFI/boot/unicode.pf2; then
set with_fonts=true
fi
if [ "\$textmode" != "true" -a "\$with_fonts" == "true" ]; then
# Use graphical term, it can be either with background image or a theme.
# input is "console", while output is "gfxterm".
# This enables "serial" input and output only when possible.
# Otherwise the failure mode is to not even enable gfxterm.
if test "\$with_serial" == "yes"; then
terminal_output gfxterm serial
terminal_input console serial
else
terminal_output gfxterm
terminal_input console
fi
else
# Sets colors for the non-graphical term.
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue
fi
${ # When there is a theme configured, use it, otherwise use the background image.
if config.isoImage.grubTheme != null then ''
# Sets theme.
set theme=(\$root)/EFI/boot/grub-theme/theme.txt
# Load theme fonts
$(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n")
'' else ''
if background_image (\$root)/EFI/boot/efi-background.png; then
# Black background means transparent background when there
# is a background image set... This seems undocumented :(
set color_normal=black/black
set color_highlight=white/blue
else
# Falls back again to proper colors.
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue
fi
''}
'';
# The EFI boot image.
# Notes about grub:
# * Yes, the grubMenuCfg has to be repeated in all submenus. Otherwise you
# will get white-on-black console-like text on sub-menus. *sigh*
efiDir = pkgs.runCommand "efi-directory" {
nativeBuildInputs = [ pkgs.buildPackages.grub2_efi ];
strictDeps = true;
} ''
mkdir -p $out/EFI/boot/
# Add a marker so GRUB can find the filesystem.
touch $out/EFI/nixos-installer-image
# ALWAYS required modules.
MODULES="fat iso9660 part_gpt part_msdos \
normal boot linux configfile loopback chain halt \
efifwsetup efi_gop \
ls search search_label search_fs_uuid search_fs_file \
gfxmenu gfxterm gfxterm_background gfxterm_menu test all_video loadenv \
exfat ext2 ntfs btrfs hfsplus udf \
videoinfo png \
echo serial \
"
echo "Building GRUB with modules:"
for mod in $MODULES; do
echo " - $mod"
done
# Modules that may or may not be available per-platform.
echo "Adding additional modules:"
for mod in efi_uga; do
if [ -f ${grubPkgs.grub2_efi}/lib/grub/${grubPkgs.grub2_efi.grubTarget}/$mod.mod ]; then
echo " - $mod"
MODULES+=" $mod"
fi
done
# Make our own efi program, we can't rely on "grub-install" since it seems to
# probe for devices, even with --skip-fs-probe.
grub-mkimage --directory=${grubPkgs.grub2_efi}/lib/grub/${grubPkgs.grub2_efi.grubTarget} -o $out/EFI/boot/boot${targetArch}.efi -p /EFI/boot -O ${grubPkgs.grub2_efi.grubTarget} \
$MODULES
cp ${grubPkgs.grub2_efi}/share/grub/unicode.pf2 $out/EFI/boot/
cat <<EOF > $out/EFI/boot/grub.cfg
set with_fonts=false
set textmode=false
# If you want to use serial for "terminal_*" commands, you need to set one up:
# Example manual configuration:
# → serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
# This uses the defaults, and makes the serial terminal available.
set with_serial=no
if serial; then set with_serial=yes ;fi
export with_serial
clear
set timeout=10
# This message will only be viewable when "gfxterm" is not used.
echo ""
echo "Loading graphical boot menu..."
echo ""
echo "Press 't' to use the text boot menu on this console..."
echo ""
${grubMenuCfg}
hiddenentry 'Text mode' --hotkey 't' {
loadfont (\$root)/EFI/boot/unicode.pf2
set textmode=true
terminal_output gfxterm console
}
hiddenentry 'GUI mode' --hotkey 'g' {
$(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n")
set textmode=false
terminal_output gfxterm
}
# If the parameter iso_path is set, append the findiso parameter to the kernel
# line. We need this to allow the nixos iso to be booted from grub directly.
if [ \''${iso_path} ] ; then
set isoboot="findiso=\''${iso_path}"
fi
#
# Menu entries
#
${buildMenuGrub2 config}
submenu "HiDPI, Quirks and Accessibility" --class hidpi --class submenu {
${grubMenuCfg}
submenu "Suggests resolution @720p" --class hidpi-720p {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "video=1280x720@60"}
}
submenu "Suggests resolution @1080p" --class hidpi-1080p {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "video=1920x1080@60"}
}
# If we boot into a graphical environment where X is autoran
# and always crashes, it makes the media unusable. Allow the user
# to disable this.
submenu "Disable display-manager" --class quirk-disable-displaymanager {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "systemd.mask=display-manager.service"}
}
# Some laptop and convertibles have the panel installed in an
# inconvenient way, rotated away from the keyboard.
# Those entries makes it easier to use the installer.
submenu "" {return}
submenu "Rotate framebuffer Clockwise" --class rotate-90cw {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:1"}
}
submenu "Rotate framebuffer Upside-Down" --class rotate-180 {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:2"}
}
submenu "Rotate framebuffer Counter-Clockwise" --class rotate-90ccw {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:3"}
}
# As a proof of concept, mainly. (Not sure it has accessibility merits.)
submenu "" {return}
submenu "Use black on white" --class accessibility-blakconwhite {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "vt.default_red=0xFF,0xBC,0x4F,0xB4,0x56,0xBC,0x4F,0x00,0xA1,0xCF,0x84,0xCA,0x8D,0xB4,0x84,0x68 vt.default_grn=0xFF,0x55,0xBA,0xBA,0x4D,0x4D,0xB3,0x00,0xA0,0x8F,0xB3,0xCA,0x88,0x93,0xA4,0x68 vt.default_blu=0xFF,0x58,0x5F,0x58,0xC5,0xBD,0xC5,0x00,0xA8,0xBB,0xAB,0x97,0xBD,0xC7,0xC5,0x68"}
}
# Serial access is a must!
submenu "" {return}
submenu "Serial console=ttyS0,115200n8" --class serial {
${grubMenuCfg}
${buildMenuAdditionalParamsGrub2 config "console=ttyS0,115200n8"}
}
}
${lib.optionalString (refindBinary != null) ''
# GRUB apparently cannot do "chainloader" operations on "CD".
if [ "\$root" != "cd0" ]; then
menuentry 'rEFInd' --class refind {
# Force root to be the FAT partition
# Otherwise it breaks rEFInd's boot
search --set=root --no-floppy --fs-uuid 1234-5678
chainloader (\$root)/EFI/boot/${refindBinary}
}
fi
''}
menuentry 'Firmware Setup' --class settings {
fwsetup
clear
echo ""
echo "If you see this message, your EFI system doesn't support this feature."
echo ""
}
menuentry 'Shutdown' --class shutdown {
halt
}
EOF
${refind}
'';
efiImg = pkgs.runCommand "efi-image_eltorito" {
nativeBuildInputs = [ pkgs.buildPackages.mtools pkgs.buildPackages.libfaketime pkgs.buildPackages.dosfstools ];
strictDeps = true;
}
# Be careful about determinism: du --apparent-size,
# dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i)
''
mkdir ./contents && cd ./contents
mkdir -p ./EFI/boot
cp -rp "${efiDir}"/EFI/boot/{grub.cfg,*.efi} ./EFI/boot
# Rewrite dates for everything in the FS
find . -exec touch --date=2000-01-01 {} +
# Round up to the nearest multiple of 1MB, for more deterministic du output
usage_size=$(( $(du -s --block-size=1M --apparent-size . | tr -cd '[:digit:]') * 1024 * 1024 ))
# Make the image 110% as big as the files need to make up for FAT overhead
image_size=$(( ($usage_size * 110) / 100 ))
# Make the image fit blocks of 1M
block_size=$((1024*1024))
image_size=$(( ($image_size / $block_size + 1) * $block_size ))
echo "Usage size: $usage_size"
echo "Image size: $image_size"
truncate --size=$image_size "$out"
faketime "2000-01-01 00:00:00" mkfs.vfat -i 12345678 -n EFIBOOT "$out"
# Force a fixed order in mcopy for better determinism, and avoid file globbing
for d in $(find EFI -type d | sort); do
faketime "2000-01-01 00:00:00" mmd -i "$out" "::/$d"
done
for f in $(find EFI -type f | sort); do
mcopy -pvm -i "$out" "$f" "::/$f"
done
# Verify the FAT partition.
fsck.vfat -vn "$out"
''; # */
# Name used by UEFI for architectures.
targetArch =
if pkgs.stdenv.isi686 || config.boot.loader.grub.forcei686 then
"ia32"
else if pkgs.stdenv.isx86_64 then
"x64"
else if pkgs.stdenv.isAarch32 then
"arm"
else if pkgs.stdenv.isAarch64 then
"aa64"
else
throw "Unsupported architecture";
# Syslinux (and isolinux) only supports x86-based architectures.
canx86BiosBoot = pkgs.stdenv.hostPlatform.isx86;
in
{
options = {
isoImage.isoName = mkOption {
default = "${config.isoImage.isoBaseName}.iso";
description = ''
Name of the generated ISO image file.
'';
};
isoImage.isoBaseName = mkOption {
default = "nixos";
description = ''
Prefix of the name of the generated ISO image file.
'';
};
isoImage.compressImage = mkOption {
default = false;
description = ''
Whether the ISO image should be compressed using
<command>zstd</command>.
'';
};
isoImage.squashfsCompression = mkOption {
default = with pkgs.stdenv.targetPlatform; "xz -Xdict-size 100% "
+ lib.optionalString (isx86_32 || isx86_64) "-Xbcj x86"
# Untested but should also reduce size for these platforms
+ lib.optionalString (isAarch32 || isAarch64) "-Xbcj arm"
+ lib.optionalString (isPower && is32bit && isBigEndian) "-Xbcj powerpc"
+ lib.optionalString (isSparc) "-Xbcj sparc";
description = ''
Compression settings to use for the squashfs nix store.
'';
example = "zstd -Xcompression-level 6";
};
isoImage.edition = mkOption {
default = "";
description = ''
Specifies which edition string to use in the volume ID of the generated
ISO image.
'';
};
isoImage.volumeID = mkOption {
# nixos-$EDITION-$RELEASE-$ARCH
default = "nixos${optionalString (config.isoImage.edition != "") "-${config.isoImage.edition}"}-${config.system.nixos.release}-${pkgs.stdenv.hostPlatform.uname.processor}";
description = ''
Specifies the label or volume ID of the generated ISO image.
Note that the label is used by stage 1 of the boot process to
mount the CD, so it should be reasonably distinctive.
'';
};
isoImage.contents = mkOption {
example = literalExpression ''
[ { source = pkgs.memtest86 + "/memtest.bin";
target = "boot/memtest.bin";
}
]
'';
description = ''
This option lists files to be copied to fixed locations in the
generated ISO image.
'';
};
isoImage.storeContents = mkOption {
example = literalExpression "[ pkgs.stdenv ]";
description = ''
This option lists additional derivations to be included in the
Nix store in the generated ISO image.
'';
};
isoImage.includeSystemBuildDependencies = mkOption {
default = false;
description = ''
Set this option to include all the needed sources etc in the
image. It significantly increases image size. Use that when
you want to be able to keep all the sources needed to build your
system or when you are going to install the system on a computer
with slow or non-existent network connection.
'';
};
isoImage.makeEfiBootable = mkOption {
default = false;
description = ''
Whether the ISO image should be an efi-bootable volume.
'';
};
isoImage.makeUsbBootable = mkOption {
default = false;
description = ''
Whether the ISO image should be bootable from CD as well as USB.
'';
};
isoImage.efiSplashImage = mkOption {
default = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/NixOS/nixos-artwork/a9e05d7deb38a8e005a2b52575a3f59a63a4dba0/bootloader/efi-background.png";
sha256 = "18lfwmp8yq923322nlb9gxrh5qikj1wsk6g5qvdh31c4h5b1538x";
};
description = ''
The splash image to use in the EFI bootloader.
'';
};
isoImage.splashImage = mkOption {
default = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/NixOS/nixos-artwork/a9e05d7deb38a8e005a2b52575a3f59a63a4dba0/bootloader/isolinux/bios-boot.png";
sha256 = "1wp822zrhbg4fgfbwkr7cbkr4labx477209agzc0hr6k62fr6rxd";
};
description = ''
The splash image to use in the legacy-boot bootloader.
'';
};
isoImage.grubTheme = mkOption {
default = pkgs.nixos-grub2-theme;
type = types.nullOr (types.either types.path types.package);
description = ''
The grub2 theme used for UEFI boot.
'';
};
isoImage.syslinuxTheme = mkOption {
default = ''
MENU TITLE NixOS
MENU RESOLUTION 800 600
MENU CLEAR
MENU ROWS 6
MENU CMDLINEROW -4
MENU TIMEOUTROW -3
MENU TABMSGROW -2
MENU HELPMSGROW -1
MENU HELPMSGENDROW -1
MENU MARGIN 0
# FG:AARRGGBB BG:AARRGGBB shadow
MENU COLOR BORDER 30;44 #00000000 #00000000 none
MENU COLOR SCREEN 37;40 #FF000000 #00E2E8FF none
MENU COLOR TABMSG 31;40 #80000000 #00000000 none
MENU COLOR TIMEOUT 1;37;40 #FF000000 #00000000 none
MENU COLOR TIMEOUT_MSG 37;40 #FF000000 #00000000 none
MENU COLOR CMDMARK 1;36;40 #FF000000 #00000000 none
MENU COLOR CMDLINE 37;40 #FF000000 #00000000 none
MENU COLOR TITLE 1;36;44 #00000000 #00000000 none
MENU COLOR UNSEL 37;44 #FF000000 #00000000 none
MENU COLOR SEL 7;37;40 #FFFFFFFF #FF5277C3 std
'';
type = types.str;
description = ''
The syslinux theme used for BIOS boot.
'';
};
isoImage.appendToMenuLabel = mkOption {
default = " Installer";
example = " Live System";
description = ''
The string to append after the menu label for the NixOS system.
This will be directly appended (without whitespace) to the NixOS version
string, like for example if it is set to <literal>XXX</literal>:
<para><literal>NixOS 99.99-pre666XXX</literal></para>
'';
};
};
# store them in lib so we can mkImageMediaOverride the
# entire file system layout in installation media (only)
config.lib.isoFileSystems = {
"/" = mkImageMediaOverride
{
fsType = "tmpfs";
options = [ "mode=0755" ];
};
# Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1
# init script.
"/iso" = mkImageMediaOverride
{ device = "/dev/root";
neededForBoot = true;
noCheck = true;
};
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD.
"/nix/.ro-store" = mkImageMediaOverride
{ fsType = "squashfs";
device = "/iso/nix-store.squashfs";
options = [ "loop" ];
neededForBoot = true;
};
"/nix/.rw-store" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
neededForBoot = true;
};
"/nix/store" = mkImageMediaOverride
{ fsType = "overlay";
device = "overlay";
options = [
"lowerdir=/nix/.ro-store"
"upperdir=/nix/.rw-store/store"
"workdir=/nix/.rw-store/work"
];
depends = [
"/nix/.ro-store"
"/nix/.rw-store/store"
"/nix/.rw-store/work"
];
};
};
config = {
assertions = [
{
assertion = !(stringLength config.isoImage.volumeID > 32);
# https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor
# Volume Identifier can only be 32 bytes
message = let
length = stringLength config.isoImage.volumeID;
howmany = toString length;
toomany = toString (length - 32);
in
"isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32.";
}
];
boot.loader.grub.version = 2;
# Don't build the GRUB menu builder script, since we don't need it
# here and it causes a cyclic dependency.
boot.loader.grub.enable = false;
environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ]
++ optional canx86BiosBoot pkgs.syslinux
;
# In stage 1 of the boot, mount the CD as the root FS by label so
# that we don't need to know its device. We pass the label of the
# root filesystem on the kernel command line, rather than in
# `fileSystems' below. This allows CD-to-USB converters such as
# UNetbootin to rewrite the kernel command line to pass the label or
# UUID of the USB stick. It would be nicer to write
# `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
# recognise that.
boot.kernelParams =
[ "root=LABEL=${config.isoImage.volumeID}"
"boot.shell_on_fail"
];
fileSystems = config.lib.isoFileSystems;
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ];
boot.initrd.kernelModules = [ "loop" "overlay" ];
# Closures to be copied to the Nix store on the CD, namely the init
# script and the top-level system configuration directory.
isoImage.storeContents =
[ config.system.build.toplevel ] ++
optional config.isoImage.includeSystemBuildDependencies
config.system.build.toplevel.drvPath;
# Create the squashfs image that contains the Nix store.
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
storeContents = config.isoImage.storeContents;
comp = config.isoImage.squashfsCompression;
};
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
[
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
target = "/boot/" + config.system.boot.loader.kernelFile;
}
{ source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
target = "/boot/" + config.system.boot.loader.initrdFile;
}
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
}
{ source = pkgs.writeText "version" config.system.nixos.label;
target = "/version.txt";
}
] ++ optionals canx86BiosBoot [
{ source = config.isoImage.splashImage;
target = "/isolinux/background.png";
}
{ source = pkgs.substituteAll {
name = "isolinux.cfg";
src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
bootRoot = "/boot";
};
target = "/isolinux/isolinux.cfg";
}
{ source = "${pkgs.syslinux}/share/syslinux";
target = "/isolinux";
}
] ++ optionals config.isoImage.makeEfiBootable [
{ source = efiImg;
target = "/boot/efi.img";
}
{ source = "${efiDir}/EFI";
target = "/EFI";
}
{ source = (pkgs.writeTextDir "grub/loopback.cfg" "source /EFI/boot/grub.cfg") + "/grub";
target = "/boot/grub";
}
{ source = config.isoImage.efiSplashImage;
target = "/EFI/boot/efi-background.png";
}
] ++ optionals (config.boot.loader.grub.memtest86.enable && canx86BiosBoot) [
{ source = "${pkgs.memtest86plus}/memtest.bin";
target = "/boot/memtest.bin";
}
] ++ optionals (config.isoImage.grubTheme != null) [
{ source = config.isoImage.grubTheme;
target = "/EFI/boot/grub-theme";
}
];
boot.loader.timeout = 10;
# Create the ISO image.
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = canx86BiosBoot;
bootImage = "/isolinux/isolinux.bin";
syslinux = if canx86BiosBoot then pkgs.syslinux else null;
} // optionalAttrs (config.isoImage.makeUsbBootable && canx86BiosBoot) {
usbBootable = true;
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
} // optionalAttrs config.isoImage.makeEfiBootable {
efiBootable = true;
efiBootImage = "boot/efi.img";
});
boot.postBootCommands =
''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
${config.nix.package.out}/bin/nix-store --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# Add vfat support to the initrd to enable people to copy the
# contents of the CD to a bootable USB stick.
boot.initrd.supportedFilesystems = [ "vfat" ];
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
{
imports = [
../sd-card/sd-image-aarch64-new-kernel-installer.nix
];
config = {
warnings = [
''
.../cd-dvd/sd-image-aarch64-new-kernel.nix is deprecated and will eventually be removed.
Please switch to .../sd-card/sd-image-aarch64-new-kernel-installer.nix, instead.
''
];
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
{
imports = [
../sd-card/sd-image-aarch64-installer.nix
];
config = {
warnings = [
''
.../cd-dvd/sd-image-aarch64.nix is deprecated and will eventually be removed.
Please switch to .../sd-card/sd-image-aarch64-installer.nix, instead.
''
];
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
{
imports = [
../sd-card/sd-image-armv7l-multiplatform-installer.nix
];
config = {
warnings = [
''
.../cd-dvd/sd-image-armv7l-multiplatform.nix is deprecated and will eventually be removed.
Please switch to .../sd-card/sd-image-armv7l-multiplatform-installer.nix, instead.
''
];
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
{
imports = [
../sd-card/sd-image-raspberrypi-installer.nix
];
config = {
warnings = [
''
.../cd-dvd/sd-image-raspberrypi.nix is deprecated and will eventually be removed.
Please switch to .../sd-card/sd-image-raspberrypi-installer.nix, instead.
''
];
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
{
imports = [
../sd-card/sd-image.nix
];
config = {
warnings = [
''
.../cd-dvd/sd-image.nix is deprecated and will eventually be removed.
Please switch to .../sd-card/sd-image.nix, instead.
''
];
};
}

View file

@ -0,0 +1,160 @@
{ config, lib, pkgs, ... }:
with lib;
let
# A dummy /etc/nixos/configuration.nix in the booted CD that
# rebuilds the CD's configuration (and allows the configuration to
# be modified, of course, providing a true live CD). Problem is
# that we don't really know how the CD was built - the Nix
# expression language doesn't allow us to query the expression being
# evaluated. So we'll just hope for the best.
dummyConfiguration = pkgs.writeText "configuration.nix"
''
{ config, pkgs, ... }:
{ # Add your own options below, e.g.:
# services.openssh.enable = true;
nixpkgs.config.platform = pkgs.platforms.fuloong2f_n32;
}
'';
pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l;
# A clue for the kernel loading
kernelParams = pkgs.writeText "kernel-params.txt" ''
Kernel Parameters:
init=/boot/init ${toString config.boot.kernelParams}
'';
# System wide nixpkgs config
nixpkgsUserConfig = pkgs.writeText "config.nix" ''
pkgs:
{
platform = pkgs.platforms.fuloong2f_n32;
}
'';
in
{
imports = [ ./system-tarball.nix ];
# Disable some other stuff we don't need.
security.sudo.enable = false;
# Include only the en_US locale. This saves 75 MiB or so compared to
# the full glibcLocales package.
i18n.supportedLocales = ["en_US.UTF-8/UTF-8" "en_US/ISO-8859-1"];
# Include some utilities that are useful for installing or repairing
# the system.
environment.systemPackages =
[ pkgs.w3m # needed for the manual anyway
pkgs.testdisk # useful for repairing boot problems
pkgs.ms-sys # for writing Microsoft boot sectors / MBRs
pkgs.parted
pkgs.ddrescue
pkgs.ccrypt
pkgs.cryptsetup # needed for dm-crypt volumes
# Some networking tools.
pkgs.sshfs-fuse
pkgs.socat
pkgs.screen
pkgs.wpa_supplicant # !!! should use the wpa module
# Hardware-related tools.
pkgs.sdparm
pkgs.hdparm
pkgs.dmraid
# Tools to create / manipulate filesystems.
pkgs.ntfsprogs # for resizing NTFS partitions
pkgs.btrfs-progs
pkgs.jfsutils
# Some compression/archiver tools.
pkgs.unzip
pkgs.zip
pkgs.xz
pkgs.dar # disk archiver
# Some editors.
pkgs.nvi
pkgs.bvi # binary editor
pkgs.joe
];
# The initrd has to contain any module that might be necessary for
# mounting the CD/DVD.
boot.initrd.availableKernelModules =
[ "vfat" "reiserfs" ];
boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10;
boot.kernelParams = [ "console=tty1" ];
boot.postBootCommands =
''
mkdir -p /mnt
cp ${dummyConfiguration} /etc/nixos/configuration.nix
'';
# Some more help text.
services.getty.helpLine =
''
Log in as "root" with an empty password. ${
if config.services.xserver.enable then
"Type `start xserver' to start\nthe graphical user interface."
else ""
}
'';
# Include the firmware for various wireless cards.
networking.enableRalinkFirmware = true;
networking.enableIntel2200BGFirmware = true;
# To speed up further installation of packages, include the complete stdenv
# in the Nix store of the tarball.
tarball.storeContents = pkgs2storeContents [ pkgs.stdenv ]
++ [
{
object = config.system.build.bootStage2;
symlink = "/boot/init";
}
{
object = config.system.build.toplevel;
symlink = "/boot/system";
}
];
tarball.contents = [
{ source = kernelParams;
target = "/kernelparams.txt";
}
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
target = "/boot/" + config.system.boot.loader.kernelFile;
}
{ source = nixpkgsUserConfig;
target = "/root/.nixpkgs/config.nix";
}
];
# Allow sshd to be started manually through "start sshd". It should
# not be started by default on the installation CD because the
# default root password is empty.
services.openssh.enable = true;
systemd.services.openssh.wantedBy = lib.mkOverride 50 [];
boot.loader.grub.enable = false;
boot.loader.generationsDir.enable = false;
system.boot.loader.kernelFile = "vmlinux";
nixpkgs.config = {
platform = pkgs.platforms.fuloong2f_n32;
};
}

View file

@ -0,0 +1,89 @@
Let all the files in the system tarball sit in a directory served by NFS (the
NFS root) like this in exportfs:
/home/pcroot 192.168.1.0/24(rw,no_root_squash,no_all_squash)
Run "exportfs -a" after editing /etc/exportfs, for the nfs server to be aware
of the changes.
Use a tftp server serving the root of boot/ (from the system tarball).
In order to have PXE boot, use the boot/dhcpd.conf-example file for your dhcpd
server, as it will point your PXE clients to pxelinux.0 from the tftp server.
Adapt the configuration to your network.
Adapt the pxelinux configuration (boot/pxelinux.cfg/default) to set the path to
your nfrroot. If you use ip=dhcp in the kernel, the nfs server ip will be taken
from dhcp and so you don't have to specify it.
The linux in bzImage includes network drivers for some usual cards.
QEMU Testing
---------------
You can test qemu pxe boot without having a DHCP server adapted, but having
nfsroot, like this:
qemu-system-x86_64 -tftp /home/pcroot/boot -net nic -net user,bootfile=pxelinux.0 -boot n
I don't know how to use NFS through the qemu '-net user' though.
QEMU Testing with NFS root and bridged network
-------------------------------------------------
This allows testing with qemu as any other host in your LAN.
Testing with the real dhcpd server requires setting up a bridge and having a
tap device.
tunctl -t tap0
brctl addbr br0
brctl addif br0 eth0
brctl addif tap0 eth0
ifconfig eth0 0.0.0.0 up
ifconfig tap0 0.0.0.0 up
ifconfig br0 up # With your ip configuration
Then you can run qemu:
qemu-system-x86_64 -boot n -net tap,ifname=tap0,script=no -net nic,model=e1000
Using the system-tarball-pc in a chroot
--------------------------------------------------
Installation:
mkdir nixos-chroot && cd nixos-chroot
tar xf your-system-tarball.tar.xz
mkdir sys dev proc tmp root var run
mount --bind /sys sys
mount --bind /dev dev
mount --bind /proc proc
Activate the system: look for a directory in nix/store similar to:
"/nix/store/y0d1lcj9fppli0hl3x0m0ba5g1ndjv2j-nixos-feb97bx-53f008"
Having found it, activate that nixos system *twice*:
chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate
chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate
This runs a 'hostname' command. Restore your old hostname with:
hostname OLDHOSTNAME
Copy your system resolv.conf to the /etc/resolv.conf inside the chroot:
cp /etc/resolv.conf etc
Then you can get an interactive shell in the nixos chroot. '*' means
to run inside the chroot interactive shell
chroot . /bin/sh
* source /etc/profile
Populate the nix database: that should be done in the init script if you
had booted this nixos. Run:
* `grep local-cmds run/current-system/init`
Then you can proceed normally subscribing to a nixos channel:
nix-channel --add https://nixos.org/channels/nixos-unstable
nix-channel --update
Testing:
nix-env -i hello
which hello
hello

View file

@ -0,0 +1,163 @@
# This module contains the basic configuration for building a NixOS
# tarball, that can directly boot, maybe using PXE or unpacking on a fs.
{ config, lib, pkgs, ... }:
with lib;
let
pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l;
# For PXE kernel loading
pxeconfig = pkgs.writeText "pxeconfig-default" ''
default menu.c32
prompt 0
label bootlocal
menu default
localboot 0
timeout 80
TOTALTIMEOUT 9000
label nixos
MENU LABEL ^NixOS using nfsroot
KERNEL bzImage
append ip=dhcp nfsroot=/home/pcroot init=${config.system.build.toplevel}/init rw
# I don't know how to make this boot with nfsroot (using the initrd)
label nixos_initrd
MENU LABEL NixOS booting the poor ^initrd.
KERNEL bzImage
append initrd=initrd ip=dhcp nfsroot=/home/pcroot init=${config.system.build.toplevel}/init rw
label memtest
MENU LABEL ^${pkgs.memtest86.name}
KERNEL memtest
'';
dhcpdExampleConfig = pkgs.writeText "dhcpd.conf-example" ''
# Example configuration for booting PXE.
allow booting;
allow bootp;
# Adapt this to your network configuration.
option domain-name "local";
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option domain-name-servers 192.168.1.1;
option routers 192.168.1.1;
# PXE-specific configuration directives...
# Some BIOS don't accept slashes for paths inside the tftp servers,
# and will report Access Violation if they see slashes.
filename "pxelinux.0";
# For the TFTP and NFS root server. Set the IP of your server.
next-server 192.168.1.34;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.50 192.168.1.55;
}
'';
readme = ./system-tarball-pc-readme.txt;
in
{
imports =
[ ./system-tarball.nix
# Profiles of this basic installation.
../../profiles/all-hardware.nix
../../profiles/base.nix
../../profiles/installation-device.nix
];
# To speed up further installation of packages, include the complete stdenv
# in the Nix store of the tarball.
tarball.storeContents = pkgs2storeContents [ pkgs.stdenv ];
tarball.contents =
[ { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
target = "/boot/" + config.system.boot.loader.kernelFile;
}
{ source = "${pkgs.syslinux}/share/syslinux/pxelinux.0";
target = "/boot/pxelinux.0";
}
{ source = "${pkgs.syslinux}/share/syslinux/menu.c32";
target = "/boot/menu.c32";
}
{ source = pxeconfig;
target = "/boot/pxelinux.cfg/default";
}
{ source = readme;
target = "/readme.txt";
}
{ source = dhcpdExampleConfig;
target = "/boot/dhcpd.conf-example";
}
{ source = "${pkgs.memtest86}/memtest.bin";
# We can't leave '.bin', because pxelinux interprets this specially,
# and it would not load the image fine.
# http://forum.canardpc.com/threads/46464-0104-when-launched-via-pxe
target = "/boot/memtest";
}
];
# Allow sshd to be started manually through "start sshd". It should
# not be started by default on the installation CD because the
# default root password is empty.
services.openssh.enable = true;
systemd.services.openssh.wantedBy = lib.mkOverride 50 [];
# To be able to use the systemTarball to catch troubles.
boot.crashDump = {
enable = true;
kernelPackages = pkgs.linuxKernel.packages.linux_3_4;
};
# No grub for the tarball.
boot.loader.grub.enable = false;
/* fake entry, just to have a happy stage-1. Users
may boot without having stage-1 though */
fileSystems.fake =
{ mountPoint = "/";
device = "/dev/something";
};
nixpkgs.config = {
packageOverrides = p: {
linux_3_4 = p.linux_3_4.override {
extraConfig = ''
# Enable drivers in kernel for most NICs.
E1000 y
# E1000E y
# ATH5K y
8139TOO y
NE2K_PCI y
ATL1 y
ATL1E y
ATL1C y
VORTEX y
VIA_RHINE y
R8169 y
# Enable nfs root boot
UNIX y # http://www.linux-mips.org/archives/linux-mips/2006-11/msg00113.html
IP_PNP y
IP_PNP_DHCP y
FSCACHE y
NFS_FS y
NFS_FSCACHE y
ROOT_NFS y
# Enable devtmpfs
DEVTMPFS y
DEVTMPFS_MOUNT y
'';
};
};
};
}

View file

@ -0,0 +1,172 @@
# This module contains the basic configuration for building a NixOS
# tarball for the sheevaplug.
{ config, lib, pkgs, ... }:
with lib;
let
# A dummy /etc/nixos/configuration.nix in the booted CD that
# rebuilds the CD's configuration (and allows the configuration to
# be modified, of course, providing a true live CD). Problem is
# that we don't really know how the CD was built - the Nix
# expression language doesn't allow us to query the expression being
# evaluated. So we'll just hope for the best.
dummyConfiguration = pkgs.writeText "configuration.nix"
''
{ config, pkgs, ... }:
{
# Add your own options below and run "nixos-rebuild switch".
# E.g.,
# services.openssh.enable = true;
}
'';
pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l;
# A clue for the kernel loading
kernelParams = pkgs.writeText "kernel-params.txt" ''
Kernel Parameters:
init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
'';
in
{
imports = [ ./system-tarball.nix ];
# Disable some other stuff we don't need.
security.sudo.enable = false;
# Include only the en_US locale. This saves 75 MiB or so compared to
# the full glibcLocales package.
i18n.supportedLocales = ["en_US.UTF-8/UTF-8" "en_US/ISO-8859-1"];
# Include some utilities that are useful for installing or repairing
# the system.
environment.systemPackages =
[ pkgs.w3m # needed for the manual anyway
pkgs.ddrescue
pkgs.ccrypt
pkgs.cryptsetup # needed for dm-crypt volumes
# Some networking tools.
pkgs.sshfs-fuse
pkgs.socat
pkgs.screen
pkgs.wpa_supplicant # !!! should use the wpa module
# Hardware-related tools.
pkgs.sdparm
pkgs.hdparm
pkgs.dmraid
# Tools to create / manipulate filesystems.
pkgs.btrfs-progs
# Some compression/archiver tools.
pkgs.unzip
pkgs.zip
pkgs.xz
pkgs.dar # disk archiver
# Some editors.
pkgs.nvi
pkgs.bvi # binary editor
pkgs.joe
];
boot.loader.grub.enable = false;
boot.loader.generationsDir.enable = false;
system.boot.loader.kernelFile = "uImage";
boot.initrd.availableKernelModules =
[ "mvsdio" "reiserfs" "ext3" "ums-cypress" "rtc_mv" "ext4" ];
boot.postBootCommands = lib.mkIf (!boot.initrd.systemd.enable)
''
mkdir -p /mnt
cp ${dummyConfiguration} /etc/nixos/configuration.nix
'';
boot.initrd.extraUtilsCommands = lib.mkIf (!boot.initrd.systemd.enable)
''
copy_bin_and_libs ${pkgs.util-linux}/sbin/hwclock
'';
boot.initrd.postDeviceCommands = lib.mkIf (!boot.initrd.systemd.enable)
''
hwclock -s
'';
boot.kernelParams =
[
"selinux=0"
"console=tty1"
# "console=ttyS0,115200n8" # serial console
];
boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_4;
boot.supportedFilesystems = [ "reiserfs" ];
/* fake entry, just to have a happy stage-1. Users
may boot without having stage-1 though */
fileSystems.fake =
{ mountPoint = "/";
device = "/dev/something";
};
services.getty = {
# Some more help text.
helpLine = ''
Log in as "root" with an empty password. ${
if config.services.xserver.enable then
"Type `start xserver' to start\nthe graphical user interface."
else ""
}
'';
};
# Setting vesa, we don't get the nvidia driver, which can't work in arm.
services.xserver.videoDrivers = [ "vesa" ];
documentation.nixos.enable = false;
# Include the firmware for various wireless cards.
networking.enableRalinkFirmware = true;
networking.enableIntel2200BGFirmware = true;
# To speed up further installation of packages, include the complete stdenv
# in the Nix store of the tarball.
tarball.storeContents = pkgs2storeContents [ pkgs.stdenv ];
tarball.contents = [
{ source = kernelParams;
target = "/kernelparams.txt";
}
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
target = "/boot/" + config.system.boot.loader.kernelFile;
}
{ source = pkgs.ubootSheevaplug;
target = "/boot/uboot";
}
];
# Allow sshd to be started manually through "start sshd". It should
# not be started by default on the installation CD because the
# default root password is empty.
services.openssh.enable = true;
systemd.services.openssh.wantedBy = lib.mkOverride 50 [];
# cpufrequtils fails to build on non-pc
powerManagement.enable = false;
nixpkgs.config = {
platform = pkgs.platforms.sheevaplug;
};
}

View file

@ -0,0 +1,93 @@
# This module creates a bootable ISO image containing the given NixOS
# configuration. The derivation for the ISO image will be placed in
# config.system.build.tarball.
{ config, lib, pkgs, ... }:
with lib;
let
versionFile = pkgs.writeText "nixos-label" config.system.nixos.label;
in
{
options = {
tarball.contents = mkOption {
example = literalExpression ''
[ { source = pkgs.memtest86 + "/memtest.bin";
target = "boot/memtest.bin";
}
]
'';
description = ''
This option lists files to be copied to fixed locations in the
generated ISO image.
'';
};
tarball.storeContents = mkOption {
example = literalExpression "[ pkgs.stdenv ]";
description = ''
This option lists additional derivations to be included in the
Nix store in the generated ISO image.
'';
};
};
config = {
# In stage 1 of the boot, mount the CD/DVD as the root FS by label
# so that we don't need to know its device.
fileSystems = { };
# boot.initrd.availableKernelModules = [ "mvsdio" "reiserfs" "ext3" "ext4" ];
# boot.initrd.kernelModules = [ "rtc_mv" ];
# Closures to be copied to the Nix store on the CD, namely the init
# script and the top-level system configuration directory.
tarball.storeContents =
[ { object = config.system.build.toplevel;
symlink = "/run/current-system";
}
];
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
tarball.contents =
[ { source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
target = "/boot/" + config.system.boot.loader.initrdFile;
}
{ source = versionFile;
target = "/nixos-version.txt";
}
];
# Create the tarball
system.build.tarball = import ../../../lib/make-system-tarball.nix {
inherit (pkgs) stdenv closureInfo pixz;
inherit (config.tarball) contents storeContents;
};
boot.postBootCommands =
''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
}

View file

@ -0,0 +1,51 @@
# This module exposes a config.system.build.kexecBoot attribute,
# which returns a directory with kernel, initrd and a shell script
# running the necessary kexec commands.
# It's meant to be scp'ed to a machine with working ssh and kexec binary
# installed.
# This is useful for (cloud) providers where you can't boot a custom image, but
# get some Debian or Ubuntu installation.
{ pkgs
, modulesPath
, config
, ...
}:
{
imports = [
(modulesPath + "/installer/netboot/netboot-minimal.nix")
];
config = {
system.build.kexecBoot =
let
kexecScript = pkgs.writeScript "kexec-boot" ''
#!/usr/bin/env bash
if ! kexec -v >/dev/null 2>&1; then
echo "kexec not found: please install kexec-tools" 2>&1
exit 1
fi
SCRIPT_DIR=$( cd -- "$( dirname -- "''${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
kexec --load ''${SCRIPT_DIR}/bzImage \
--initrd=''${SCRIPT_DIR}/initrd.gz \
--command-line "init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}"
kexec -e
''; in
pkgs.linkFarm "kexec-tree" [
{
name = "initrd.gz";
path = "${config.system.build.netbootRamdisk}/initrd";
}
{
name = "bzImage";
path = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}";
}
{
name = "kexec-boot";
path = kexecScript;
}
];
};
}

View file

@ -0,0 +1,17 @@
# This module contains the basic configuration for building netboot
# images
{ lib, ... }:
with lib;
{
imports =
[ ./netboot.nix
# Profiles of this basic netboot media
../../profiles/all-hardware.nix
../../profiles/base.nix
../../profiles/installation-device.nix
];
}

View file

@ -0,0 +1,10 @@
# This module defines a small netboot environment.
{ ... }:
{
imports =
[ ./netboot-base.nix
../../profiles/minimal.nix
];
}

View file

@ -0,0 +1,120 @@
# This module creates netboot media containing the given NixOS
# configuration.
{ config, lib, pkgs, ... }:
with lib;
{
options = {
netboot.storeContents = mkOption {
example = literalExpression "[ pkgs.stdenv ]";
description = ''
This option lists additional derivations to be included in the
Nix store in the generated netboot image.
'';
};
};
config = {
# Don't build the GRUB menu builder script, since we don't need it
# here and it causes a cyclic dependency.
boot.loader.grub.enable = false;
# !!! Hack - attributes expected by other modules.
environment.systemPackages = [ pkgs.grub2_efi ]
++ (if pkgs.stdenv.hostPlatform.system == "aarch64-linux"
then []
else [ pkgs.grub2 pkgs.syslinux ]);
fileSystems."/" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
};
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD.
fileSystems."/nix/.ro-store" = mkImageMediaOverride
{ fsType = "squashfs";
device = "../nix-store.squashfs";
options = [ "loop" ];
neededForBoot = true;
};
fileSystems."/nix/.rw-store" = mkImageMediaOverride
{ fsType = "tmpfs";
options = [ "mode=0755" ];
neededForBoot = true;
};
fileSystems."/nix/store" = mkImageMediaOverride
{ fsType = "overlay";
device = "overlay";
options = [
"lowerdir=/nix/.ro-store"
"upperdir=/nix/.rw-store/store"
"workdir=/nix/.rw-store/work"
];
depends = [
"/nix/.ro-store"
"/nix/.rw-store/store"
"/nix/.rw-store/work"
];
};
boot.initrd.availableKernelModules = [ "squashfs" "overlay" ];
boot.initrd.kernelModules = [ "loop" "overlay" ];
# Closures to be copied to the Nix store, namely the init
# script and the top-level system configuration directory.
netboot.storeContents =
[ config.system.build.toplevel ];
# Create the squashfs image that contains the Nix store.
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
storeContents = config.netboot.storeContents;
};
# Create the initrd
system.build.netbootRamdisk = pkgs.makeInitrd {
inherit (config.boot.initrd) compressor;
prepend = [ "${config.system.build.initialRamdisk}/initrd" ];
contents =
[ { object = config.system.build.squashfsStore;
symlink = "/nix-store.squashfs";
}
];
};
system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" ''
#!ipxe
# Use the cmdline variable to allow the user to specify custom kernel params
# when chainloading this script from other iPXE scripts like netboot.xyz
kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline}
initrd initrd
boot
'';
boot.loader.timeout = 10;
boot.postBootCommands =
''
# After booting, register the contents of the Nix store
# in the Nix database in the tmpfs.
${config.nix.package}/bin/nix-store --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
}

View file

@ -0,0 +1,12 @@
# List all devices which are detected by nixos-generate-config.
# Common devices are enabled by default.
{ lib, ... }:
with lib;
{
config = mkDefault {
# Common firmware, i.e. for wifi cards
hardware.enableRedistributableFirmware = true;
};
}

View file

@ -0,0 +1,6 @@
# Enables non-free firmware on devices not recognized by `nixos-generate-config`.
{ lib, ... }:
{
hardware.enableRedistributableFirmware = lib.mkDefault true;
}

View file

@ -0,0 +1,10 @@
{
imports = [
../../profiles/installation-device.nix
./sd-image-aarch64.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View file

@ -0,0 +1,10 @@
{
imports = [
../../profiles/installation-device.nix
./sd-image-aarch64-new-kernel.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View file

@ -0,0 +1,7 @@
{ pkgs, ... }:
{
imports = [ ./sd-image-aarch64.nix ];
boot.kernelPackages = pkgs.linuxPackages_latest;
}

View file

@ -0,0 +1,83 @@
# To build, use:
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-aarch64.nix -A config.system.build.sdImage
{ config, lib, pkgs, ... }:
{
imports = [
../../profiles/base.nix
./sd-image.nix
];
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.consoleLogLevel = lib.mkDefault 7;
# The serial ports listed here are:
# - ttyS0: for Tegra (Jetson TX1)
# - ttyAMA0: for QEMU's -machine virt
boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
sdImage = {
populateFirmwareCommands = let
configTxt = pkgs.writeText "config.txt" ''
[pi3]
kernel=u-boot-rpi3.bin
[pi02]
kernel=u-boot-rpi3.bin
[pi4]
kernel=u-boot-rpi4.bin
enable_gic=1
armstub=armstub8-gic.bin
# Otherwise the resolution will be weird in most cases, compared to
# what the pi3 firmware does by default.
disable_overscan=1
# Supported in newer board revisions
arm_boost=1
[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1
[all]
# Boot in 64-bit mode.
arm_64bit=1
# U-Boot needs this to work, regardless of whether UART is actually used or not.
# Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
# a requirement in the future.
enable_uart=1
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
'';
in ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
# Add the config
cp ${configTxt} firmware/config.txt
# Add pi3 specific files
cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
# Add pi4 specific files
cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin firmware/u-boot-rpi4.bin
cp ${pkgs.raspberrypi-armstubs}/armstub8-gic.bin firmware/armstub8-gic.bin
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-4-b.dtb firmware/
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-400.dtb firmware/
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-cm4.dtb firmware/
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-cm4s.dtb firmware/
'';
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View file

@ -0,0 +1,10 @@
{
imports = [
../../profiles/installation-device.nix
./sd-image-armv7l-multiplatform.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View file

@ -0,0 +1,52 @@
# To build, use:
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage
{ config, lib, pkgs, ... }:
{
imports = [
../../profiles/base.nix
./sd-image.nix
];
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.consoleLogLevel = lib.mkDefault 7;
boot.kernelPackages = pkgs.linuxPackages_latest;
# The serial ports listed here are:
# - ttyS0: for Tegra (Jetson TK1)
# - ttymxc0: for i.MX6 (Wandboard)
# - ttyAMA0: for Allwinner (pcDuino3 Nano) and QEMU's -machine virt
# - ttyO0: for OMAP (BeagleBone Black)
# - ttySAC2: for Exynos (ODROID-XU3)
boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=ttySAC2,115200n8" "console=tty0"];
sdImage = {
populateFirmwareCommands = let
configTxt = pkgs.writeText "config.txt" ''
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
[pi2]
kernel=u-boot-rpi2.bin
[pi3]
kernel=u-boot-rpi3.bin
# U-Boot used to need this to work, regardless of whether UART is actually used or not.
# TODO: check when/if this can be removed.
enable_uart=1
'';
in ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
cp ${pkgs.ubootRaspberryPi2}/u-boot.bin firmware/u-boot-rpi2.bin
cp ${pkgs.ubootRaspberryPi3_32bit}/u-boot.bin firmware/u-boot-rpi3.bin
cp ${configTxt} firmware/config.txt
'';
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View file

@ -0,0 +1,10 @@
{
imports = [
../../profiles/installation-device.nix
./sd-image-raspberrypi.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View file

@ -0,0 +1,41 @@
# To build, use:
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-raspberrypi.nix -A config.system.build.sdImage
{ config, lib, pkgs, ... }:
{
imports = [
../../profiles/base.nix
./sd-image.nix
];
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.consoleLogLevel = lib.mkDefault 7;
boot.kernelPackages = pkgs.linuxKernel.packages.linux_rpi1;
sdImage = {
populateFirmwareCommands = let
configTxt = pkgs.writeText "config.txt" ''
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
[pi0]
kernel=u-boot-rpi0.bin
[pi1]
kernel=u-boot-rpi1.bin
'';
in ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
cp ${pkgs.ubootRaspberryPiZero}/u-boot.bin firmware/u-boot-rpi0.bin
cp ${pkgs.ubootRaspberryPi}/u-boot.bin firmware/u-boot-rpi1.bin
cp ${configTxt} firmware/config.txt
'';
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View file

@ -0,0 +1,10 @@
{
imports = [
../../profiles/installation-device.nix
./sd-image-riscv64-qemu.nix
];
# the installation media is also the installation target,
# so we don't want to provide the installation configuration.nix.
installer.cloneConfig = false;
}

View file

@ -0,0 +1,32 @@
# To build, use:
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-riscv64-qemu.nix -A config.system.build.sdImage
{ config, lib, pkgs, ... }:
{
imports = [
../../profiles/base.nix
./sd-image.nix
];
boot.loader = {
grub.enable = false;
generic-extlinux-compatible = {
enable = true;
# Don't even specify FDTDIR - We do not have the correct DT
# The DTB is generated by QEMU at runtime
useGenerationDeviceTree = false;
};
};
boot.consoleLogLevel = lib.mkDefault 7;
boot.kernelParams = [ "console=tty0" "console=ttyS0,115200n8" ];
sdImage = {
populateFirmwareCommands = "";
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View file

@ -0,0 +1,27 @@
# To build, use:
# nix-build nixos -I nixos-config=nixos/modules/installer/sd-card/sd-image-x86_64.nix -A config.system.build.sdImage
# This image is primarily used in NixOS tests (boot.nix) to test `boot.loader.generic-extlinux-compatible`.
{ config, lib, pkgs, ... }:
{
imports = [
../../profiles/base.nix
./sd-image.nix
];
boot.loader = {
grub.enable = false;
generic-extlinux-compatible.enable = true;
};
boot.consoleLogLevel = lib.mkDefault 7;
sdImage = {
populateFirmwareCommands = "";
populateRootCommands = ''
mkdir -p ./files/boot
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
'';
};
}

View file

@ -0,0 +1,269 @@
# This module creates a bootable SD card image containing the given NixOS
# configuration. The generated image is MBR partitioned, with a FAT
# /boot/firmware partition, and ext4 root partition. The generated image
# is sized to fit its contents, and a boot script automatically resizes
# the root partition to fit the device on the first boot.
#
# The firmware partition is built with expectation to hold the Raspberry
# Pi firmware and bootloader, and be removed and replaced with a firmware
# build for the target SoC for other board families.
#
# The derivation for the SD image will be placed in
# config.system.build.sdImage
{ config, lib, pkgs, ... }:
with lib;
let
rootfsImage = pkgs.callPackage ../../../lib/make-ext4-fs.nix ({
inherit (config.sdImage) storePaths;
compressImage = true;
populateImageCommands = config.sdImage.populateRootCommands;
volumeLabel = "NIXOS_SD";
} // optionalAttrs (config.sdImage.rootPartitionUUID != null) {
uuid = config.sdImage.rootPartitionUUID;
});
in
{
imports = [
(mkRemovedOptionModule [ "sdImage" "bootPartitionID" ] "The FAT partition for SD image now only holds the Raspberry Pi firmware files. Use firmwarePartitionID to configure that partition's ID.")
(mkRemovedOptionModule [ "sdImage" "bootSize" ] "The boot files for SD image have been moved to the main ext4 partition. The FAT partition now only holds the Raspberry Pi firmware files. Changing its size may not be required.")
../../profiles/all-hardware.nix
];
options.sdImage = {
imageName = mkOption {
default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.img";
description = ''
Name of the generated image file.
'';
};
imageBaseName = mkOption {
default = "nixos-sd-image";
description = ''
Prefix of the name of the generated image file.
'';
};
storePaths = mkOption {
type = with types; listOf package;
example = literalExpression "[ pkgs.stdenv ]";
description = ''
Derivations to be included in the Nix store in the generated SD image.
'';
};
firmwarePartitionOffset = mkOption {
type = types.int;
default = 8;
description = ''
Gap in front of the /boot/firmware partition, in mebibytes (1024×1024
bytes).
Can be increased to make more space for boards requiring to dd u-boot
SPL before actual partitions.
Unless you are building your own images pre-configured with an
installed U-Boot, you can instead opt to delete the existing `FIRMWARE`
partition, which is used **only** for the Raspberry Pi family of
hardware.
'';
};
firmwarePartitionID = mkOption {
type = types.str;
default = "0x2178694e";
description = ''
Volume ID for the /boot/firmware partition on the SD card. This value
must be a 32-bit hexadecimal number.
'';
};
firmwarePartitionName = mkOption {
type = types.str;
default = "FIRMWARE";
description = ''
Name of the filesystem which holds the boot firmware.
'';
};
rootPartitionUUID = mkOption {
type = types.nullOr types.str;
default = null;
example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7";
description = ''
UUID for the filesystem on the main NixOS partition on the SD card.
'';
};
firmwareSize = mkOption {
type = types.int;
# As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
default = 30;
description = ''
Size of the /boot/firmware partition, in megabytes.
'';
};
populateFirmwareCommands = mkOption {
example = literalExpression "'' cp \${pkgs.myBootLoader}/u-boot.bin firmware/ ''";
description = ''
Shell commands to populate the ./firmware directory.
All files in that directory are copied to the
/boot/firmware partition on the SD image.
'';
};
populateRootCommands = mkOption {
example = literalExpression "''\${config.boot.loader.generic-extlinux-compatible.populateCmd} -c \${config.system.build.toplevel} -d ./files/boot''";
description = ''
Shell commands to populate the ./files directory.
All files in that directory are copied to the
root (/) partition on the SD image. Use this to
populate the ./files/boot (/boot) directory.
'';
};
postBuildCommands = mkOption {
example = literalExpression "'' dd if=\${pkgs.myBootLoader}/SPL of=$img bs=1024 seek=1 conv=notrunc ''";
default = "";
description = ''
Shell commands to run after the image is built.
Can be used for boards requiring to dd u-boot SPL before actual partitions.
'';
};
compressImage = mkOption {
type = types.bool;
default = true;
description = ''
Whether the SD image should be compressed using
<command>zstd</command>.
'';
};
expandOnBoot = mkOption {
type = types.bool;
default = true;
description = ''
Whether to configure the sd image to expand it's partition on boot.
'';
};
};
config = {
fileSystems = {
"/boot/firmware" = {
device = "/dev/disk/by-label/${config.sdImage.firmwarePartitionName}";
fsType = "vfat";
# Alternatively, this could be removed from the configuration.
# The filesystem is not needed at runtime, it could be treated
# as an opaque blob instead of a discrete FAT32 filesystem.
options = [ "nofail" "noauto" ];
};
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
};
};
sdImage.storePaths = [ config.system.build.toplevel ];
system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs,
mtools, libfaketime, util-linux, zstd }: stdenv.mkDerivation {
name = config.sdImage.imageName;
nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
inherit (config.sdImage) imageName compressImage;
buildCommand = ''
mkdir -p $out/nix-support $out/sd-image
export img=$out/sd-image/${config.sdImage.imageName}
echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
if test -n "$compressImage"; then
echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products
else
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
fi
echo "Decompressing rootfs image"
zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img
# Gap in front of the first partition, in MiB
gap=${toString config.sdImage.firmwarePartitionOffset}
# Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }')
firmwareSizeBlocks=$((${toString config.sdImage.firmwareSize} * 1024 * 1024 / 512))
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
truncate -s $imageSize $img
# type=b is 'W95 FAT32', type=83 is 'Linux'.
# The "bootable" partition is where u-boot will look file for the bootloader
# information (dtbs, extlinux.conf file).
sfdisk $img <<EOF
label: dos
label-id: ${config.sdImage.firmwarePartitionID}
start=''${gap}M, size=$firmwareSizeBlocks, type=b
start=$((gap + ${toString config.sdImage.firmwareSize}))M, type=83, bootable
EOF
# Copy the rootfs into the SD image
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
dd conv=notrunc if=./root-fs.img of=$img seek=$START count=$SECTORS
# Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
truncate -s $((SECTORS * 512)) firmware_part.img
faketime "1970-01-01 00:00:00" mkfs.vfat -i ${config.sdImage.firmwarePartitionID} -n ${config.sdImage.firmwarePartitionName} firmware_part.img
# Populate the files intended for /boot/firmware
mkdir firmware
${config.sdImage.populateFirmwareCommands}
# Copy the populated /boot/firmware into the SD image
(cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
# Verify the FAT partition before copying it.
fsck.vfat -vn firmware_part.img
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
${config.sdImage.postBuildCommands}
if test -n "$compressImage"; then
zstd -T$NIX_BUILD_CORES --rm $img
fi
'';
}) {};
boot.postBootCommands = lib.mkIf config.sdImage.expandOnBoot ''
# 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.util-linux}/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
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration
# nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/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
'';
};
}

View file

@ -0,0 +1,22 @@
getVersion() {
local dir="$1"
rev=
if [ -e "$dir/.git" ]; then
if [ -z "$(type -P git)" ]; then
echo "warning: Git not found; cannot figure out revision of $dir" >&2
return
fi
cd "$dir"
rev=$(git rev-parse --short HEAD)
if git describe --always --dirty | grep -q dirty; then
rev+=M
fi
fi
}
if nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then
getVersion $nixpkgs
if [ -n "$rev" ]; then
echo ".git.$rev"
fi
fi

View file

@ -0,0 +1,7 @@
{
x86_64-linux = "/nix/store/6mjgljq8sm9bsz6k22as5ar3jw78644m-nix-2.8.1";
i686-linux = "/nix/store/c4yjv4l8wncdla6ycicvsjrdf40xjkpp-nix-2.8.1";
aarch64-linux = "/nix/store/qkgvks80mdibq7m86hqasgr5lpixbnmh-nix-2.8.1";
x86_64-darwin = "/nix/store/riz4mzb1xhp36088ffnp40lz52bpxz01-nix-2.8.1";
aarch64-darwin = "/nix/store/dirm8hsnmvvzjs21hrx8i84w8k453jzp-nix-2.8.1";
}

View file

@ -0,0 +1,31 @@
{ system ? builtins.currentSystem
, config ? {}
, networkExpr
}:
let
nodes = builtins.mapAttrs (vm: module: {
_file = "${networkExpr}@node-${vm}";
imports = [ module ];
}) (import networkExpr);
pkgs = import ../../../../.. { inherit system config; };
testing = import ../../../../lib/testing-python.nix {
inherit system pkgs;
};
interactiveDriver = (testing.makeTest { inherit nodes; testScript = "start_all(); join_all();"; }).driverInteractive;
in
pkgs.runCommand "nixos-build-vms" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
mkdir -p $out/bin
ln -s ${interactiveDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
ln -s ${interactiveDriver}/bin/nixos-test-driver $out/bin/nixos-run-vms
wrapProgram $out/bin/nixos-test-driver \
--add-flags "--interactive"
wrapProgram $out/bin/nixos-run-vms \
--set testScript "${pkgs.writeText "start-all" "start_all(); join_all();"}" \
--add-flags "--no-interactive"
''

View file

@ -0,0 +1,53 @@
#! @runtimeShell@ -e
# shellcheck shell=bash
# Shows the usage of this command to the user
showUsage() {
exec man nixos-build-vms
exit 1
}
# Parse valid argument options
nixBuildArgs=()
networkExpr=
while [ $# -gt 0 ]; do
case "$1" in
--no-out-link)
nixBuildArgs+=("--no-out-link")
;;
--show-trace)
nixBuildArgs+=("--show-trace")
;;
-h|--help)
showUsage
exit 0
;;
--option)
shift
nixBuildArgs+=("--option" "$1" "$2"); shift
;;
*)
if [ -n "$networkExpr" ]; then
echo "Network expression already set!"
showUsage
exit 1
fi
networkExpr="$(readlink -f "$1")"
;;
esac
shift
done
if [ -z "$networkExpr" ]
then
echo "ERROR: A network expression must be specified!" >&2
exit 1
fi
# Build a network of VMs
nix-build '<nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
--argstr networkExpr "$networkExpr" "${nixBuildArgs[@]}"

View file

@ -0,0 +1,109 @@
#! @runtimeShell@
# shellcheck shell=bash
set -e
# Re-exec ourselves in a private mount namespace so that our bind
# mounts get cleaned up automatically.
if [ -z "$NIXOS_ENTER_REEXEC" ]; then
export NIXOS_ENTER_REEXEC=1
if [ "$(id -u)" != 0 ]; then
extraFlags="-r"
fi
exec unshare --fork --mount --uts --mount-proc --pid $extraFlags -- "$0" "$@"
else
mount --make-rprivate /
fi
mountPoint=/mnt
system=/nix/var/nix/profiles/system
command=("$system/sw/bin/bash" "--login")
silent=0
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
case "$i" in
--root)
mountPoint="$1"; shift 1
;;
--system)
system="$1"; shift 1
;;
--help)
exec man nixos-enter
exit 1
;;
--command|-c)
command=("$system/sw/bin/bash" "-c" "$1")
shift 1
;;
--silent)
silent=1
;;
--)
command=("$@")
break
;;
*)
echo "$0: unknown option \`$i'"
exit 1
;;
esac
done
if [[ ! -e $mountPoint/etc/NIXOS ]]; then
echo "$0: '$mountPoint' is not a NixOS installation" >&2
exit 126
fi
mkdir -p "$mountPoint/dev" "$mountPoint/sys"
chmod 0755 "$mountPoint/dev" "$mountPoint/sys"
mount --rbind /dev "$mountPoint/dev"
mount --rbind /sys "$mountPoint/sys"
# modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52
chroot_add_resolv_conf() {
local chrootDir="$1" resolvConf="$1/etc/resolv.conf"
[[ -e /etc/resolv.conf ]] || return 0
# Handle resolv.conf as a symlink to somewhere else.
if [[ -L "$resolvConf" ]]; then
# readlink(1) should always give us *something* since we know at this point
# it's a symlink. For simplicity, ignore the case of nested symlinks.
# We also ignore the possibility of `../`s escaping the root.
resolvConf="$(readlink "$resolvConf")"
if [[ "$resolvConf" = /* ]]; then
resolvConf="$chrootDir$resolvConf"
else
resolvConf="$chrootDir/etc/$resolvConf"
fi
fi
# ensure file exists to bind mount over
if [[ ! -f "$resolvConf" ]]; then
install -Dm644 /dev/null "$resolvConf" || return 1
fi
mount --bind /etc/resolv.conf "$resolvConf"
}
chroot_add_resolv_conf "$mountPoint" || echo "$0: failed to set up resolv.conf" >&2
(
# If silent, write both stdout and stderr of activation script to /dev/null
# otherwise, write both streams to stderr of this process
if [ "$silent" -eq 1 ]; then
exec 2>/dev/null
fi
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" IN_NIXOS_ENTER=1 chroot "$mountPoint" "$system/activate" 1>&2 || true
# Create /tmp
chroot "$mountPoint" systemd-tmpfiles --create --remove --exclude-prefix=/dev 1>&2 || true
)
unset TMPDIR
exec chroot "$mountPoint" "${command[@]}"

View file

@ -0,0 +1,684 @@
#! @perl@
use strict;
use Cwd 'abs_path';
use File::Spec;
use File::Path;
use File::Basename;
use File::Slurp;
use File::stat;
umask(0022);
sub uniq {
my %seen;
my @res = ();
foreach my $s (@_) {
if (!defined $seen{$s}) {
$seen{$s} = 1;
push @res, $s;
}
}
return @res;
}
sub runCommand {
my ($cmd) = @_;
open FILE, "$cmd 2>&1 |" or die "Failed to execute: $cmd\n";
my @ret = <FILE>;
close FILE;
return ($?, @ret);
}
# Process the command line.
my $outDir = "/etc/nixos";
my $rootDir = ""; # = /
my $force = 0;
my $noFilesystems = 0;
my $showHardwareConfig = 0;
for (my $n = 0; $n < scalar @ARGV; $n++) {
my $arg = $ARGV[$n];
if ($arg eq "--help") {
exec "man nixos-generate-config" or die;
}
elsif ($arg eq "--dir") {
$n++;
$outDir = $ARGV[$n];
die "$0: --dir requires an argument\n" unless defined $outDir;
}
elsif ($arg eq "--root") {
$n++;
$rootDir = $ARGV[$n];
die "$0: --root requires an argument\n" unless defined $rootDir;
die "$0: no need to specify `/` with `--root`, it is the default\n" if $rootDir eq "/";
$rootDir =~ s/\/*$//; # remove trailing slashes
$rootDir = File::Spec->rel2abs($rootDir); # resolve absolute path
}
elsif ($arg eq "--force") {
$force = 1;
}
elsif ($arg eq "--no-filesystems") {
$noFilesystems = 1;
}
elsif ($arg eq "--show-hardware-config") {
$showHardwareConfig = 1;
}
else {
die "$0: unrecognized argument $arg\n";
}
}
my @attrs = ();
my @kernelModules = ();
my @initrdKernelModules = ();
my @initrdAvailableKernelModules = ();
my @modulePackages = ();
my @imports;
sub debug {
return unless defined $ENV{"DEBUG"};
print STDERR @_;
}
my $cpuinfo = read_file "/proc/cpuinfo";
sub hasCPUFeature {
my $feature = shift;
return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
}
sub cpuManufacturer {
my $id = shift;
return $cpuinfo =~ /^vendor_id\s*:.* $id$/m;
}
# Determine CPU governor to use
if (-e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors") {
my $governors = read_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors");
# ondemand governor is not available on sandy bridge or later Intel CPUs
my @desired_governors = ("ondemand", "powersave");
my $e;
foreach $e (@desired_governors) {
if (index($governors, $e) != -1) {
last if (push @attrs, "powerManagement.cpuFreqGovernor = lib.mkDefault \"$e\";");
}
}
}
# Virtualization support?
push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
push @attrs, "hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;" if cpuManufacturer "AuthenticAMD";
push @attrs, "hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;" if cpuManufacturer "GenuineIntel";
# Look at the PCI devices and add necessary modules. Note that most
# modules are auto-detected so we don't need to list them here.
# However, some are needed in the initrd to boot the system.
my $videoDriver;
sub pciCheck {
my $path = shift;
my $vendor = read_file "$path/vendor"; chomp $vendor;
my $device = read_file "$path/device"; chomp $device;
my $class = read_file "$path/class"; chomp $class;
my $module;
if (-e "$path/driver/module") {
$module = basename `readlink -f $path/driver/module`;
chomp $module;
}
debug "$path: $vendor $device $class";
debug " $module" if defined $module;
debug "\n";
if (defined $module) {
# See the bottom of http://pciids.sourceforge.net/pci.ids for
# device classes.
if (# Mass-storage controller. Definitely important.
$class =~ /^0x01/ ||
# Firewire controller. A disk might be attached.
$class =~ /^0x0c00/ ||
# USB controller. Needed if we want to use the
# keyboard when things go wrong in the initrd.
$class =~ /^0x0c03/
)
{
push @initrdAvailableKernelModules, $module;
}
}
# broadcom STA driver (wl.ko)
# list taken from http://www.broadcom.com/docs/linux_sta/README.txt
if ($vendor eq "0x14e4" &&
($device eq "0x4311" || $device eq "0x4312" || $device eq "0x4313" ||
$device eq "0x4315" || $device eq "0x4327" || $device eq "0x4328" ||
$device eq "0x4329" || $device eq "0x432a" || $device eq "0x432b" ||
$device eq "0x432c" || $device eq "0x432d" || $device eq "0x4353" ||
$device eq "0x4357" || $device eq "0x4358" || $device eq "0x4359" ||
$device eq "0x4331" || $device eq "0x43a0" || $device eq "0x43b1"
) )
{
push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
push @kernelModules, "wl";
}
# broadcom FullMac driver
# list taken from
# https://wireless.wiki.kernel.org/en/users/Drivers/brcm80211#brcmfmac
if ($vendor eq "0x14e4" &&
($device eq "0x43a3" || $device eq "0x43df" || $device eq "0x43ec" ||
$device eq "0x43d3" || $device eq "0x43d9" || $device eq "0x43e9" ||
$device eq "0x43ba" || $device eq "0x43bb" || $device eq "0x43bc" ||
$device eq "0xaa52" || $device eq "0x43ca" || $device eq "0x43cb" ||
$device eq "0x43cc" || $device eq "0x43c3" || $device eq "0x43c4" ||
$device eq "0x43c5"
) )
{
# we need e.g. brcmfmac43602-pcie.bin
push @imports, "(modulesPath + \"/hardware/network/broadcom-43xx.nix\")";
}
# In case this is a virtio scsi device, we need to explicitly make this available.
if ($vendor eq "0x1af4" && $device eq "0x1004") {
push @initrdAvailableKernelModules, "virtio_scsi";
}
# Can't rely on $module here, since the module may not be loaded
# due to missing firmware. Ideally we would check modules.pcimap
# here.
push @attrs, "networking.enableIntel2200BGFirmware = true;" if
$vendor eq "0x8086" &&
($device eq "0x1043" || $device eq "0x104f" || $device eq "0x4220" ||
$device eq "0x4221" || $device eq "0x4223" || $device eq "0x4224");
push @attrs, "networking.enableIntel3945ABGFirmware = true;" if
$vendor eq "0x8086" &&
($device eq "0x4229" || $device eq "0x4230" ||
$device eq "0x4222" || $device eq "0x4227");
# Assume that all NVIDIA cards are supported by the NVIDIA driver.
# There may be exceptions (e.g. old cards).
# FIXME: do we want to enable an unfree driver here?
#$videoDriver = "nvidia" if $vendor eq "0x10de" && $class =~ /^0x03/;
}
foreach my $path (glob "/sys/bus/pci/devices/*") {
pciCheck $path;
}
# Idem for USB devices.
sub usbCheck {
my $path = shift;
my $class = read_file "$path/bInterfaceClass"; chomp $class;
my $subclass = read_file "$path/bInterfaceSubClass"; chomp $subclass;
my $protocol = read_file "$path/bInterfaceProtocol"; chomp $protocol;
my $module;
if (-e "$path/driver/module") {
$module = basename `readlink -f $path/driver/module`;
chomp $module;
}
debug "$path: $class $subclass $protocol";
debug " $module" if defined $module;
debug "\n";
if (defined $module) {
if (# Mass-storage controller. Definitely important.
$class eq "08" ||
# Keyboard. Needed if we want to use the
# keyboard when things go wrong in the initrd.
($class eq "03" && $protocol eq "01")
)
{
push @initrdAvailableKernelModules, $module;
}
}
}
foreach my $path (glob "/sys/bus/usb/devices/*") {
if (-e "$path/bInterfaceClass") {
usbCheck $path;
}
}
# Add the modules for all block and MMC devices.
foreach my $path (glob "/sys/class/{block,mmc_host}/*") {
my $module;
if (-e "$path/device/driver/module") {
$module = basename `readlink -f $path/device/driver/module`;
chomp $module;
push @initrdAvailableKernelModules, $module;
}
}
# Add bcache module, if needed.
my @bcacheDevices = glob("/dev/bcache*");
if (scalar @bcacheDevices > 0) {
push @initrdAvailableKernelModules, "bcache";
}
# Prevent unbootable systems if LVM snapshots are present at boot time.
if (`lsblk -o TYPE` =~ "lvm") {
push @initrdKernelModules, "dm-snapshot";
}
my $virt = `@detectvirt@`;
chomp $virt;
# Check if we're a VirtualBox guest. If so, enable the guest
# additions.
if ($virt eq "oracle") {
push @attrs, "virtualisation.virtualbox.guest.enable = true;"
}
# Likewise for QEMU.
if ($virt eq "qemu" || $virt eq "kvm" || $virt eq "bochs") {
push @imports, "(modulesPath + \"/profiles/qemu-guest.nix\")";
}
# Also for Hyper-V.
if ($virt eq "microsoft") {
push @attrs, "virtualisation.hypervGuest.enable = true;"
}
# Pull in NixOS configuration for containers.
if ($virt eq "systemd-nspawn") {
push @attrs, "boot.isContainer = true;";
}
# Provide firmware for devices that are not detected by this script,
# unless we're in a VM/container.
push @imports, "(modulesPath + \"/installer/scan/not-detected.nix\")"
if $virt eq "none";
# For a device name like /dev/sda1, find a more stable path like
# /dev/disk/by-uuid/X or /dev/disk/by-label/Y.
sub findStableDevPath {
my ($dev) = @_;
return $dev if substr($dev, 0, 1) ne "/";
return $dev unless -e $dev;
my $st = stat($dev) or return $dev;
foreach my $dev2 (glob("/dev/disk/by-uuid/*"), glob("/dev/mapper/*"), glob("/dev/disk/by-label/*")) {
my $st2 = stat($dev2) or next;
return $dev2 if $st->rdev == $st2->rdev;
}
return $dev;
}
push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];" if $videoDriver;
# Generate the swapDevices option from the currently activated swap
# devices.
my @swaps = read_file("/proc/swaps", err_mode => 'carp');
my @swapDevices;
if (@swaps) {
shift @swaps;
foreach my $swap (@swaps) {
my @fields = split ' ', $swap;
my $swapFilename = $fields[0];
my $swapType = $fields[1];
next unless -e $swapFilename;
my $dev = findStableDevPath $swapFilename;
if ($swapType =~ "partition") {
# zram devices are more likely created by configuration.nix, so
# ignore them here
next if ($swapFilename =~ /^\/dev\/zram/);
push @swapDevices, "{ device = \"$dev\"; }";
} elsif ($swapType =~ "file") {
# swap *files* are more likely specified in configuration.nix, so
# ignore them here.
} else {
die "Unsupported swap type: $swapType\n";
}
}
}
# Generate the fileSystems option from the currently mounted
# filesystems.
sub in {
my ($d1, $d2) = @_;
return $d1 eq $d2 || substr($d1, 0, length($d2) + 1) eq "$d2/";
}
my $fileSystems;
my %fsByDev;
foreach my $fs (read_file("/proc/self/mountinfo")) {
chomp $fs;
my @fields = split / /, $fs;
my $mountPoint = $fields[4];
$mountPoint =~ s/\\040/ /g; # account for mount points with spaces in the name (\040 is the escape character)
$mountPoint =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
next unless -d $mountPoint;
my @mountOptions = split /,/, $fields[5];
next if !in($mountPoint, $rootDir);
$mountPoint = substr($mountPoint, length($rootDir)); # strip the root directory (e.g. /mnt)
$mountPoint = "/" if $mountPoint eq "";
# Skip special filesystems.
next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs";
# Skip the optional fields.
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
my $fsType = $fields[$n];
my $device = $fields[$n + 1];
my @superOptions = split /,/, $fields[$n + 2];
$device =~ s/\\040/ /g; # account for devices with spaces in the name (\040 is the escape character)
$device =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
# Skip the read-only bind-mount on /nix/store.
next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
# Maybe this is a bind-mount of a filesystem we saw earlier?
if (defined $fsByDev{$fields[2]}) {
# Make sure this isn't a btrfs subvolume.
my $msg = `@btrfs@ subvol show $rootDir$mountPoint`;
if ($? != 0 || $msg =~ /ERROR:/s) {
my $path = $fields[3]; $path = "" if $path eq "/";
my $base = $fsByDev{$fields[2]};
$base = "" if $base eq "/";
$fileSystems .= <<EOF;
fileSystems.\"$mountPoint\" =
{ device = \"$base$path\";
fsType = \"none\";
options = \[ \"bind\" \];
};
EOF
next;
}
}
$fsByDev{$fields[2]} = $mountPoint;
# We don't know how to handle FUSE filesystems.
if ($fsType eq "fuseblk" || $fsType eq "fuse") {
print STDERR "warning: don't know how to emit fileSystem option for FUSE filesystem $mountPoint\n";
next;
}
# Is this a mount of a loopback device?
my @extraOptions;
if ($device =~ /\/dev\/loop(\d+)/) {
my $loopnr = $1;
my $backer = read_file "/sys/block/loop$loopnr/loop/backing_file";
if (defined $backer) {
chomp $backer;
$device = $backer;
push @extraOptions, "loop";
}
}
# Is this a btrfs filesystem?
if ($fsType eq "btrfs") {
my ($status, @info) = runCommand("@btrfs@ subvol show $rootDir$mountPoint");
if ($status != 0 || join("", @info) =~ /ERROR:/) {
die "Failed to retrieve subvolume info for $mountPoint\n";
}
my @ids = join("\n", @info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
if ($#ids > 0) {
die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
} elsif ($#ids == 0) {
my @paths = join("", @info) =~ m/^([^\n]*)/;
if ($#paths > 0) {
die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
} elsif ($#paths != 0) {
die "Btrfs did not return a path for the subvolume at $mountPoint\n";
}
push @extraOptions, "subvol=$paths[0]";
}
}
# Don't emit tmpfs entry for /tmp, because it most likely comes from the
# boot.tmpOnTmpfs option in configuration.nix (managed declaratively).
next if ($mountPoint eq "/tmp" && $fsType eq "tmpfs");
# Emit the filesystem.
$fileSystems .= <<EOF;
fileSystems.\"$mountPoint\" =
{ device = \"${\(findStableDevPath $device)}\";
fsType = \"$fsType\";
EOF
if (scalar @extraOptions > 0) {
$fileSystems .= <<EOF;
options = \[ ${\join " ", map { "\"" . $_ . "\"" } uniq(@extraOptions)} \];
EOF
}
$fileSystems .= <<EOF;
};
EOF
# If this filesystem is on a LUKS device, then add a
# boot.initrd.luks.devices entry.
if (-e $device) {
my $deviceName = basename(abs_path($device));
if (-e "/sys/class/block/$deviceName"
&& read_file("/sys/class/block/$deviceName/dm/uuid", err_mode => 'quiet') =~ /^CRYPT-LUKS/)
{
my @slaves = glob("/sys/class/block/$deviceName/slaves/*");
if (scalar @slaves == 1) {
my $slave = "/dev/" . basename($slaves[0]);
if (-e $slave) {
my $dmName = read_file("/sys/class/block/$deviceName/dm/name");
chomp $dmName;
# Ensure to add an entry only once
my $luksDevice = " boot.initrd.luks.devices.\"$dmName\".device";
if ($fileSystems !~ /^\Q$luksDevice\E/m) {
$fileSystems .= "$luksDevice = \"${\(findStableDevPath $slave)}\";\n\n";
}
}
}
}
}
}
# For lack of a better way to determine it, guess whether we should use a
# bigger font for the console from the display mode on the first
# framebuffer. A way based on the physical size/actual DPI reported by
# the monitor would be nice, but I don't know how to do this without X :)
my $fb_modes_file = "/sys/class/graphics/fb0/modes";
if (-f $fb_modes_file && -r $fb_modes_file) {
my $modes = read_file($fb_modes_file);
$modes =~ m/([0-9]+)x([0-9]+)/;
my $console_width = $1, my $console_height = $2;
if ($console_width > 1920) {
push @attrs, "# high-resolution display";
push @attrs, 'hardware.video.hidpi.enable = lib.mkDefault true;';
}
}
# Generate the hardware configuration file.
sub toNixStringList {
my $res = "";
foreach my $s (@_) {
$res .= " \"$s\"";
}
return $res;
}
sub toNixList {
my $res = "";
foreach my $s (@_) {
$res .= " $s";
}
return $res;
}
sub multiLineList {
my $indent = shift;
return " [ ]" if !@_;
my $res = "\n${indent}[ ";
my $first = 1;
foreach my $s (@_) {
$res .= "$indent " if !$first;
$first = 0;
$res .= "$s\n";
}
$res .= "$indent]";
return $res;
}
my $initrdAvailableKernelModules = toNixStringList(uniq @initrdAvailableKernelModules);
my $initrdKernelModules = toNixStringList(uniq @initrdKernelModules);
my $kernelModules = toNixStringList(uniq @kernelModules);
my $modulePackages = toNixList(uniq @modulePackages);
my $fsAndSwap = "";
if (!$noFilesystems) {
$fsAndSwap = "\n$fileSystems ";
$fsAndSwap .= "swapDevices =" . multiLineList(" ", @swapDevices) . ";\n";
}
my $networkingDhcpConfig = generateNetworkingDhcpConfig();
my $hwConfig = <<EOF;
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =${\multiLineList(" ", @imports)};
boot.initrd.availableKernelModules = [$initrdAvailableKernelModules ];
boot.initrd.kernelModules = [$initrdKernelModules ];
boot.kernelModules = [$kernelModules ];
boot.extraModulePackages = [$modulePackages ];
$fsAndSwap
$networkingDhcpConfig
${\join "", (map { " $_\n" } (uniq @attrs))}}
EOF
sub generateNetworkingDhcpConfig {
# FIXME disable networking.useDHCP by default when switching to networkd.
my $config = <<EOF;
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
EOF
foreach my $path (glob "/sys/class/net/*") {
my $dev = basename($path);
if ($dev ne "lo") {
$config .= " # networking.interfaces.$dev.useDHCP = lib.mkDefault true;\n";
}
}
return $config;
}
sub generateXserverConfig {
my $xserverEnabled = "@xserverEnabled@";
my $config = "";
if ($xserverEnabled eq "1") {
$config = <<EOF;
# Enable the X11 windowing system.
services.xserver.enable = true;
EOF
} else {
$config = <<EOF;
# Enable the X11 windowing system.
# services.xserver.enable = true;
EOF
}
}
if ($showHardwareConfig) {
print STDOUT $hwConfig;
} else {
if ($outDir eq "/etc/nixos") {
$outDir = "$rootDir$outDir";
} else {
$outDir = File::Spec->rel2abs($outDir);
$outDir =~ s/\/*$//; # remove trailing slashes
}
my $fn = "$outDir/hardware-configuration.nix";
print STDERR "writing $fn...\n";
mkpath($outDir, 0, 0755);
write_file($fn, $hwConfig);
# Generate a basic configuration.nix, unless one already exists.
$fn = "$outDir/configuration.nix";
if ($force || ! -e $fn) {
print STDERR "writing $fn...\n";
my $bootLoaderConfig = "";
if (-e "/sys/firmware/efi/efivars") {
$bootLoaderConfig = <<EOF;
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
EOF
} elsif (-e "/boot/extlinux") {
$bootLoaderConfig = <<EOF;
# Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
boot.loader.grub.enable = false;
# Enables the generation of /boot/extlinux/extlinux.conf
boot.loader.generic-extlinux-compatible.enable = true;
EOF
} elsif ($virt ne "systemd-nspawn") {
$bootLoaderConfig = <<EOF;
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# boot.loader.grub.efiSupport = true;
# boot.loader.grub.efiInstallAsRemovable = true;
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
# Define on which hard drive you want to install Grub.
# boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
EOF
}
my $networkingDhcpConfig = generateNetworkingDhcpConfig();
my $xserverConfig = generateXserverConfig();
(my $desktopConfiguration = <<EOF)=~s/^/ /gm;
@desktopConfiguration@
EOF
write_file($fn, <<EOF);
@configuration@
EOF
print STDERR "For more hardware-specific settings, see https://github.com/NixOS/nixos-hardware.\n"
} else {
print STDERR "warning: not overwriting existing $fn\n";
}
}
# workaround for a bug in substituteAll

View file

@ -0,0 +1,218 @@
#! @runtimeShell@
# shellcheck shell=bash
set -e
shopt -s nullglob
export PATH=@path@:$PATH
# Ensure a consistent umask.
umask 0022
# Parse the command line for the -I flag
extraBuildFlags=()
flakeFlags=()
mountPoint=/mnt
channelPath=
system=
verbosity=()
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
case "$i" in
--max-jobs|-j|--cores|-I|--substituters)
j="$1"; shift 1
extraBuildFlags+=("$i" "$j")
;;
--option)
j="$1"; shift 1
k="$1"; shift 1
extraBuildFlags+=("$i" "$j" "$k")
;;
--root)
mountPoint="$1"; shift 1
;;
--system|--closure)
system="$1"; shift 1
;;
--flake)
flake="$1"
flakeFlags=(--experimental-features 'nix-command flakes')
shift 1
;;
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
lockFlags+=("$i")
;;
--update-input)
j="$1"; shift 1
lockFlags+=("$i" "$j")
;;
--override-input)
j="$1"; shift 1
k="$1"; shift 1
lockFlags+=("$i" "$j" "$k")
;;
--channel)
channelPath="$1"; shift 1
;;
--no-channel-copy)
noChannelCopy=1
;;
--no-root-password|--no-root-passwd)
noRootPasswd=1
;;
--no-bootloader)
noBootLoader=1
;;
--show-trace|--impure|--keep-going)
extraBuildFlags+=("$i")
;;
--help)
exec man nixos-install
exit 1
;;
--debug)
set -x
;;
-v*|--verbose)
verbosity+=("$i")
;;
*)
echo "$0: unknown option \`$i'"
exit 1
;;
esac
done
if ! test -e "$mountPoint"; then
echo "mount point $mountPoint doesn't exist"
exit 1
fi
# Verify permissions are okay-enough
checkPath="$(realpath "$mountPoint")"
while [[ "$checkPath" != "/" ]]; do
mode="$(stat -c '%a' "$checkPath")"
if [[ "${mode: -1}" -lt "5" ]]; then
echo "path $checkPath should have permissions 755, but had permissions $mode. Consider running 'chmod o+rx $checkPath'."
exit 1
fi
checkPath="$(dirname "$checkPath")"
done
# Get the path of the NixOS configuration file.
if [[ -z $NIXOS_CONFIG ]]; then
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
fi
if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
echo "$0: \$NIXOS_CONFIG is not an absolute path"
exit 1
fi
if [[ -n $flake ]]; then
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
flake="${BASH_REMATCH[1]}"
flakeAttr="${BASH_REMATCH[2]}"
fi
if [[ -z "$flakeAttr" ]]; then
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri."
echo "For example, to use the output nixosConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri."
exit 1
fi
flakeAttr="nixosConfigurations.\"$flakeAttr\""
fi
# Resolve the flake.
if [[ -n $flake ]]; then
flake=$(nix "${flakeFlags[@]}" flake metadata --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
fi
if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then
echo "configuration file $NIXOS_CONFIG doesn't exist"
exit 1
fi
# A place to drop temporary stuff.
tmpdir="$(mktemp -d -p "$mountPoint")"
trap 'rm -rf $tmpdir' EXIT
# store temporary files on target filesystem by default
export TMPDIR=${TMPDIR:-$tmpdir}
sub="auto?trusted=1"
# Copy the NixOS/Nixpkgs sources to the target as the initial contents
# of the NixOS channel.
if [[ -z $noChannelCopy ]]; then
if [[ -z $channelPath ]]; then
channelPath="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
fi
if [[ -n $channelPath ]]; then
echo "copying channel..."
mkdir -p "$mountPoint"/nix/var/nix/profiles/per-user/root
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" --extra-substituters "$sub" \
-p "$mountPoint"/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet \
"${verbosity[@]}"
install -m 0700 -d "$mountPoint"/root/.nix-defexpr
ln -sfn /nix/var/nix/profiles/per-user/root/channels "$mountPoint"/root/.nix-defexpr/channels
fi
fi
# Build the system configuration in the target filesystem.
if [[ -z $system ]]; then
outLink="$tmpdir/system"
if [[ -z $flake ]]; then
echo "building the configuration in $NIXOS_CONFIG..."
nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
--extra-substituters "$sub" \
'<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}"
else
echo "building the flake in $flake..."
nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
--store "$mountPoint" --extra-substituters "$sub" "${verbosity[@]}" \
"${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link "$outLink"
fi
system=$(readlink -f "$outLink")
fi
# Set the system profile to point to the configuration. TODO: combine
# this with the previous step once we have a nix-env replacement with
# a progress bar.
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" \
--extra-substituters "$sub" \
-p "$mountPoint"/nix/var/nix/profiles/system --set "$system" "${verbosity[@]}"
# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
mkdir -m 0755 -p "$mountPoint/etc"
touch "$mountPoint/etc/NIXOS"
# Switch to the new system configuration. This will install Grub with
# a menu default pointing at the kernel/initrd/etc of the new
# configuration.
if [[ -z $noBootLoader ]]; then
echo "installing the boot loader..."
# Grub needs an mtab.
ln -sfn /proc/mounts "$mountPoint"/etc/mtab
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$mountPoint" -- /run/current-system/bin/switch-to-configuration boot
fi
# Ask the user to set a root password, but only if the passwd command
# exists (i.e. when mutable user accounts are enabled).
if [[ -z $noRootPasswd ]] && [ -t 0 ]; then
if nixos-enter --root "$mountPoint" -c 'test -e /nix/var/nix/profiles/system/sw/bin/passwd'; then
set +e
nixos-enter --root "$mountPoint" -c 'echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd'
exit_code=$?
set -e
if [[ $exit_code != 0 ]]; then
echo "Setting a root password failed with the above printed error."
echo "You can set the root password manually by executing \`nixos-enter --root ${mountPoint@Q}\` and then running \`passwd\` in the shell of the new system."
exit $exit_code
fi
fi
fi
echo "installation finished!"

View file

@ -0,0 +1 @@
{ pkgs, ... }: pkgs.nixos-option

View file

@ -0,0 +1,24 @@
#! @runtimeShell@
# shellcheck shell=bash
case "$1" in
-h|--help)
exec man nixos-version
exit 1
;;
--hash|--revision)
if ! [[ @revision@ =~ ^[0-9a-f]+$ ]]; then
echo "$0: Nixpkgs commit hash is unknown"
exit 1
fi
echo "@revision@"
;;
--json)
cat <<EOF
@json@
EOF
;;
*)
echo "@version@ (@codeName@)"
;;
esac

View file

@ -0,0 +1,243 @@
# This module generates nixos-install, nixos-rebuild,
# nixos-generate-config, etc.
{ config, lib, pkgs, ... }:
with lib;
let
makeProg = args: pkgs.substituteAll (args // {
dir = "bin";
isExecutable = true;
});
nixos-build-vms = makeProg {
name = "nixos-build-vms";
src = ./nixos-build-vms/nixos-build-vms.sh;
inherit (pkgs) runtimeShell;
};
nixos-install = makeProg {
name = "nixos-install";
src = ./nixos-install.sh;
inherit (pkgs) runtimeShell;
nix = config.nix.package.out;
path = makeBinPath [
pkgs.jq
nixos-enter
];
};
nixos-rebuild = pkgs.nixos-rebuild.override { nix = config.nix.package.out; };
nixos-generate-config = makeProg {
name = "nixos-generate-config";
src = ./nixos-generate-config.pl;
perl = "${pkgs.perl.withPackages (p: [ p.FileSlurp ])}/bin/perl";
detectvirt = "${config.systemd.package}/bin/systemd-detect-virt";
btrfs = "${pkgs.btrfs-progs}/bin/btrfs";
inherit (config.system.nixos-generate-config) configuration desktopConfiguration;
xserverEnabled = config.services.xserver.enable;
};
nixos-option =
if lib.versionAtLeast (lib.getVersion config.nix.package) "2.4pre"
then null
else pkgs.nixos-option;
nixos-version = makeProg {
name = "nixos-version";
src = ./nixos-version.sh;
inherit (pkgs) runtimeShell;
inherit (config.system.nixos) version codeName revision;
inherit (config.system) configurationRevision;
json = builtins.toJSON ({
nixosVersion = config.system.nixos.version;
} // optionalAttrs (config.system.nixos.revision != null) {
nixpkgsRevision = config.system.nixos.revision;
} // optionalAttrs (config.system.configurationRevision != null) {
configurationRevision = config.system.configurationRevision;
});
};
nixos-enter = makeProg {
name = "nixos-enter";
src = ./nixos-enter.sh;
inherit (pkgs) runtimeShell;
};
in
{
options.system.nixos-generate-config = {
configuration = mkOption {
internal = true;
type = types.str;
description = ''
The NixOS module that <literal>nixos-generate-config</literal>
saves to <literal>/etc/nixos/configuration.nix</literal>.
This is an internal option. No backward compatibility is guaranteed.
Use at your own risk!
Note that this string gets spliced into a Perl script. The perl
variable <literal>$bootLoaderConfig</literal> can be used to
splice in the boot loader configuration.
'';
};
desktopConfiguration = mkOption {
internal = true;
type = types.listOf types.lines;
default = [];
description = ''
Text to preseed the desktop configuration that <literal>nixos-generate-config</literal>
saves to <literal>/etc/nixos/configuration.nix</literal>.
This is an internal option. No backward compatibility is guaranteed.
Use at your own risk!
Note that this string gets spliced into a Perl script. The perl
variable <literal>$bootLoaderConfig</literal> can be used to
splice in the boot loader configuration.
'';
};
};
options.system.disableInstallerTools = mkOption {
internal = true;
type = types.bool;
default = false;
description = ''
Disable nixos-rebuild, nixos-generate-config, nixos-installer
and other NixOS tools. This is useful to shrink embedded,
read-only systems which are not expected to be rebuild or
reconfigure themselves. Use at your own risk!
'';
};
config = lib.mkIf (config.nix.enable && !config.system.disableInstallerTools) {
system.nixos-generate-config.configuration = mkDefault ''
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
$bootLoaderConfig
# networking.hostName = "nixos"; # Define your hostname.
# Pick only one of the below networking options.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password\@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
# i18n.defaultLocale = "en_US.UTF-8";
# console = {
# font = "Lat2-Terminus16";
# keyMap = "us";
# useXkbConfig = true; # use xkbOptions in tty.
# };
$xserverConfig
$desktopConfiguration
# Configure keymap in X11
# services.xserver.layout = "us";
# services.xserver.xkbOptions = {
# "eurosign:e";
# "caps:escape" # map caps to escape.
# };
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
# hardware.pulseaudio.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
# users.users.jane = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable sudo for the user.
# packages = with pkgs; [
# firefox
# thunderbird
# ];
# };
# List packages installed in system profile. To search, run:
# \$ nix search wget
# environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
# wget
# ];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "${config.system.nixos.release}"; # Did you read the comment?
}
'';
environment.systemPackages =
[ nixos-build-vms
nixos-install
nixos-rebuild
nixos-generate-config
nixos-version
nixos-enter
] ++ lib.optional (nixos-option != null) nixos-option;
system.build = {
inherit nixos-install nixos-generate-config nixos-option nixos-rebuild nixos-enter;
};
};
}

View file

@ -0,0 +1,61 @@
{ lib, ... }:
with lib;
{
imports =
[ ../virtualisation/virtualbox-image.nix
../installer/cd-dvd/channel.nix
../profiles/demo.nix
../profiles/clone-config.nix
];
# FIXME: UUID detection is currently broken
boot.loader.grub.fsIdentifier = "provided";
# Allow mounting of shared folders.
users.users.demo.extraGroups = [ "vboxsf" ];
# Add some more video drivers to give X11 a shot at working in
# VMware and QEMU.
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
powerManagement.enable = false;
system.stateVersion = mkDefault "18.03";
installer.cloneConfigExtra = ''
# Let demo build as a trusted user.
# nix.settings.trusted-users = [ "demo" ];
# Mount a VirtualBox shared folder.
# This is configurable in the VirtualBox menu at
# Machine / Settings / Shared Folders.
# fileSystems."/mnt" = {
# fsType = "vboxsf";
# device = "nameofdevicetomount";
# options = [ "rw" ];
# };
# By default, the NixOS VirtualBox demo image includes SDDM and Plasma.
# If you prefer another desktop manager or display manager, you may want
# to disable the default.
# services.xserver.desktopManager.plasma5.enable = lib.mkForce false;
# services.xserver.displayManager.sddm.enable = lib.mkForce false;
# Enable GDM/GNOME by uncommenting above two lines and two lines below.
# services.xserver.displayManager.gdm.enable = true;
# services.xserver.desktopManager.gnome.enable = true;
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# List packages installed in system profile. To search, run:
# \$ nix search wget
# environment.systemPackages = with pkgs; [
# wget vim
# ];
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
'';
}