From 6cd5b906780fb69871f49f2a985adc58c169417f Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Mon, 23 Dec 2024 22:18:38 +0000
Subject: [PATCH 1/9] outputs.rootubifs -> ubifs

---
 modules/outputs/ubifs.nix     | 7 +------
 modules/outputs/ubivolume.nix | 2 +-
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/modules/outputs/ubifs.nix b/modules/outputs/ubifs.nix
index b7a7c61d..4dfc8847 100644
--- a/modules/outputs/ubifs.nix
+++ b/modules/outputs/ubifs.nix
@@ -13,11 +13,6 @@ in
     ./initramfs.nix
   ];
 
-  options.system.outputs.rootubifs = mkOption {
-    type = types.package;
-    internal = true;
-  };
-
   options.hardware.ubi = {
     minIOSize = mkOption { type = types.str; };
     logicalEraseBlockSize = mkOption { type = types.str; }; # LEB
@@ -33,7 +28,7 @@ in
     };
     boot.initramfs.enable = true;
     system.outputs = {
-      rootubifs =
+      rootfs =
         let
           inherit (pkgs.pkgsBuildBuild) runCommand mtdutils;
           cfg = config.hardware.ubi;
diff --git a/modules/outputs/ubivolume.nix b/modules/outputs/ubivolume.nix
index 71c52318..1d82292a 100644
--- a/modules/outputs/ubivolume.nix
+++ b/modules/outputs/ubivolume.nix
@@ -81,7 +81,7 @@ in
           ]);
 
         disk = ubiDisk {
-          initramfs = config.system.outputs.rootubifs; # liminix.builders.squashfs config.filesystem.contents; #           # assert this is a proper FIT.
+          initramfs = config.system.outputs.rootfs; # ???
         };
 
       in

From ede8f12d2bfa1af2f24048e4a0fd8f36dfbe7f80 Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Mon, 23 Dec 2024 22:20:16 +0000
Subject: [PATCH 2/9] declare options.hardware.ubi unconditionally

this is so it can be defined in device modules even when
ubifs is not included in the configuration
---
 modules/hardware.nix      | 6 ++++++
 modules/outputs/ubifs.nix | 7 -------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/modules/hardware.nix b/modules/hardware.nix
