sane.image: fix so `imgs.moby` includes a working bootloader
This commit is contained in:
parent
a65673847a
commit
eff37765ae
|
@ -1,12 +1,22 @@
|
||||||
|
# tow-boot: <https://tow-boot.org>
|
||||||
|
# docs (pinephone specific): <https://github.com/Tow-Boot/Tow-Boot/tree/development/boards/pine64-pinephoneA64>
|
||||||
|
# LED and button behavior is defined here: <https://github.com/Tow-Boot/Tow-Boot/blob/development/modules/tow-boot/phone-ux.nix>
|
||||||
|
# - hold VOLDOWN: enter recovery mode
|
||||||
|
# - LED will turn aqua instead of yellow
|
||||||
|
# - recovery mode would ordinarily allow a selection of entries, but for pinephone i guess it doesn't do anything?
|
||||||
|
# - hold VOLUP: force it to load the OS from eMMC?
|
||||||
|
# - LED will turn blue instead of yellow
|
||||||
|
# boot LEDs:
|
||||||
|
# - yellow = entered tow-boot
|
||||||
|
# - 10 red flashes => poweroff means tow-boot couldn't boot into the next stage (i.e. distroboot)
|
||||||
|
# - distroboot: <https://source.denx.de/u-boot/u-boot/-/blob/v2022.04/doc/develop/distro.rst>)
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
# we need space in the GPT header to place tow-boot.
|
# we need space in the GPT header to place tow-boot.
|
||||||
# only actually need 1 MB, but better to over-allocate than under-allocate
|
# only actually need 1 MB, but better to over-allocate than under-allocate
|
||||||
sane.image.extraGPTPadding = 16 * 1024 * 1024;
|
sane.image.extraGPTPadding = 16 * 1024 * 1024;
|
||||||
sane.image.firstPartGap = 0;
|
sane.image.firstPartGap = 0;
|
||||||
system.build.img = pkgs.runCommand "nixos_full-disk-image.img" {} ''
|
sane.image.installBootloader = ''
|
||||||
cp -v ${config.system.build.img-without-firmware}/nixos.img $out
|
dd if=${pkgs.tow-boot-pinephone}/Tow-Boot.noenv.bin of=$out/nixos.img bs=1024 seek=8 conv=notrunc
|
||||||
chmod +w $out
|
|
||||||
dd if=${pkgs.tow-boot-pinephone}/Tow-Boot.noenv.bin of=$out bs=1024 seek=8 conv=notrunc
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
{ config, lib, pkgs, utils, ... }:
|
# this builds a disk image which can be flashed onto a HDD, SD card, etc, and boot a working image.
|
||||||
|
# debug the image by building one of:
|
||||||
|
# - `nix build '.#imgs.$host' --builders "" -v`
|
||||||
|
# - `nix build '.#imgs.$host.passthru.{bootFsImg,nixFsImg,withoutBootloader}'`
|
||||||
|
# then loop-mounting it:
|
||||||
|
# - `sudo losetup -Pf ./result/nixos.img`
|
||||||
|
# - `mkdir /tmp/nixos.boot`
|
||||||
|
# - `sudo mount /dev/loop0p1 /tmp/nixos.boot`, and look inside
|
||||||
|
#
|
||||||
# TODO: replace mobile-nixos parts with Disko <https://github.com/nix-community/disko>
|
# TODO: replace mobile-nixos parts with Disko <https://github.com/nix-community/disko>
|
||||||
|
# or just inline them here.
|
||||||
|
{ config, lib, pkgs, utils, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -62,6 +72,14 @@ in
|
||||||
N.B.: setting this to something other than 512B is not well tested.
|
N.B.: setting this to something other than 512B is not well tested.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
sane.image.installBootloader = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
command which takes the full disk image and installs hw-specific bootloader (u-boot, tow-boot, etc).
|
||||||
|
for EFI-native systems (most x86_64), can be left empty.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = let
|
config = let
|
||||||
# return true if super starts with sub
|
# return true if super starts with sub
|
||||||
|
@ -90,10 +108,52 @@ in
|
||||||
"ext4" = pkgs.imageBuilder.fileSystem.makeExt4;
|
"ext4" = pkgs.imageBuilder.fileSystem.makeExt4;
|
||||||
"btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs;
|
"btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs;
|
||||||
};
|
};
|
||||||
in
|
|
||||||
lib.mkIf cfg.enable
|
bootFsImg = fsBuilderMapBoot."${bootFs.fsType}" {
|
||||||
{
|
# fs properties
|
||||||
system.build.img-without-firmware = with pkgs; pkgs.imageBuilder.diskImage.makeGPT {
|
name = "ESP";
|
||||||
|
partitionID = vfatUuidFromFs bootFs;
|
||||||
|
# partition properties
|
||||||
|
partitionLabel = "EFI System";
|
||||||
|
partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}";
|
||||||
|
size = cfg.bootPartSize;
|
||||||
|
inherit (cfg) sectorSize;
|
||||||
|
blockSize = cfg.sectorSize; # has to be a multiple of sectorSize
|
||||||
|
|
||||||
|
populateCommands = let
|
||||||
|
extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles);
|
||||||
|
in ''
|
||||||
|
echo "running installBootLoader"
|
||||||
|
${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d .
|
||||||
|
echo "ran installBootLoader"
|
||||||
|
${extras}
|
||||||
|
echo "copied extraBootFiles"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
nixFsImg = fsBuilderMapNix."${nixFs.fsType}" {
|
||||||
|
# fs properties
|
||||||
|
name = "NIXOS_SYSTEM";
|
||||||
|
partitionID = uuidFromFs nixFs;
|
||||||
|
# partition properties
|
||||||
|
partitionLabel = "Linux filesystem";
|
||||||
|
partitionUUID = uuidFromFs nixFs;
|
||||||
|
# inherit (cfg) sectorSize; # imageBuilder only supports sectorSize for vfat. btrfs defaults to a 4096B sector size, somehow it abstracts over the drive's sector size?
|
||||||
|
|
||||||
|
populateCommands = let
|
||||||
|
closureInfo = pkgs.buildPackages.closureInfo { rootPaths = config.system.build.toplevel; };
|
||||||
|
extraRelPaths = builtins.toString (builtins.map (p: "./" + builtins.toString(relPath nixFs.mountPoint p)) cfg.extraDirectories);
|
||||||
|
in ''
|
||||||
|
mkdir -p ./${storeRelPath} ${extraRelPaths}
|
||||||
|
echo "Copying system closure..."
|
||||||
|
while IFS= read -r path; do
|
||||||
|
echo " Copying $path"
|
||||||
|
cp -prf "$path" ./${storeRelPath}
|
||||||
|
done < "${closureInfo}/store-paths"
|
||||||
|
echo "Done copying system closure..."
|
||||||
|
cp -v ${closureInfo}/registration ./nix-path-registration
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
img = (pkgs.imageBuilder.diskImage.makeGPT {
|
||||||
name = "nixos";
|
name = "nixos";
|
||||||
diskID = vfatUuidFromFs bootFs;
|
diskID = vfatUuidFromFs bootFs;
|
||||||
# leave some space for firmware
|
# leave some space for firmware
|
||||||
|
@ -102,52 +162,28 @@ in
|
||||||
headerHole = cfg.extraGPTPadding;
|
headerHole = cfg.extraGPTPadding;
|
||||||
partitions = [
|
partitions = [
|
||||||
(pkgs.imageBuilder.gap cfg.firstPartGap)
|
(pkgs.imageBuilder.gap cfg.firstPartGap)
|
||||||
(fsBuilderMapBoot."${bootFs.fsType}" {
|
bootFsImg
|
||||||
# fs properties
|
nixFsImg
|
||||||
name = "ESP";
|
|
||||||
partitionID = vfatUuidFromFs bootFs;
|
|
||||||
# partition properties
|
|
||||||
partitionLabel = "EFI System";
|
|
||||||
partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}";
|
|
||||||
size = cfg.bootPartSize;
|
|
||||||
inherit (cfg) sectorSize;
|
|
||||||
blockSize = cfg.sectorSize; # has to be a multiple of sectorSize
|
|
||||||
|
|
||||||
populateCommands = let
|
|
||||||
extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles);
|
|
||||||
in ''
|
|
||||||
echo "running installBootLoader"
|
|
||||||
${config.system.build.installBootLoader} ${config.system.build.toplevel} -d .
|
|
||||||
echo "ran installBootLoader"
|
|
||||||
${extras}
|
|
||||||
echo "copied extraBootFiles"
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
(fsBuilderMapNix."${nixFs.fsType}" {
|
|
||||||
# fs properties
|
|
||||||
name = "NIXOS_SYSTEM";
|
|
||||||
partitionID = uuidFromFs nixFs;
|
|
||||||
# partition properties
|
|
||||||
partitionLabel = "Linux filesystem";
|
|
||||||
partitionUUID = uuidFromFs nixFs;
|
|
||||||
# inherit (cfg) sectorSize; # imageBuilder only supports sectorSize for vfat. btrfs defaults to a 4096B sector size, somehow it abstracts over the drive's sector size?
|
|
||||||
|
|
||||||
populateCommands = let
|
|
||||||
closureInfo = buildPackages.closureInfo { rootPaths = config.system.build.toplevel; };
|
|
||||||
extraRelPaths = builtins.toString (builtins.map (p: "./" + builtins.toString(relPath nixFs.mountPoint p)) cfg.extraDirectories);
|
|
||||||
in ''
|
|
||||||
mkdir -p ./${storeRelPath} ${extraRelPaths}
|
|
||||||
echo "Copying system closure..."
|
|
||||||
while IFS= read -r path; do
|
|
||||||
echo " Copying $path"
|
|
||||||
cp -prf "$path" ./${storeRelPath}
|
|
||||||
done < "${closureInfo}/store-paths"
|
|
||||||
echo "Done copying system closure..."
|
|
||||||
cp -v ${closureInfo}/registration ./nix-path-registration
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
|
}) // {
|
||||||
|
passthru = {
|
||||||
|
inherit bootFsImg nixFsImg;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable
|
||||||
|
{
|
||||||
|
system.build.img = (if cfg.installBootloader == null then
|
||||||
|
img
|
||||||
|
else pkgs.runCommand "nixos-with-bootloader" {} ''
|
||||||
|
cp -vR ${img} $out
|
||||||
|
chmod -R +w $out
|
||||||
|
${cfg.installBootloader}
|
||||||
|
'') // {
|
||||||
|
passthru = {
|
||||||
|
inherit bootFsImg nixFsImg;
|
||||||
|
withoutBootloader = img;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
system.build.img = lib.mkDefault config.system.build.img-without-firmware;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue