user.rst (11468B)
1 User Manual 2 ########### 3 4 This manual is an early work in progress, not least because Liminix is 5 not yet really ready for users who are not also developers. Your 6 feedback to improve it is very welcome. 7 8 Installation 9 ************ 10 11 The Liminix installation process is not quite like installing NixOS on 12 a real computer, but some NixOS experience will nevertheless be 13 helpful in understanding it. The steps are as follows: 14 15 * Decide whether you want the device to be updatable in-place (there 16 are advantages and disadvantages), or if you are happy to generate 17 and flash a new image whenever changes are required. 18 19 * Create a :file:`configuration.nix` describing the system you want 20 21 * Build an image 22 23 * Flash it to the device 24 25 Supported devices 26 ================= 27 28 For a list of devices that Liminix (present or previous versions) 29 has run on, refer to `devices/ in the source repo <https://gti.telent.net/dan/liminix/src/branch/main/devices>`_. For devices that _currently_ build, 30 cross-reference it with `the CI status <https://build.liminix.org/jobset/liminix/build#tabs-jobs>`_. Everything that builds is (usually) expected 31 to run, so if you end up with an image that builds but doesn't 32 boot, please report it as a bug. 33 34 As of June 2023 the device list is a little thin. Adding devices based 35 on the Atheros or Mediatek (Ralink) platform should be quite 36 straightforward if you have some C/Linux kernel experience and are 37 prepared to open it up and attach serial wires: please refer to the 38 Developer Manual. 39 40 41 Choosing a flavour (read-only or updatable) 42 =========================================== 43 44 Liminix installations come in two "flavours"- read-only or in-place 45 updatable: 46 47 * a read-only installation can't be updated once it is flashed to your 48 device, and so must be reinstalled in its entirety every time you 49 want to change it. It uses the ``squashfs`` filesystem which has 50 very good compression ratios and so you can pack quite a lot of 51 useful stuff onto your device. This is good if you don't expect 52 to change it often. 53 54 * an updatable installation has a writable filesystem so that you can 55 update configuration, upgrade packages and install new packages over 56 the network after installation. This uses the `jffs2 57 <http://www.linux-mtd.infradead.org/doc/jffs2.html>`_ filesystem: 58 although it does compress the data, the need to support writes means 59 that it can't pack quite as small as squashfs, so you will not have 60 as much space to play with. 61 62 Updatability caveats 63 ~~~~~~~~~~~~~~~~~~~~ 64 65 At the time of writing this manual the read-only squashfs support is 66 much more mature. Consider also that it may not be possible to perform 67 "larger" updates in-place even if you do opt for updatability. If you 68 have (for example) an 11MB system on a 16MB device, you won't be able 69 to do an in-place update of something fundamental like the C library 70 (libc), as this will temporarily require 22MB to install all the 71 packages needing the new library before the packages using the old 72 library can be removed. A writable system will be more useful for 73 smaller updates such as installing a new package (perhaps you 74 temporarily need tcpdump to diagnose a network problem) or for 75 changing configuration files. 76 77 Note also that the kernel is not part of the filesystem so cannot be 78 updated this way. Kernel changes require a full reflash. 79 80 81 82 Creating configuration.nix 83 ========================== 84 85 86 You need to create a :file:`configuration.nix` that describes your device 87 and the services that you want to run on it. Start by copying 88 :file:`vanilla-configuration.nix` and adjusting it, or look in the `examples` 89 directory for some pre-written configurations. 90 91 :file:`configuration.nix` conventionally describes the packages, services, 92 user accounts etc of the device. It does not describe the hardware 93 itself, which is specified separately in the build command (as you 94 will see below). 95 96 Your configuration may include modules: it probably *should* 97 include the ``standard`` module unless you understand what it 98 does and what happens if you leave it out. 99 100 .. code-block:: nix 101 102 imports = [ 103 ./modules/standard.nix 104 ] 105 configuration.rootfsType = "jffs2"; # or "squashfs" 106 107 108 109 Building 110 ======== 111 112 Build Liminix using the :file:`default.nix` in the project toplevel 113 directory, passing it arguments for configuration and hardware. For 114 example: 115 116 .. code-block:: console 117 118 nix-build -I liminix-config=./tests/smoke/configuration.nix \ 119 --arg device "import ./devices/qemu" -A outputs.default 120 121 In this command ``<liminix-config>`` points to your 122 :file:`configuration.nix`, ``device`` is the file for your hardware device 123 definition, and ``outputs.default`` will generate some kind of 124 Liminix image output appropriate to that device. 125 126 For the qemu device in this example, ``outputs.default`` is an alias 127 for ``outputs.vmbuild``, which creates a directory containing a 128 squashfs root image and a kernel. You can use the :command:`mips-vm` command to 129 run this. 130 131 For the currently supported hardware devices, ``outputs.default`` 132 creates a directory containing a file called ``firmware.bin``. This 133 is a raw image file that can be written directly to the firmware flash 134 partition. 135 136 137 Flashing 138 ======== 139 140 141 Flashing from the boot monitor 142 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 144 If you are prepared to open the device and have a TTL serial adaptor 145 of some kind to connect it to, you can probably flash it using U-Boot. 146 This is quite hardware-specific, and sometimes involves soldering: 147 please refer to the Developer Manual. 148 149 150 Flashing from an existing Liminix system with :command:`flashcp` 151 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 152 153 The flash procedure from an existing Liminix-system is two-step. 154 First we reboot the device (using "kexec") into an "ephemeral" 155 RAM-based version of the new configuration, then when we're happy it 156 works we can flash the image - and if it doesn't work we can reboot 157 the device again and it will boot from the old image. 158 159 160 161 Building the RAM-based image 162 ............................ 163 164 To create the ephemeral image, build ``outputs.kexecboot`` instead of 165 ``outputs.default``. This generates a directory containing the root 166 filesystem image and kernel, along with an executable called `kexec` 167 and a `boot.sh` script that runs it with appropriate arguments. 168 169 For example 170 171 .. code-block:: console 172 173 nix-build --show-trace -I liminix-config=./examples/arhcive.nix \ 174 --arg device "import ./devices/gl-ar750" 175 -A outputs.kexecboot && \ 176 (tar chf - result | ssh root@the-device tar -C /run -xvf -) 177 178 and then login to the device and run 179 180 .. code-block:: console 181 182 cd /run/result 183 sh ./boot.sh . 184 185 186 This will load the new kernel and map the root filesystem into a RAM 187 disk, then start executing the new kernel. *This is effectively a 188 reboot - be sure to close all open files and finish anything else 189 you were doing first.* 190 191 If the new system crashes or is rebooted, then the device will revert 192 to the old configuration it finds in flash. 193 194 195 Building the second (permanent) image 196 ..................................... 197 198 While running in the kexecboot system, you can copy the permanent 199 image to the device with :command:`ssh` 200 201 .. code-block:: console 202 203 build-machine$ tar chf - result/firmware.bin | \ 204 ssh root@the-device tar -C /run -xvf - 205 206 Next you need to connect to the device and locate the "firmware" 207 partition, which you can do with a combination of :command:`dmesg` 208 output and the contents of :file:`/proc/mtd` 209 210 .. code-block:: console 211 212 <5>[ 0.469841] Creating 4 MTD partitions on "spi0.0": 213 <5>[ 0.474837] 0x000000000000-0x000000040000 : "u-boot" 214 <5>[ 0.480796] 0x000000040000-0x000000050000 : "u-boot-env" 215 <5>[ 0.487056] 0x000000050000-0x000000060000 : "art" 216 <5>[ 0.492753] 0x000000060000-0x000001000000 : "firmware" 217 218 # cat /proc/mtd 219 dev: size erasesize name 220 mtd0: 00040000 00001000 "u-boot" 221 mtd1: 00010000 00001000 "u-boot-env" 222 mtd2: 00010000 00001000 "art" 223 mtd3: 00fa0000 00001000 "firmware" 224 mtd4: 002a0000 00001000 "kernel" 225 mtd5: 00d00000 00001000 "rootfs" 226 227 Now run (in this example) 228 229 .. code-block:: console 230 231 flashcp -v firmware.bin /dev/mtd3 232 233 234 "I know my new image is good, can I skip the intemediate step?" 235 ``````````````````````````````````````````````````````````````` 236 237 In addition to giving you a chance to see if the new image works, this 238 two-step process ensures that you're not copying the new image over 239 the top of the active root filesystem. It might work, or it might 240 crash in surprising ways. 241 242 243 244 Flashing from OpenWrt (not currently advised!) 245 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 246 247 .. CAUTION:: At your own risk! This will (at least in some 248 circumstances) lead to bricking the device: we think this 249 flash method is currently incompatible with use of a 250 writeable (jffs2) filesystem. 251 252 If your device is running OpenWrt then it probably has the 253 :command:`mtd` command installed. After transferring the image onto the 254 device using e.g. :command:`ssh`, you can run it as follows: 255 256 .. code-block:: console 257 258 mtd -r write /tmp/firmware.bin firmware 259 260 For more information, please see the `OpenWrt manual <https://openwrt.org/docs/guide-user/installation/sysupgrade.cli>`_ which may also contain (hardware-dependent) instructions on how to flash an image using the vendor firmware - perhaps even from a web interface. 261 262 263 Updating an installed system (JFFS2) 264 ************************************ 265 266 Adding packages 267 =============== 268 269 270 If your device is running a JFFS2 root filesystem, you can build 271 extra packages for it on your build system and copy them to the 272 device: any package in Nixpkgs or in the Liminix overlay is available 273 with the ``pkgs`` prefix: 274 275 .. code-block:: console 276 277 nix-build -I liminix-config=./my-configuration.nix \ 278 --arg device "import ./devices/mydevice" -A pkgs.tcpdump 279 280 nix-shell -p min-copy-closure root@the-device result/ 281 282 Note that this only copies the package to the device: it doesn't update 283 any profile to add it to ``$PATH`` 284 285 286 Rebuilding the system 287 ===================== 288 289 :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: 290 291 .. code-block:: console 292 293 liminix-rebuild root@the-device -I liminix-config=./examples/rotuer.nix --arg device "import ./devices/gl-ar750" 294 295 This will 296 297 * build anything that needs building 298 * copy new or changed packages to the device 299 * reboot the device 300 301 It doesn't delete old packages automatically: to do that run 302 :command:`min-collect-garbage`, which will delete any packages not in 303 the current system closure. Note that Liminix does not have the NixOS 304 concept of environments or generations, and there is no way back from 305 this except for building the previous configuration again. 306 307 308 309 Caveats 310 ~~~~~~~ 311 312 * it needs there to be enough free space on the device for all the new 313 packages in addition to all the packages already on it - which may be 314 a problem if a lot of things have changed (e.g. a new version of 315 nixpkgs). 316 317 * it cannot upgrade the kernel, only userland 318 319 Configuration options 320 ********************* 321 322 .. include:: modules.rst