migrate the nix install to an external USB drive.
this requires a patch to uboot: - uboot thinks the drive has a capacity of 0 (i.e. 'unknown'). unclear precisely why. could be noncompliant drive firmware, or a timeout somewhere. and a patch to the rpi bootloader: - in order to trampoline into the rpi-4 uboot. and custom kernel modules in the initrd: - in order to detect the USB hub (rpi fw). additionally, i'm MANUALLY placing `bcm2711-rpi-400.dtb` into `/boot/nixos/..-linux-5.10.111-dtbs/broadcom`. i'll want to do this automatically over time. i hope to simplify much of this over time: this is just the first thing which works after a couple days of hacking at it.
This commit is contained in:
parent
aeb8319154
commit
1064867194
46
cfg/fs.nix
46
cfg/fs.nix
|
@ -1,27 +1,57 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
|
||||
fsType = "ext4";
|
||||
};
|
||||
# fileSystems."/" = {
|
||||
# device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
fileSystems."/mnt/storage" = {
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/2be70d38-79f4-41b6-bee2-bce5a25f8f7b";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/boot" = {
|
||||
# this is the /dev/sda1 boot device.
|
||||
# by mounting this in boot, we can then run `nixos-rebuild` and it'll only take affect when booting from sda1
|
||||
# (old mmc1 boot will be preserved)
|
||||
device = "/dev/disk/by-uuid/B318-A67E";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
# fileSystems."/mnt/storage" = {
|
||||
# device = "/dev/disk/by-uuid/2be70d38-79f4-41b6-bee2-bce5a25f8f7b";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
# temporary; nix porting
|
||||
# fileSystems."/home/colin" = {
|
||||
# device = "/mnt/storage/home/colin";
|
||||
# options = [ "bind" ];
|
||||
# };
|
||||
# fileSystems."/boot" = {
|
||||
# device = "/mnt/storage/boot";
|
||||
# options = [ "bind" ];
|
||||
# };
|
||||
# fileSystems."/var/spool" = {
|
||||
# device = "/mnt/storage/var/spool";
|
||||
# options = [ "bind" ];
|
||||
# };
|
||||
# fileSystems."/var/lib" = {
|
||||
# device = "/mnt/storage/var/lib";
|
||||
# options = [ "bind" ];
|
||||
# };
|
||||
|
||||
fileSystems."/var/lib/pleroma" = {
|
||||
device = "/mnt/storage/opt/pleroma.nix";
|
||||
device = "/opt/pleroma";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
|
||||
fileSystems."/var/lib/transmission/Downloads" = {
|
||||
device = "/mnt/storage/opt/uninsane/media";
|
||||
device = "/opt/uninsane/media";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
fileSystems."/var/lib/transmission/.incomplete" = {
|
||||
device = "/mnt/storage/opt/uninsane/media/incomplete";
|
||||
device = "/opt/uninsane/media/incomplete";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
{
|
||||
networking.domain = "uninsane.org";
|
||||
|
||||
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
|
||||
# Per-interface useDHCP will be mandatory in the future, so this generated config
|
||||
# replicates the default behaviour.
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces.eth0.useDHCP = true;
|
||||
# TODO: how to disable entirely?
|
||||
networking.interfaces.wlan0.useDHCP = false;
|
||||
|
||||
# networking.firewall.enable = false;
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
# web-created keys are allowed to delete files, which you probably don't want for an incremental backup program
|
||||
services.duplicity.targetUrl = builtins.replaceStrings ["\n"] [""] (builtins.readFile /etc/nixos/secrets/duplicity_url);
|
||||
# format: PASSPHRASE=<cleartext>
|
||||
# two sisters
|
||||
services.duplicity.secretFile = /etc/nixos/secrets/duplicity_env;
|
||||
# NB: manually trigger with `systemctl start duplicity`
|
||||
services.duplicity.frequency = "daily";
|
||||
|
@ -24,7 +25,7 @@
|
|||
"/var/lib/transmission/Downloads"
|
||||
"/var/lib/transmission/.incomplete"
|
||||
# data that's not worth the cost to backup:
|
||||
"/mnt/storage/opt/uninsane/media"
|
||||
"/opt/uninsane/media"
|
||||
];
|
||||
|
||||
# set this for the FIRST backup, then remove it to enable incremental backups
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
# IRC bridging
|
||||
# note: Rizon allows only FOUR simultaneous IRC connections per IP: https://wiki.rizon.net/index.php?title=Connection/Session_Limit_Exemptions
|
||||
# Rizon supports CertFP for auth: https://wiki.rizon.net/index.php?title=CertFP
|
||||
services.matrix-appservice-irc.enable = true;
|
||||
# services.matrix-appservice-irc.enable = true;
|
||||
services.matrix-appservice-irc.registrationUrl = "http://127.0.0.1:8009";
|
||||
# settings documented here: https://github.com/matrix-org/matrix-appservice-irc/blob/develop/config.sample.yaml
|
||||
services.matrix-appservice-irc.settings = {
|
||||
|
@ -136,15 +136,15 @@
|
|||
};
|
||||
|
||||
# hardcoded mappings, for when dynamicChannels fails us. TODO: probably safe to remove these.
|
||||
mappings = {
|
||||
"#chat" = {
|
||||
roomIds = [ "!GXJSOTdbtxRboGtDep:uninsane.org" ];
|
||||
};
|
||||
# BakaBT requires account registration, which i think means my user needs to be added before the appservice user
|
||||
"#BakaBT" = {
|
||||
roomIds = [ "!feZKttuYuHilqPFSkD:uninsane.org" ];
|
||||
};
|
||||
};
|
||||
# mappings = {
|
||||
# "#chat" = {
|
||||
# roomIds = [ "!GXJSOTdbtxRboGtDep:uninsane.org" ];
|
||||
# };
|
||||
# # BakaBT requires account registration, which i think means my user needs to be added before the appservice user
|
||||
# "#BakaBT" = {
|
||||
# roomIds = [ "!feZKttuYuHilqPFSkD:uninsane.org" ];
|
||||
# };
|
||||
# };
|
||||
# for per-user IRC password:
|
||||
# invite @irc_rizon_NickServ:uninsane.org to a DM and type `help` => register
|
||||
# invite the matrix-appservice-irc user to a DM and type `!help` => add PW to database
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
# web blog/personal site
|
||||
services.nginx.virtualHosts."uninsane.org" = {
|
||||
root = "/mnt/storage/opt/uninsane/root";
|
||||
root = "/opt/uninsane/root";
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{
|
||||
services.postgresql.enable = true;
|
||||
services.postgresql.dataDir = "/mnt/storage/opt/postgresql/13";
|
||||
services.postgresql.dataDir = "/opt/postgresql/13";
|
||||
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
|
||||
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
rpc-password = "{503fc8928344f495efb8e1f955111ca5c862ce0656SzQnQ5";
|
||||
rpc-whitelist-enabled = false;
|
||||
|
||||
# download-dir = "/mnt/storage/opt/uninsane/media/";
|
||||
# download-dir = "/opt/uninsane/media/";
|
||||
|
||||
# force peer connections to be encrypted
|
||||
encryption = 2;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
pkgs.fd
|
||||
pkgs.file
|
||||
pkgs.git
|
||||
pkgs.gptfdisk
|
||||
pkgs.htop
|
||||
pkgs.iftop
|
||||
pkgs.iotop
|
||||
|
@ -39,6 +40,8 @@
|
|||
pkgs.netcat
|
||||
pkgs.nettools
|
||||
pkgs.nmap
|
||||
pkgs.parted
|
||||
pkgs.python3
|
||||
pkgs.ripgrep
|
||||
pkgs.socat
|
||||
pkgs.sudo
|
||||
|
@ -71,8 +74,9 @@
|
|||
];
|
||||
};
|
||||
|
||||
# Automatically log in at the virtual consoles.
|
||||
services.getty.autologinUser = "colin";
|
||||
# automatically log in at the virtual consoles.
|
||||
# using root here makes sure we always have an escape hatch
|
||||
services.getty.autologinUser = "root";
|
||||
|
||||
security.sudo = {
|
||||
enable = true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# your system. Help is available in the configuration.nix(5) man page
|
||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
{ config, lib, modulesPath, pkgs, specialArgs, options }:
|
||||
|
||||
let
|
||||
pkgsUnstable = import (builtins.fetchTarball {
|
||||
|
@ -16,7 +16,10 @@ let
|
|||
}) {};
|
||||
in
|
||||
{
|
||||
imports = [ ./cfg ];
|
||||
imports = [
|
||||
./cfg
|
||||
./modules
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
|
@ -31,92 +34,55 @@ in
|
|||
# https://github.com/go-gitea/gitea/pull/19119
|
||||
# safe to remove after 1.16.5 (or 1.16.7 if we need db compat?)
|
||||
gitea = pkgsUnstable.gitea;
|
||||
|
||||
# try a newer rpi4 u-boot
|
||||
# ubootRaspberryPi4_64bit = pkgsUnstable.ubootRaspberryPi4_64bit;
|
||||
ubootRaspberryPi4_64bit = self.callPackage ./pkgs/ubootRaspberryPi4_64bit { pkgs = super; };
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
# XXX colin: UNMODIFIED DEFAULTS BELOW
|
||||
|
||||
# Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
|
||||
# NixOS defaults to grub: we don't want that.
|
||||
boot.loader.grub.enable = false;
|
||||
# Enables the generation of /boot/extlinux/extlinux.conf
|
||||
boot.loader.generic-extlinux-compatible.enable = true;
|
||||
boot.loader.raspberryPiColin.enable = true;
|
||||
boot.loader.raspberryPiColin.uboot.enable = true;
|
||||
boot.loader.raspberryPiColin.version = 4;
|
||||
|
||||
# networking.hostName = "nixos"; # Define your hostname.
|
||||
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||
|
||||
# Set your time zone.
|
||||
# time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
|
||||
# Per-interface useDHCP will be mandatory in the future, so this generated config
|
||||
# replicates the default behaviour.
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces.eth0.useDHCP = true;
|
||||
networking.interfaces.wlan0.useDHCP = true;
|
||||
|
||||
# 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";
|
||||
# };
|
||||
|
||||
# Enable the X11 windowing system.
|
||||
# services.xserver.enable = true;
|
||||
|
||||
|
||||
|
||||
# Configure keymap in X11
|
||||
# services.xserver.layout = "us";
|
||||
# services.xserver.xkbOptions = "eurosign:e";
|
||||
|
||||
# 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.
|
||||
# };
|
||||
|
||||
# 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
|
||||
# firefox
|
||||
boot.initrd.availableKernelModules = [
|
||||
"bcm2711_thermal"
|
||||
"bcm_phy_lib"
|
||||
"brcmfmac"
|
||||
"brcmutil"
|
||||
"broadcom"
|
||||
"clk_raspberrypi"
|
||||
"drm" # Direct Render Manager
|
||||
"enclosure" # SCSI ?
|
||||
"fuse"
|
||||
"mdio_bcm_unimac"
|
||||
"pcie_brcmstb"
|
||||
"raspberrypi_cpufreq"
|
||||
"raspberrypi_hwmon"
|
||||
"ses" # SCSI Enclosure Services
|
||||
"uas" # USB attached storage
|
||||
"uio" # userspace IO
|
||||
"uio_pdrv_genirq"
|
||||
"xhci_pci"
|
||||
"xhci_pci_renesas"
|
||||
];
|
||||
boot.initrd.compressor = "gzip"; # defaults to zstd
|
||||
# hack in the `boot.shell_on_fail` arg since it doesn't seem to work otherwise
|
||||
boot.initrd.preFailCommands = "allowShell=1";
|
||||
# default: 4 (warn). 7 is debug
|
||||
# boot.consoleLogLevel = 7;
|
||||
# boot.kernelParams = [
|
||||
# "boot.shell_on_fail"
|
||||
# # "boot.trace"
|
||||
# # "systemd.log_level=debug"
|
||||
# # "systemd.log_target=console"
|
||||
# ];
|
||||
|
||||
# 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;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./system ];
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./loader ];
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./raspberrypi/raspberrypi.nix ];
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{ pkgs }:
|
||||
|
||||
pkgs.substituteAll {
|
||||
src = ./extlinux-conf-builder.sh;
|
||||
isExecutable = true;
|
||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||
inherit (pkgs) bash;
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
#! @bash@/bin/sh -e
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
export PATH=/empty
|
||||
for i in @path@; do PATH=$PATH:$i/bin; done
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>] [-n <dtbName>] [-r]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
timeout= # Timeout in centiseconds
|
||||
default= # Default configuration
|
||||
target=/boot # Target directory
|
||||
numGenerations=0 # Number of other generations to include in the menu
|
||||
|
||||
while getopts "t:c:d:g:n:r" opt; do
|
||||
case "$opt" in
|
||||
t) # U-Boot interprets '0' as infinite and negative as instant boot
|
||||
if [ "$OPTARG" -lt 0 ]; then
|
||||
timeout=0
|
||||
elif [ "$OPTARG" = 0 ]; then
|
||||
timeout=-10
|
||||
else
|
||||
timeout=$((OPTARG * 10))
|
||||
fi
|
||||
;;
|
||||
c) default="$OPTARG" ;;
|
||||
d) target="$OPTARG" ;;
|
||||
g) numGenerations="$OPTARG" ;;
|
||||
n) dtbName="$OPTARG" ;;
|
||||
r) noDeviceTree=1 ;;
|
||||
\?) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$timeout" = "" -o "$default" = "" ] && usage
|
||||
|
||||
mkdir -p $target/nixos
|
||||
mkdir -p $target/extlinux
|
||||
|
||||
# Convert a path to a file in the Nix store such as
|
||||
# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
|
||||
cleanName() {
|
||||
local path="$1"
|
||||
echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
|
||||
}
|
||||
|
||||
# Copy a file from the Nix store to $target/nixos.
|
||||
declare -A filesCopied
|
||||
|
||||
copyToKernelsDir() {
|
||||
local src=$(readlink -f "$1")
|
||||
local dst="$target/nixos/$(cleanName $src)"
|
||||
# Don't copy the file if $dst already exists. This means that we
|
||||
# have to create $dst atomically to prevent partially copied
|
||||
# kernels or initrd if this script is ever interrupted.
|
||||
if ! test -e $dst; then
|
||||
local dstTmp=$dst.tmp.$$
|
||||
cp -r $src $dstTmp
|
||||
mv $dstTmp $dst
|
||||
fi
|
||||
filesCopied[$dst]=1
|
||||
result=$dst
|
||||
}
|
||||
|
||||
# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an
|
||||
# extlinux menu entry
|
||||
addEntry() {
|
||||
local path=$(readlink -f "$1")
|
||||
local tag="$2" # Generation number or 'default'
|
||||
|
||||
if ! test -e $path/kernel -a -e $path/initrd; then
|
||||
return
|
||||
fi
|
||||
|
||||
copyToKernelsDir "$path/kernel"; kernel=$result
|
||||
copyToKernelsDir "$path/initrd"; initrd=$result
|
||||
dtbDir=$(readlink -m "$path/dtbs")
|
||||
if [ -e "$dtbDir" ]; then
|
||||
copyToKernelsDir "$dtbDir"; dtbs=$result
|
||||
fi
|
||||
|
||||
timestampEpoch=$(stat -L -c '%Z' $path)
|
||||
|
||||
timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch)
|
||||
nixosLabel="$(cat $path/nixos-version)"
|
||||
extraParams="$(cat $path/kernel-params)"
|
||||
|
||||
echo
|
||||
echo "LABEL nixos-$tag"
|
||||
if [ "$tag" = "default" ]; then
|
||||
echo " MENU LABEL NixOS - Default"
|
||||
else
|
||||
echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosLabel)"
|
||||
fi
|
||||
echo " LINUX ../nixos/$(basename $kernel)"
|
||||
echo " INITRD ../nixos/$(basename $initrd)"
|
||||
echo " APPEND init=$path/init $extraParams"
|
||||
|
||||
if [ -n "$noDeviceTree" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -d "$dtbDir" ]; then
|
||||
# if a dtbName was specified explicitly, use that, else use FDTDIR
|
||||
if [ -n "$dtbName" ]; then
|
||||
echo " FDT ../nixos/$(basename $dtbs)/${dtbName}"
|
||||
else
|
||||
echo " FDTDIR ../nixos/$(basename $dtbs)"
|
||||
fi
|
||||
else
|
||||
if [ -n "$dtbName" ]; then
|
||||
echo "Explicitly requested dtbName $dtbName, but there's no FDTDIR - bailing out." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
tmpFile="$target/extlinux/extlinux.conf.tmp.$$"
|
||||
|
||||
cat > $tmpFile <<EOF
|
||||
# Generated file, all changes will be lost on nixos-rebuild!
|
||||
|
||||
# Change this to e.g. nixos-42 to temporarily boot to an older configuration.
|
||||
DEFAULT nixos-default
|
||||
|
||||
MENU TITLE ------------------------------------------------------------
|
||||
TIMEOUT $timeout
|
||||
EOF
|
||||
|
||||
addEntry $default default >> $tmpFile
|
||||
|
||||
if [ "$numGenerations" -gt 0 ]; then
|
||||
# Add up to $numGenerations generations of the system profile to the menu,
|
||||
# in reverse (most recent to least recent) order.
|
||||
for generation in $(
|
||||
(cd /nix/var/nix/profiles && ls -d system-*-link) \
|
||||
| sed 's/system-\([0-9]\+\)-link/\1/' \
|
||||
| sort -n -r \
|
||||
| head -n $numGenerations); do
|
||||
link=/nix/var/nix/profiles/system-$generation-link
|
||||
addEntry $link $generation
|
||||
done >> $tmpFile
|
||||
fi
|
||||
|
||||
mv -f $tmpFile $target/extlinux/extlinux.conf
|
||||
|
||||
# Remove obsolete files from $target/nixos.
|
||||
for fn in $target/nixos/*; do
|
||||
if ! test "${filesCopied[$fn]}" = 1; then
|
||||
echo "Removing no longer needed boot file: $fn"
|
||||
chmod +w -- "$fn"
|
||||
rm -rf -- "$fn"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,9 @@
|
|||
{ pkgs, configTxt, firmware ? pkgs.raspberrypifw }:
|
||||
|
||||
pkgs.substituteAll {
|
||||
src = ./raspberrypi-builder.sh;
|
||||
isExecutable = true;
|
||||
inherit (pkgs) bash;
|
||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||
inherit firmware configTxt;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
#! @bash@/bin/sh
|
||||
|
||||
# This can end up being called disregarding the shebang.
|
||||
set -e
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
export PATH=/empty
|
||||
for i in @path@; do PATH=$PATH:$i/bin; done
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 -c <path-to-default-configuration> [-d <boot-dir>]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
default= # Default configuration
|
||||
target=/boot # Target directory
|
||||
|
||||
while getopts "c:d:" opt; do
|
||||
case "$opt" in
|
||||
c) default="$OPTARG" ;;
|
||||
d) target="$OPTARG" ;;
|
||||
\?) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "updating the boot generations directory..."
|
||||
|
||||
mkdir -p $target/old
|
||||
|
||||
# Convert a path to a file in the Nix store such as
|
||||
# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
|
||||
cleanName() {
|
||||
local path="$1"
|
||||
echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
|
||||
}
|
||||
|
||||
# Copy a file from the Nix store to $target/kernels.
|
||||
declare -A filesCopied
|
||||
|
||||
copyToKernelsDir() {
|
||||
local src="$1"
|
||||
local dst="$target/old/$(cleanName $src)"
|
||||
# Don't copy the file if $dst already exists. This means that we
|
||||
# have to create $dst atomically to prevent partially copied
|
||||
# kernels or initrd if this script is ever interrupted.
|
||||
if ! test -e $dst; then
|
||||
local dstTmp=$dst.tmp.$$
|
||||
cp $src $dstTmp
|
||||
mv $dstTmp $dst
|
||||
fi
|
||||
filesCopied[$dst]=1
|
||||
result=$dst
|
||||
}
|
||||
|
||||
copyForced() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
cp $src $dst.tmp
|
||||
mv $dst.tmp $dst
|
||||
}
|
||||
|
||||
outdir=$target/old
|
||||
mkdir -p $outdir || true
|
||||
|
||||
# Copy its kernel and initrd to $target/old.
|
||||
addEntry() {
|
||||
local path="$1"
|
||||
local generation="$2"
|
||||
|
||||
if ! test -e $path/kernel -a -e $path/initrd; then
|
||||
return
|
||||
fi
|
||||
|
||||
local kernel=$(readlink -f $path/kernel)
|
||||
local initrd=$(readlink -f $path/initrd)
|
||||
local dtb_path=$(readlink -f $path/dtbs)
|
||||
|
||||
if test -n "@copyKernels@"; then
|
||||
copyToKernelsDir $kernel; kernel=$result
|
||||
copyToKernelsDir $initrd; initrd=$result
|
||||
fi
|
||||
|
||||
echo $(readlink -f $path) > $outdir/$generation-system
|
||||
echo $(readlink -f $path/init) > $outdir/$generation-init
|
||||
cp $path/kernel-params $outdir/$generation-cmdline.txt
|
||||
echo $initrd > $outdir/$generation-initrd
|
||||
echo $kernel > $outdir/$generation-kernel
|
||||
|
||||
if test "$generation" = "default"; then
|
||||
copyForced $kernel $target/kernel.img
|
||||
copyForced $initrd $target/initrd
|
||||
for dtb in $dtb_path/{broadcom,}/bcm*.dtb; do
|
||||
dst="$target/$(basename $dtb)"
|
||||
copyForced $dtb "$dst"
|
||||
filesCopied[$dst]=1
|
||||
done
|
||||
cp "$(readlink -f "$path/init")" $target/nixos-init
|
||||
echo "`cat $path/kernel-params` init=$path/init" >$target/cmdline.txt
|
||||
fi
|
||||
}
|
||||
|
||||
addEntry $default default
|
||||
|
||||
# Add all generations of the system profile to the menu, in reverse
|
||||
# (most recent to least recent) order.
|
||||
for generation in $(
|
||||
(cd /nix/var/nix/profiles && ls -d system-*-link) \
|
||||
| sed 's/system-\([0-9]\+\)-link/\1/' \
|
||||
| sort -n -r); do
|
||||
link=/nix/var/nix/profiles/system-$generation-link
|
||||
addEntry $link $generation
|
||||
done
|
||||
|
||||
# Add the firmware files
|
||||
fwdir=@firmware@/share/raspberrypi/boot/
|
||||
copyForced $fwdir/bootcode.bin $target/bootcode.bin
|
||||
copyForced $fwdir/fixup.dat $target/fixup.dat
|
||||
copyForced $fwdir/fixup4.dat $target/fixup4.dat
|
||||
copyForced $fwdir/fixup4cd.dat $target/fixup4cd.dat
|
||||
copyForced $fwdir/fixup4db.dat $target/fixup4db.dat
|
||||
copyForced $fwdir/fixup4x.dat $target/fixup4x.dat
|
||||
copyForced $fwdir/fixup_cd.dat $target/fixup_cd.dat
|
||||
copyForced $fwdir/fixup_db.dat $target/fixup_db.dat
|
||||
copyForced $fwdir/fixup_x.dat $target/fixup_x.dat
|
||||
copyForced $fwdir/start.elf $target/start.elf
|
||||
copyForced $fwdir/start4.elf $target/start4.elf
|
||||
copyForced $fwdir/start4cd.elf $target/start4cd.elf
|
||||
copyForced $fwdir/start4db.elf $target/start4db.elf
|
||||
copyForced $fwdir/start4x.elf $target/start4x.elf
|
||||
copyForced $fwdir/start_cd.elf $target/start_cd.elf
|
||||
copyForced $fwdir/start_db.elf $target/start_db.elf
|
||||
copyForced $fwdir/start_x.elf $target/start_x.elf
|
||||
|
||||
# Add the config.txt
|
||||
copyForced @configTxt@ $target/config.txt
|
||||
|
||||
# Remove obsolete files from $target and $target/old.
|
||||
for fn in $target/old/*linux* $target/old/*initrd-initrd* $target/bcm*.dtb; do
|
||||
if ! test "${filesCopied[$fn]}" = 1; then
|
||||
rm -vf -- "$fn"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,101 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.boot.loader.raspberryPiColin;
|
||||
|
||||
builderUboot = import ./uboot-builder.nix { inherit pkgs configTxt; inherit (cfg) version; };
|
||||
builderGeneric = import ./raspberrypi-builder.nix { inherit pkgs configTxt; };
|
||||
|
||||
builder =
|
||||
if cfg.uboot.enable then
|
||||
"${builderUboot} -g ${toString cfg.uboot.configurationLimit} -t ${timeoutStr} -c"
|
||||
else
|
||||
"${builderGeneric} -c";
|
||||
|
||||
blCfg = config.boot.loader;
|
||||
timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
|
||||
|
||||
isAarch64 = pkgs.stdenv.hostPlatform.isAarch64;
|
||||
optional = pkgs.lib.optionalString;
|
||||
|
||||
configTxt =
|
||||
pkgs.writeText "config.txt" (''
|
||||
# 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
|
||||
|
||||
# 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
|
||||
'' + optional isAarch64 ''
|
||||
# Boot in 64-bit mode.
|
||||
arm_64bit=1
|
||||
'' + (if cfg.uboot.enable then ''
|
||||
kernel=u-boot-rpi.bin
|
||||
'' else ''
|
||||
kernel=kernel.img
|
||||
initramfs initrd followkernel
|
||||
'') + optional (cfg.firmwareConfig != null) cfg.firmwareConfig);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
boot.loader.raspberryPiColin = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to create files with the system generations in
|
||||
<literal>/boot</literal>.
|
||||
<literal>/boot/old</literal> will hold files from old generations.
|
||||
'';
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
default = 2;
|
||||
type = types.enum [ 0 1 2 3 4 ];
|
||||
description = "";
|
||||
};
|
||||
|
||||
uboot = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enable using uboot as bootmanager for the raspberry pi.
|
||||
'';
|
||||
};
|
||||
|
||||
configurationLimit = mkOption {
|
||||
default = 20;
|
||||
example = 10;
|
||||
type = types.int;
|
||||
description = ''
|
||||
Maximum number of configurations in the boot menu.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
firmwareConfig = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.lines;
|
||||
description = ''
|
||||
Extra options that will be appended to <literal>/boot/config.txt</literal> file.
|
||||
For possible values, see: https://www.raspberrypi.org/documentation/configuration/config-txt/
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
system.build.installBootLoader = builder;
|
||||
system.boot.loader.id = "raspberrypi";
|
||||
system.boot.loader.kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
{ pkgs, version, configTxt }:
|
||||
|
||||
let
|
||||
isAarch64 = pkgs.stdenv.hostPlatform.isAarch64;
|
||||
|
||||
uboot =
|
||||
if version == 0 then
|
||||
pkgs.ubootRaspberryPiZero
|
||||
else if version == 1 then
|
||||
pkgs.ubootRaspberryPi
|
||||
else if version == 2 then
|
||||
pkgs.ubootRaspberryPi2
|
||||
else if version == 3 then
|
||||
if isAarch64 then
|
||||
pkgs.ubootRaspberryPi3_64bit
|
||||
else
|
||||
pkgs.ubootRaspberryPi3_32bit
|
||||
else if version == 4 then
|
||||
if isAarch64 then
|
||||
pkgs.ubootRaspberryPi4_64bit
|
||||
else
|
||||
pkgs.ubootRaspberryPi4_32bit
|
||||
else
|
||||
throw "U-Boot is only supported on the raspberry pi {1,2,3,4}.";
|
||||
|
||||
extlinuxConfBuilder =
|
||||
import ../generic-extlinux-compatible/extlinux-conf-builder.nix {
|
||||
pkgs = pkgs.buildPackages;
|
||||
};
|
||||
in
|
||||
pkgs.substituteAll {
|
||||
src = ./uboot-builder.sh;
|
||||
isExecutable = true;
|
||||
inherit (pkgs) bash;
|
||||
path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
|
||||
firmware = pkgs.raspberrypifw;
|
||||
inherit uboot;
|
||||
inherit configTxt;
|
||||
inherit extlinuxConfBuilder;
|
||||
inherit version;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#! @bash@/bin/sh -e
|
||||
|
||||
target=/boot # Target directory
|
||||
|
||||
while getopts "t:c:d:g:" opt; do
|
||||
case "$opt" in
|
||||
d) target="$OPTARG" ;;
|
||||
*) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
copyForced() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
cp $src $dst.tmp
|
||||
mv $dst.tmp $dst
|
||||
}
|
||||
|
||||
# Call the extlinux builder
|
||||
"@extlinuxConfBuilder@" "$@"
|
||||
|
||||
# Add the firmware files
|
||||
fwdir=@firmware@/share/raspberrypi/boot/
|
||||
copyForced $fwdir/bootcode.bin $target/bootcode.bin
|
||||
copyForced $fwdir/fixup.dat $target/fixup.dat
|
||||
copyForced $fwdir/fixup_cd.dat $target/fixup_cd.dat
|
||||
copyForced $fwdir/fixup_db.dat $target/fixup_db.dat
|
||||
copyForced $fwdir/fixup_x.dat $target/fixup_x.dat
|
||||
copyForced $fwdir/start.elf $target/start.elf
|
||||
copyForced $fwdir/start_cd.elf $target/start_cd.elf
|
||||
copyForced $fwdir/start_db.elf $target/start_db.elf
|
||||
copyForced $fwdir/start_x.elf $target/start_x.elf
|
||||
|
||||
# Add the uboot file
|
||||
copyForced @uboot@/u-boot.bin $target/u-boot-rpi.bin
|
||||
|
||||
# Add the config.txt
|
||||
copyForced @configTxt@ $target/config.txt
|
|
@ -0,0 +1,5 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./boot ];
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{ pkgs }:
|
||||
|
||||
(pkgs.jackett.overrideAttrs (upstream: {
|
||||
patches = [
|
||||
patches = (upstream.patches or []) ++ [
|
||||
# bind to an IP address which is usable behind a netns
|
||||
./01-fix-bind-host.patch
|
||||
];
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
|
||||
index eae03bf023..2ded4123ce 100644
|
||||
--- a/configs/rpi_4_defconfig
|
||||
+++ b/configs/rpi_4_defconfig
|
||||
@@ -63,3 +63,11 @@ CONFIG_VIDEO_BCM2835=y
|
||||
CONFIG_CONSOLE_SCROLL_LINES=10
|
||||
CONFIG_PHYS_TO_BUS=y
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
+CONFIG_CMD_CONFIG=y
|
||||
+CONFIG_CMD_EFIDEBUG=y
|
||||
+CONFIG_CMD_GPT=y
|
||||
+CONFIG_CMD_LOG=y
|
||||
+CONFIG_CMD_READ=y
|
||||
+CONFIG_CMD_USB_MASS_STORAGE=y
|
||||
+CONFIG_LOG_MAX_LEVEL=8
|
||||
+CONFIG_CMD_LSBLK=y
|
||||
diff --git a/disk/part.c b/disk/part.c
|
||||
index 79955c7fb0..c1d469cebb 100644
|
||||
--- a/disk/part.c
|
||||
+++ b/disk/part.c
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <part.h>
|
||||
#include <ubifs_uboot.h>
|
||||
|
||||
-#undef PART_DEBUG
|
||||
+#define PART_DEBUG
|
||||
|
||||
#ifdef PART_DEBUG
|
||||
#define PRINTF(fmt,args...) printf (fmt ,##args)
|
||||
|
||||
diff --git a/disk/part_efi.c b/disk/part_efi.c
|
||||
index 829ccb6bd1..5f3f0ae042 100644
|
||||
--- a/disk/part_efi.c
|
||||
+++ b/disk/part_efi.c
|
||||
@@ -133,12 +133,12 @@ static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
|
||||
* Check that the first_usable_lba and that the last_usable_lba are
|
||||
* within the disk.
|
||||
*/
|
||||
- if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) {
|
||||
+ if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba && lastlba != 0) {
|
||||
printf("GPT: first_usable_lba incorrect: %llX > " LBAF "\n",
|
||||
le64_to_cpu(gpt_h->first_usable_lba), lastlba);
|
||||
return -1;
|
||||
}
|
||||
- if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) {
|
||||
+ if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba && lastlba != 0) {
|
||||
printf("GPT: last_usable_lba incorrect: %llX > " LBAF "\n",
|
||||
le64_to_cpu(gpt_h->last_usable_lba), lastlba);
|
||||
return -1;
|
||||
@@ -1044,6 +1044,8 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
|
||||
return 2;
|
||||
}
|
||||
|
||||
+ printf("is_gpt_valid: sig, lba0, lbaend %llx %llx %llx\n", pgpt_head->signature, pgpt_head->first_usable_lba, pgpt_head->last_usable_lba);
|
||||
+
|
||||
if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
|
||||
return 0;
|
||||
|
||||
@@ -1088,6 +1090,7 @@ static int find_valid_gpt(struct blk_desc *dev_desc, gpt_header *gpt_head,
|
||||
gpt_entry **pgpt_pte)
|
||||
{
|
||||
int r;
|
||||
+ printf("find_valid_gpt %s\n", dev_desc->vendor);
|
||||
|
||||
r = is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head,
|
||||
pgpt_pte);
|
||||
|
||||
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
|
||||
index 21c5209bb6..6ce03d8d09 100644
|
||||
--- a/drivers/block/blk-uclass.c
|
||||
+++ b/drivers/block/blk-uclass.c
|
||||
@@ -443,6 +443,8 @@ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
|
||||
const struct blk_ops *ops = blk_get_ops(dev);
|
||||
ulong blks_read;
|
||||
|
||||
+ printf("blk_dread %s %llu %llu\n", block_dev->vendor, start, blkcnt);
|
||||
+
|
||||
if (!ops->read)
|
||||
return -ENOSYS;
|
||||
|
||||
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
|
||||
index 7a5f0851b5..01545f7480 100644
|
||||
--- a/include/configs/rpi.h
|
||||
+++ b/include/configs/rpi.h
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
/* Architecture, CPU, etc.*/
|
||||
|
||||
+#define CONFIG_SYS_64BIT_LBA
|
||||
+
|
||||
/* Use SoC timer for AArch32, but architected timer for AArch64 */
|
||||
#ifndef CONFIG_ARM64
|
||||
#define CONFIG_SYS_TIMER_RATE 1000000
|
||||
diff --git a/include/log.h b/include/log.h
|
||||
index 8f35c10abb..afd2d704f4 100644
|
||||
--- a/include/log.h
|
||||
+++ b/include/log.h
|
||||
@@ -241,11 +241,7 @@ int _log_buffer(enum log_category_t cat, enum log_level_t level,
|
||||
__func__, pr_fmt(_fmt), ##_args); \
|
||||
})
|
||||
|
||||
-#ifdef DEBUG
|
||||
#define _DEBUG 1
|
||||
-#else
|
||||
-#define _DEBUG 0
|
||||
-#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define _SPL_BUILD 1
|
|
@ -0,0 +1,9 @@
|
|||
{ pkgs }:
|
||||
|
||||
(pkgs.ubootRaspberryPi4_64bit.overrideAttrs (upstream: {
|
||||
patches = (upstream.patches or []) ++ [
|
||||
# enable booting from > 2 TiB drives
|
||||
./01-enable-large-gpt.patch
|
||||
];
|
||||
}))
|
||||
|
Loading…
Reference in New Issue