From 71b583a756b198da349ee53649c6ed9fa6aa7a7e Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sun, 17 Sep 2023 17:36:02 +0100 Subject: [PATCH] copy "how to flash" from the old docs --- doc/admin.rst | 191 ++++++++++++++++++++++++++++++++++++++++-- doc/configuration.rst | 11 ++- 2 files changed, 187 insertions(+), 15 deletions(-) diff --git a/doc/admin.rst b/doc/admin.rst index 9885997..71f9b18 100644 --- a/doc/admin.rst +++ b/doc/admin.rst @@ -1,15 +1,188 @@ System Administration ##################### -.. - - administration guide +Services on a running system +**************************** - - what you can do on a running system - - s6-rc commands +* add an s6-rc cheatsheet here - - writable filesystem: min-copy-closure, min-collect-garbage, - liminix-rebuild - - full flash: - how to do the two-step thing - flash from OpenWrt +Flashing and updating +********************* + + + +Flashing from an existing Liminix system with :command:`flashcp` +================================================================ + +The flash procedure from an existing Liminix-system has two steps. +First we reboot the device (using "kexec") into an "ephemeral" +RAM-based version of the new configuration, then when we're happy it +works we can flash the image - and if it doesn't work we can reboot +the device again and it will boot from the old image. + + +Building the RAM-based image +---------------------------- + +To create the ephemeral image, build ``outputs.kexecboot`` instead of +``outputs.default``. This generates a directory containing the root +filesystem image and kernel, along with an executable called `kexec` +and a `boot.sh` script that runs it with appropriate arguments. + +For example + +.. code-block:: console + + nix-build --show-trace -I liminix-config=./examples/arhcive.nix \ + --arg device "import ./devices/gl-ar750" + -A outputs.kexecboot && \ + (tar chf - result | ssh root@the-device tar -C /run -xvf -) + +and then login to the device and run + +.. code-block:: console + + cd /run/result + sh ./boot.sh . + + +This will load the new kernel and map the root filesystem into a RAM +disk, then start executing the new kernel. *This is effectively a +reboot - be sure to close all open files and finish anything else +you were doing first.* + +If the new system crashes or is rebooted, then the device will revert +to the old configuration it finds in flash. + + +Building the second (permanent) image +------------------------------------- + +While running in the kexecboot system, you can copy the permanent +image to the device with :command:`ssh` + +.. code-block:: console + + build-machine$ tar chf - result/firmware.bin | \ + ssh root@the-device tar -C /run -xvf - + +Next you need to connect to the device and locate the "firmware" +partition, which you can do with a combination of :command:`dmesg` +output and the contents of :file:`/proc/mtd` + +.. code-block:: console + + <5>[ 0.469841] Creating 4 MTD partitions on "spi0.0": + <5>[ 0.474837] 0x000000000000-0x000000040000 : "u-boot" + <5>[ 0.480796] 0x000000040000-0x000000050000 : "u-boot-env" + <5>[ 0.487056] 0x000000050000-0x000000060000 : "art" + <5>[ 0.492753] 0x000000060000-0x000001000000 : "firmware" + + # cat /proc/mtd + dev: size erasesize name + mtd0: 00040000 00001000 "u-boot" + mtd1: 00010000 00001000 "u-boot-env" + mtd2: 00010000 00001000 "art" + mtd3: 00fa0000 00001000 "firmware" + mtd4: 002a0000 00001000 "kernel" + mtd5: 00d00000 00001000 "rootfs" + +Now run (in this example) + +.. code-block:: console + + flashcp -v firmware.bin /dev/mtd3 + + +"I know my new image is good, can I skip the intermediate step?" +---------------------------------------------------------------- + +In addition to giving you a chance to see if the new image works, this +two-step process ensures that you're not copying the new image over +the top of the active root filesystem. Sometimes it works, but you +will at least need physical access to the device to power-cycle it +because it will be effectively frozen afterwards. + + +Flashing from the boot monitor +============================== + +If you are prepared to open the device and have a TTL serial adaptor +of some kind to connect it to, you can probably flash it using U-Boot. +This is quite hardware-specific, and sometimes involves soldering: +please refer to the Developer Manual. + + +Flashing from OpenWrt (not currently advised!) +============================================== + +.. CAUTION:: At your own risk! This will (at least in some + circumstances) lead to bricking the device: we think this + flash method is currently incompatible with use of a + writeable (jffs2) filesystem. + +If your device is running OpenWrt then it probably has the +:command:`mtd` command installed. After transferring the image onto the +device using e.g. :command:`ssh`, you can run it as follows: + +.. code-block:: console + + mtd -r write /tmp/firmware.bin firmware + +For more information, please see the `OpenWrt manual `_ which may also contain (hardware-dependent) instructions on how to flash an image using the vendor firmware - perhaps even from a web interface. + +Updating an installed system (JFFS2) +************************************ + + +Adding packages +=============== + +If your device is running a JFFS2 root filesystem, you can build +extra packages for it on your build system and copy them to the +device: any package in Nixpkgs or in the Liminix overlay is available +with the ``pkgs`` prefix: + +.. code-block:: console + + nix-build -I liminix-config=./my-configuration.nix \ + --arg device "import ./devices/mydevice" -A pkgs.tcpdump + + nix-shell -p min-copy-closure root@the-device result/ + +Note that this only copies the package to the device: it doesn't update +any profile to add it to ``$PATH`` + + +Rebuilding the system +===================== + +:command:`liminix-rebuild` is the Liminix analogue of :command:`nixos-rebuild`, although its operation is a bit different because it expects to run on a build machine and then copy to the host device. Run it with the same ``liminix-config`` and ``device`` parameters as you would run :command:`nix-build`, and it will build any new/changed packages and then copy them to the device using SSH. For example: + +.. code-block:: console + + liminix-rebuild root@the-device -I liminix-config=./examples/rotuer.nix --arg device "import ./devices/gl-ar750" + +This will + +* build anything that needs building +* copy new or changed packages to the device +* reboot the device + +It doesn't delete old packages automatically: to do that run +:command:`min-collect-garbage`, which will delete any packages not in +the current system closure. Note that Liminix does not have the NixOS +concept of environments or generations, and there is no way back from +this except for building the previous configuration again. + + +Caveats +~~~~~~~ + +* it needs there to be enough free space on the device for all the new + packages in addition to all the packages already on it - which may be + a problem if a lot of things have changed (e.g. a new version of + nixpkgs). + +* it cannot upgrade the kernel, only userland diff --git a/doc/configuration.rst b/doc/configuration.rst index 4c45506..007489f 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -1,5 +1,5 @@ -Configuration and Module Guide -############################## +Configuration +############# Liminix uses the Nix language to provide congruent configuration management. This means that to change anything about the way in @@ -150,8 +150,7 @@ meaning that it won't be started until that other service is up. Module implementation ********************* -.. - TODO: make your own modules +TODO: make your own modules - * how a module exposes services - * defining types +* how a module exposes services +* defining types