index 056cd04f..fc62021e 100644
--- a/modules/hardware.nix
+++ b/modules/hardware.nix
@@ -13,6 +13,12 @@ in
   options = {
     boot = { };
     hardware = {
+      ubi = {
+        minIOSize = mkOption { type = types.str; };
+        logicalEraseBlockSize = mkOption { type = types.str; }; # LEB
+        physicalEraseBlockSize = mkOption { type = types.str; }; # PEB
+        maxLEBcount = mkOption { type = types.str; }; # LEB
+      };
       dts = {
         src = mkOption {
           type = types.nullOr types.path;
diff --git a/modules/outputs/ubifs.nix b/modules/outputs/ubifs.nix
index 4dfc8847..badfc498 100644
--- a/modules/outputs/ubifs.nix
+++ b/modules/outputs/ubifs.nix
@@ -13,13 +13,6 @@ in
     ./initramfs.nix
   ];
 
-  options.hardware.ubi = {
-    minIOSize = mkOption { type = types.str; };
-    logicalEraseBlockSize = mkOption { type = types.str; }; # LEB
-    physicalEraseBlockSize = mkOption { type = types.str; }; # PEB
-    maxLEBcount = mkOption { type = types.str; }; # LEB
-  };
-
   config = mkIf (config.rootfsType == "ubifs") {
     kernel.config = {
       MTD_UBI="y";

From 848214d1047532acb902df7c1a534a1cba26f62b Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Mon, 23 Dec 2024 22:36:14 +0000
Subject: [PATCH 3/9] add ubivolume output

---
 modules/outputs/ubivolume.nix     | 5 ++++-
 modules/outputs/zyxel-nwa-fit.nix | 4 ++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/modules/outputs/ubivolume.nix b/modules/outputs/ubivolume.nix
index 1d82292a..d5097cd8 100644
--- a/modules/outputs/ubivolume.nix
+++ b/modules/outputs/ubivolume.nix
@@ -18,6 +18,9 @@ in
       eraseBlockSize = mkOption { type = types.str; }; # LEB
       maxLEBcount = mkOption { type = types.str; }; # LEB
     };
+    options.system.outputs.ubivolume = mkOption {
+      type = types.package;
+    };
 
     config = mkIf (config.rootfsType == "ubifs") {
       kernel.config = {
@@ -28,7 +31,7 @@ in
       };
       boot.initramfs.enable = true;
 
-      system.outputs.rootfs =
+      system.outputs.ubivolume =
       let
         inherit (pkgs.pkgsBuildBuild) runCommand;
         ubiVolume = ({ name, volumeId, image, flags ? [] }:
diff --git a/modules/outputs/zyxel-nwa-fit.nix b/modules/outputs/zyxel-nwa-fit.nix
index a6e14b66..13e8f9da 100644
--- a/modules/outputs/zyxel-nwa-fit.nix
+++ b/modules/outputs/zyxel-nwa-fit.nix
@@ -31,7 +31,7 @@ on a system with pre-existing firmware and OS.
   config = mkIf (config.rootfsType == "ubifs") {
 
     system.outputs.zyxel-nwa-fit =
-      let 
+      let
         o = config.system.outputs;
         # 8129kb padding.
         paddedKernel = pkgs.runCommand "padded-kernel" {} ''
@@ -39,7 +39,7 @@ on a system with pre-existing firmware and OS.
           dd if=/dev/zero of=$out bs=1 count=1 seek=8388607
         '';
         firmwareImage = pkgs.runCommand "firmware-image" {} ''
-          cat ${paddedKernel} ${o.rootfs} > $out
+          cat ${paddedKernel} ${o.ubivolume} > $out
         '';
         dts = pkgs.writeText "image.its" ''
         /dts-v1/;

From bc20f4c6b748960699c9015cbbd6275c8ccdde5e Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Mon, 23 Dec 2024 23:59:52 +0000
Subject: [PATCH 4/9] rt3200 test install

---
 devices/belkin-rt3200/default.nix |  8 ++++++--
 modules/outputs/ubimage.nix       | 31 +++++++++++++++----------------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
index 4436e713..574dd00d 100644
--- a/devices/belkin-rt3200/default.nix
+++ b/devices/belkin-rt3200/default.nix
@@ -44,7 +44,9 @@
         MT7622> tftpboot 0x42000000  openwrt-mediatek-mt7622-linksys_e8450-ubi-initramfs-recovery-installer.itb
         MT7622> bootm 0x42000000
 
-     Once it's finished booted into Linux you can safely reboot
+     This will write the new flash layout and then boot into a
+     "recovery" OpenWrt installation. Once it's finished booting into
+     Linux you can safely reboot
 
      Installing Liminix
      ------------------
@@ -73,6 +75,7 @@
         ../../modules/arch/aarch64.nix
         ../../modules/outputs/tftpboot.nix
         ../../modules/outputs/ubifs.nix
+        ../../modules/outputs/ubimage.nix
       ];
       config = {
     kernel = {
@@ -203,7 +206,8 @@
       in {
         ubi = {
           minIOSize = "2048";
-          eraseBlockSize = "126976";
+          logicalEraseBlockSize = "126976";
+          physicalEraseBlockSize = "131072";
           maxLEBcount = "1024"; # guessing
         };
 
diff --git a/modules/outputs/ubimage.nix b/modules/outputs/ubimage.nix
index c6ab4641..528c7b2f 100644
--- a/modules/outputs/ubimage.nix
+++ b/modules/outputs/ubimage.nix
@@ -82,12 +82,11 @@ automatically, you can try booting it by hand to see if it works:
 .. code-block:: console
 
     uboot> ubifsmount ubi0:liminix
-    uboot> ubifsload ''${loadaddr} boot/uimage
+    uboot> ubifsload ''${loadaddr} boot/fit
     uboot> bootm ''${loadaddr}
 
 Once you've done this and you're happy with it, reset the device to
-U-Boot. You don't need to recreate the volume but you do need to
-repeat step 3.
+return to U-Boot.
 
 5) Instructions for configuring autoboot are likely to be very
 device-dependent. On the Linksys E8450/Belkin RT3200, the environment
@@ -96,7 +95,10 @@ you could do
 
 .. code-block:: console
 
-    uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix; ubifsload ''${loadaddr} boot/uimage; bootm ''${loadaddr}'
+    uboot> setenv orig_boot_production $boot_production
+    uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix && ubifsload ''${loadaddr} boot/fit && bootm ''${loadaddr}'
+    uboot> saveenv
+    uboot> reset
 
 On other devices, some detective work may be needed. Try running
 `printenv` and look for likely commands, try looking at the existing
@@ -111,16 +113,13 @@ boot process, maybe even try looking for documentation for that device.
     };
   };
 
-  config = mkIf (config.rootfsType == "ubifs") {
-    system.outputs = {
-      ubimage =
-        let o = config.system.outputs; in
-        pkgs.runCommand "ubimage" {} ''
-          mkdir $out
-          cd $out
-          ln -s ${o.rootfs} rootfs
-          ln -s ${instructions} env.scr
-       '';
-    };
-  };
+  config.system.outputs.ubimage =
+    assert config.rootfsType == "ubifs";
+    let o = config.system.outputs; in
+    pkgs.runCommand "ubimage" {} ''
+      mkdir $out
+      cd $out
+      ln -s ${o.rootfs} rootfs
+      ln -s ${instructions} env.scr
+   '';
 }

From 0ee9c76c333cd59d5fd664b6a2a3d3a6a454a861 Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Tue, 24 Dec 2024 12:20:48 +0000
Subject: [PATCH 5/9] think

---
 THOUGHTS.txt | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/THOUGHTS.txt b/THOUGHTS.txt
index d46f4bbe..dbf996ef 100644
--- a/THOUGHTS.txt
+++ b/THOUGHTS.txt
@@ -6634,3 +6634,39 @@ Read 7491584 bytes from volume recovery to 0000000048000000
    Using 'config-1' configuration
    Trying 'kernel-1' kernel subimage
      Description:  ARM64 OpenWrt Linux-6.6.45
+
+Sun Dec 22 17:39:56 GMT 2024
+
+From the output above it looks like the device I have plugged in has
+an openwrt "recovery" image but not a "production" image
+
+It also looks like it will be quite hard work to persuade it to boot
+from usb or anything. It doesn't have any of the extlinux stuff
+but it does have uefi for what that's worth
+
+default boot_production command reads a ubi volume called 'fit' and
+calls bootm on what it finds
+
+we could define boot_production to ubifsmount liminix; ubifs load
+<addr> <filename> (which is a fit) and bootm it. *presumably* we could
+do this from the openwrt recovery image
+
+but could we install the whole system using said recovery image?  I
+expect we could do, it only requires getting a tarball onto it and
+unpacking it
+
+however, extlinux is not going to be helpful
+(actually it might be a bit, if we ask it to write the fit as
+well as/instead of the individual files)
+
+maybe we need separate concepts of "the filesystem contains
+stuff we need for boot" and "the stuff we need is the stuff
+that extlinux needs"
+
+each bootloader makes an output called bootfiles, and
+the bootablerootdir output copies from bootfiles
+
+Mon Dec 23 18:28:50 GMT 2024
+
+it might be worth moving ubi option decls into the hardware module, if
+they're hardware-dependent

From f8a275d1a31f7fd9cb716c70d44f24f203a313ee Mon Sep 17 00:00:00 2001
From: Arnout Engelen <arnout@bzzt.net>
Date: Tue, 17 Dec 2024 20:24:14 +0100
Subject: [PATCH 6/9] use Linux kernel sources associated with openwrt by
 default

---
 devices/belkin-rt3200/default.nix  |  5 -----
 devices/families/qemu.nix          |  5 -----
 devices/gl-ar750/default.nix       |  6 ------
 devices/gl-mt300a/default.nix      |  5 -----
 devices/gl-mt300n-v2/default.nix   |  5 -----
 devices/tp-archer-ax23/default.nix |  5 -----
 devices/zyxel-nwa50ax/default.nix  |  6 ------
 modules/kernel/default.nix         |  6 +++---
 pkgs/openwrt/default.nix           | 11 +++++++++++
 9 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
index 574dd00d..4962a873 100644
--- a/devices/belkin-rt3200/default.nix
+++ b/devices/belkin-rt3200/default.nix
@@ -79,11 +79,6 @@
       ];
       config = {
     kernel = {
-      src = pkgs.pkgsBuildBuild.fetchurl {
-        name = "linux.tar.gz";
-        url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-        hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-      };
       extraPatchPhase = ''
           ${pkgs.openwrt.applyPatches.mediatek}
       '';
diff --git a/devices/families/qemu.nix b/devices/families/qemu.nix
index ce28d884..ccf054c1 100644
--- a/devices/families/qemu.nix
+++ b/devices/families/qemu.nix
@@ -5,11 +5,6 @@
   ];
   config = {
     kernel = {
-      src = pkgs.pkgsBuildBuild.fetchurl {
-        name = "linux.tar.gz";
-        url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-        hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-      };
       config = {
         MTD = "y";
         MTD_BLOCK = "y";
diff --git a/devices/gl-ar750/default.nix b/devices/gl-ar750/default.nix
index 7be4c904..a7f18a6c 100644
--- a/devices/gl-ar750/default.nix
+++ b/devices/gl-ar750/default.nix
@@ -161,12 +161,6 @@
         appendDTB = true;
       };
       kernel = {
-        src = pkgs.pkgsBuildBuild.fetchurl {
-          name = "linux.tar.gz";
-          url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-          hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-        };
-
         # Mainline linux 5.19 doesn't have device-tree support for
         # this device or even for the SoC, so we use the extensive
         # OpenWrt kernel patches
diff --git a/devices/gl-mt300a/default.nix b/devices/gl-mt300a/default.nix
index 6659951f..d972e44c 100644
--- a/devices/gl-mt300a/default.nix
+++ b/devices/gl-mt300a/default.nix
@@ -114,11 +114,6 @@
      };
 
       kernel = {
-        src = pkgs.fetchurl {
-          name = "linux.tar.gz";
-          url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-          hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-        };
         extraPatchPhase = ''
           ${openwrt.applyPatches.ramips}
           ${openwrt.applyPatches.rt2x00}
diff --git a/devices/gl-mt300n-v2/default.nix b/devices/gl-mt300n-v2/default.nix
index ae12317d..901bfaa4 100644
--- a/devices/gl-mt300n-v2/default.nix
+++ b/devices/gl-mt300n-v2/default.nix
@@ -125,11 +125,6 @@
       };
 
       kernel = {
-        src = pkgs.fetchurl {
-          name = "linux.tar.gz";
-          url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-          hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-        };
         extraPatchPhase = ''
           ${openwrt.applyPatches.ramips}
         '';
diff --git a/devices/tp-archer-ax23/default.nix b/devices/tp-archer-ax23/default.nix
index 64eff0fd..6c6519c3 100644
--- a/devices/tp-archer-ax23/default.nix
+++ b/devices/tp-archer-ax23/default.nix
@@ -50,11 +50,6 @@
       ];
       config = {
         kernel = {
-          src = pkgs.pkgsBuildBuild.fetchurl {
-            name = "linux.tar.gz";
-            url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-            hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-          };
           extraPatchPhase = ''
             ${pkgs.openwrt.applyPatches.ramips}
           '';
diff --git a/devices/zyxel-nwa50ax/default.nix b/devices/zyxel-nwa50ax/default.nix
index 9c9b9d9c..710473d2 100644
--- a/devices/zyxel-nwa50ax/default.nix
+++ b/devices/zyxel-nwa50ax/default.nix
@@ -250,14 +250,8 @@
       #  IMAGE/ramboot-factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi
 
       kernel = {
-        src = pkgs.fetchurl {
-          name = "linux.tar.gz";
-          url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
-          hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
-        };
         extraPatchPhase = ''
           ${openwrt.applyPatches.ramips}
-
         '';
         config = {
 
diff --git a/modules/kernel/default.nix b/modules/kernel/default.nix
index e5431fec..373bfcc2 100644
--- a/modules/kernel/default.nix
+++ b/modules/kernel/default.nix
@@ -6,7 +6,7 @@
 { lib, pkgs, config, ...}:
 let
   inherit (lib) mkOption types ;
-  inherit (pkgs) liminix;
+  inherit (pkgs) liminix openwrt;
 
   mergeConditionals = conf : conditions :
     # for each key in conditions, if it is present in conf
@@ -21,8 +21,8 @@ let
 in {
   options = {
     kernel = {
-      src = mkOption { type = types.path; } ;
-      version = mkOption { type = types.str; default = "5.15.137";} ;
+      src = mkOption { type = types.path; default = openwrt.kernelSrc; } ;
+      version = mkOption { type = types.str; default = openwrt.kernelVersion;} ;
       modular = mkOption {
         type = types.bool;
         default = true;
diff --git a/pkgs/openwrt/default.nix b/pkgs/openwrt/default.nix
index 2fb16ec1..7376dd8b 100644
--- a/pkgs/openwrt/default.nix
+++ b/pkgs/openwrt/default.nix
@@ -29,6 +29,17 @@ let
   '';
 in {
   inherit src;
+
+  # The kernel sources typically used with this version of openwrt
+  # You can find this in `include/kernel-5.15` or similar in the
+  # openwrt sources
+  kernelSrc = pkgsBuildBuild.fetchurl {
+    name = "linux.tar.gz";
+    url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.137.tar.gz";
+    hash = "sha256-PkdzUKZ0IpBiWe/RS70J76JKnBFzRblWcKlaIFNxnHQ=";
+  };
+  kernelVersion = "5.15.137";
+
   applyPatches.ath79 = doPatch "ath79";
   applyPatches.ramips = doPatch "ramips";
   applyPatches.mediatek = doPatch "mediatek"; # aarch64

From 67a1cd37185c7a528a6e4db0714f5ad16e55b42d Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Tue, 24 Dec 2024 13:45:11 +0000
Subject: [PATCH 7/9] improve install instructions for belkin rt3200

---
 devices/belkin-rt3200/default.nix | 59 +++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
index 4962a873..ffd19acc 100644
--- a/devices/belkin-rt3200/default.nix
+++ b/devices/belkin-rt3200/default.nix
@@ -4,7 +4,8 @@
     ******************************
 
     This device is based on a 64 bit Mediatek MT7622 ARM platform,
-    and is "work in progress" in Liminix.
+    and is mostly feature-complete in Liminix but as of Dec 2024
+    has seen very little actual use.
 
     .. note:: The factory flash image contains ECC errors that make it
               incompatible with Liminix: use the `OpenWrt
@@ -25,7 +26,11 @@
     Installation
     ============
 
-    Installation is currently a manual process.
+    Liminix on this device uses the UBI volume management system to
+    perform wear leveling on the flash. This is not set up from the
+    factory, so a one-time step is needed to prepare it before Liminix
+    can be installed.
+
 
     Preparation
     -----------
@@ -33,7 +38,7 @@
     To prepare the device for Liminix you first need to use the
     `OpenWrt UBI Installer
     <https://github.com/dangowrt/owrt-ubi-installer>`_ image to
-    rewrite the flash layout. You can do this in onw of two ways:
+    rewrite the flash layout. You can do this in one of two ways:
     either follow the instructions to do it through the vendor web
     interface, or you can drop to U-boot and use TFTP
 
@@ -44,16 +49,50 @@
         MT7622> tftpboot 0x42000000  openwrt-mediatek-mt7622-linksys_e8450-ubi-initramfs-recovery-installer.itb
         MT7622> bootm 0x42000000
 
-     This will write the new flash layout and then boot into a
-     "recovery" OpenWrt installation. Once it's finished booting into
-     Linux you can safely reboot
+    This will write the new flash layout and then boot into a
+    "recovery" OpenWrt installation.
 
-     Installing Liminix
-     ------------------
+    Building/installing Liminix
+    ----------------
 
-     This is a manual process: you need a :ref:`serial <serial>` conection and TFTP : follow the instructions at :ref:`system-outputs-ubimage`
+    The default target for this device is ``outputs.ubimage`` which
+    makes a ubifs image suitable for use with :command:`ubiupdatevol`.
+    For a first-time installation the simplest way to achieve this is
+    using the OpenWrt recovery system that you installed in the
+    previous step. In this configuration the device assigns itself the
+    IP address 192.168.1.1/24 on its LAN ports and expects the
+    connected computer to have 192.168.1.254
 
-'';
+    The `ubi0_7` device in these instructions is correct as of Dec
+    2024 (dangowrt/owrt-ubi-installer commit d79e7928). If you are
+    installing some time later, it is important to check the output
+    from :command:`ubinfo -a` and make sure you are updating the
+    "liminix" volume and not some other one which had been introduced
+    since I wrote this.
+
+    .. code-block:: console
+
+        $ nix-build -I liminix-config=./my-configuration.nix  --arg device "import ./devices/belkin-rt3200" -A outputs.default
+        $ cat result/rootfs | ssh root@192.168.1.1 "cat > /tmp/rootfs"
+        $ ssh root@192.168.1.1
+        root@OpenWrt:~# ubimkvol /dev/ubi0 --name=liminix --maxavsize
+        root@OpenWrt:~# ubinfo -a
+        [...]
+        Volume ID:   7 (on ubi0)
+        Type:        dynamic
+        Alignment:   1
+        Size:        851 LEBs (108056576 bytes, 103.0 MiB)
+        State:       OK
+        Name:        liminix
+        Character device major/minor: 250:8
+        root@OpenWrt:~# ubiupdatevol /dev/ubi0_7 /tmp/rootfs
+
+     For subsequent Liminix reinstalls, you don't need to repeat the
+     "Preparation" step and in fact should seek to avoid it if
+     possible. Updating volumes with :command:`ubiupdatevol` will
+     preserve the erase counters used for write levelling, so is
+     preferred over any kind of "factory" wipe which will reset them.
+     '';
 
   system = {
     crossSystem = {

From 294492a17697b68ceda114ae1347b31b74655881 Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Tue, 24 Dec 2024 13:46:19 +0000
Subject: [PATCH 8/9] jiggle imports

---
 devices/belkin-rt3200/default.nix | 1 -
 modules/outputs.nix               | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
index ffd19acc..d669b32e 100644
--- a/devices/belkin-rt3200/default.nix
+++ b/devices/belkin-rt3200/default.nix
@@ -114,7 +114,6 @@
         ../../modules/arch/aarch64.nix
         ../../modules/outputs/tftpboot.nix
         ../../modules/outputs/ubifs.nix
-        ../../modules/outputs/ubimage.nix
       ];
       config = {
     kernel = {
diff --git a/modules/outputs.nix b/modules/outputs.nix
index 6da7daaa..9eaeedf3 100644
--- a/modules/outputs.nix
+++ b/modules/outputs.nix
@@ -17,6 +17,7 @@ in
     ./outputs/boot-fit.nix
     ./outputs/uimage.nix
     ./outputs/updater
+    ./outputs/ubimage.nix
   ];
   options = {
     system.outputs = {

From 3f6e9b6384100104bba008a3e10cd9e674b8a64c Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Tue, 24 Dec 2024 13:46:36 +0000
Subject: [PATCH 9/9] rt3200 defaults to ubifs

---
 devices/belkin-rt3200/default.nix | 1 +
 1 file changed, 1 insertion(+)

diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
index d669b32e..68da44c8 100644
--- a/devices/belkin-rt3200/default.nix
+++ b/devices/belkin-rt3200/default.nix
@@ -218,6 +218,7 @@
       tftp.loadAddress = lim.parseInt "0x4007ff28";
       imageFormat = "fit";
     };
+    rootfsType = lib.mkDefault "ubifs";
     filesystem =
       let inherit (pkgs.pseudofile) dir symlink;
            in