From 241f1013ed818ad212e0491b3c482ba7f6f442ba Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 11 Jul 2024 23:31:00 +0100 Subject: [PATCH] add new Installation guide move the u-boot/serial stuff here from development, as the reality of Liminix development in 2024 is that serial connection is still the smoothest installation method --- doc/admin.rst | 134 --------------------------------- doc/development.rst | 58 --------------- doc/index.rst | 1 + doc/installation.rst | 173 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 192 deletions(-) create mode 100644 doc/installation.rst diff --git a/doc/admin.rst b/doc/admin.rst index 6bb159a..ec8253a 100644 --- a/doc/admin.rst +++ b/doc/admin.rst @@ -116,140 +116,6 @@ human-readable format, use :command:`s6-tai64nlocal`. -Flashing and updating -********************* - - - -Flashing from Liminix -===================== - -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 -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 build the permanent -image and copy it to the device with :command:`ssh` - -.. code-block:: console - - build-machine$ nix-build -I liminix-config=./examples/arhcive.nix \ - --arg device "import ./devices/gl-ar750" - -A outputs.default && \ - (tar chf - result | ssh root@the-device tar -C /run -xvf -) - - 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 use U-Boot and a TFTP -server to download and flash the image. This is quite -hardware-specific, and sometimes involves soldering: please refer -to :ref:`serial`. - - -Flashing from OpenWrt -===================== - -.. CAUTION:: Untested! A previous version of these instructions - (without the -e flag) led to bricking the device - when flashing a jffs2 image. If you are reading - this message, nobody has yet reported on whether the - new instructions are any better. - -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 -e -r write /tmp/firmware.bin firmware - -The options to this command are for "erase before writing" and "reboot -after writing". - -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) ************************************ diff --git a/doc/development.rst b/doc/development.rst index dca89c5..c82373c 100644 --- a/doc/development.rst +++ b/doc/development.rst @@ -88,64 +88,6 @@ time with configurations for RP-PPPoE and/or Accel PPP.` Hardware devices **************** -.. _serial: - -U-Boot and serial shenanigans -============================= - -Every device that we have so far encountered in Liminix uses `U-Boot, -the "Universal Boot Loader" `_ so -it's worth knowing a bit about it. "Universal" is in this context a -bit of a misnomer, though: encountering *mainline* U-Boot is very rare -and often you'll find it is a fork from some version last updated -in 2008. Upgrading U-Boot is more or less complicated depending on the -device and is outside scope for Liminix. - -To speak to U-Boot on your device you'll usually need a serial -connection to it. This is device-specific. Usually it involves -opening the box, locating the serial header pins (TX, RX and GND) and -connecting a USB TTL converter to them. - -The Rolls Royce of USB/UART cables is the `FTDI cable -`_, -but there are cheaper alternatives based on the PL2303 and CP2102 chipsets. Or -get creative and use the `UART GPIO pins `_ on a Raspberry Pi. Whatever you do, make sure -that the voltages are compatible: if your device is 3.3V (this is -typical but not universal), you don't want to be sending it 5v or -(even worse) 12v. - -Run a terminal emulator such as Minicom on the computer at other end -of the link. 115200 8N1 is the typical speed. - -.. NOTE:: - - TTL serial connections typically have no form of flow control and - so don't always like having massive chunks of text pasted into - them - and U-Boot may drop characters while it's busy. So don't - necessarily expect to copy-paste large chunks of text into the - terminal emulator and have it work just like that. - - If using Minicom, you may find it helps to bring up the "Termimal - settings" dialog (C^A T), then configure "Newline tx delay" to - some small but non-zero value. - -When you turn the router on you should be greeted with some messages -from U-Boot, followed by the instruction to hit some key to stop -autoboot. Do this and you will get to the prompt. If you didn't see -anything, the strong likelihood is that TX and RX are the wrong way -around. If you see garbage, try a different speed. - -Interesting commands to try first in U-Boot are :command:`help` and -:command:`printenv`. - -To do anything useful with U-Boot you will probably need a way to get -large binary files onto the device, and the usual way to do this is by -adding a network connection and using TFTP to download them. It's -quite common that the device's U-Boot doesn't speak DHCP so it will -need a static LAN address. You might also want to keep it away from -your "real" LAN: see :ref:`bng` for some potentially useful tooling -to use it on an isolated network. - TFTP ==== diff --git a/doc/index.rst b/doc/index.rst index 9632bf6..d8199c8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -8,6 +8,7 @@ Liminix intro tutorial configuration + installation admin development modules diff --git a/doc/installation.rst b/doc/installation.rst new file mode 100644 index 0000000..4aaa8ff --- /dev/null +++ b/doc/installation.rst @@ -0,0 +1,173 @@ +Installation +############ + +Hardware devices vary wildly in their affordances for installing new +operating systems, so it should be no surprise that the Liminix +installation procedure is hardware-dependent. This section contains +generic instructions, but please refer to the documentation for your +device to find whether and how well they apply. + + + +Flashing from the boot monitor (TFTP install) +********************************************* + +If you are prepared to open the device and have a TTL serial adaptor +of some kind to connect it to, you can probably use U-Boot and a TFTP +server to download and flash the image. + +This is quite hardware-specific and may even involve soldering - see +the documention for your device. However, it is in some ways the most +"reliable" option: if you can see what's happening (or not happening) +in early boot, the risk of "bricking" is substantially reduced and you +have options for recovering if you misstep or flash a bad image. + + +.. _serial: + +U-Boot and serial shenanigans +============================= + +Every device that we have so far encountered in Liminix uses `U-Boot, +the "Universal Boot Loader" `_ so +it's worth knowing a bit about it. "Universal" is in this context a +bit of a misnomer, though: encountering *mainline* U-Boot is very rare +and often you'll find it is a fork from some version last updated +in 2008. Upgrading U-Boot is more or less complicated depending on the +device and is outside scope for Liminix. + +To speak to U-Boot on your device you'll usually need a serial +connection to it. This typically involves opening the box, locating +the serial header pins (TX, RX and GND) and connecting a USB TTL +converter to them. + +The Rolls Royce of USB/UART cables is the `FTDI cable +`_, +but there are cheaper alternatives based on the PL2303 and CP2102 chipsets - or you could even +get creative and use the `UART GPIO pins `_ on a Raspberry Pi. Whatever you do, make sure +that the voltages are compatible: if your device is 3.3V (this is +typical but not universal), you don't want to be sending it 5v or +(even worse) 12v. + +Run a terminal emulator such as Minicom on the computer at other end +of the link. 115200 8N1 is the typical speed. + +.. NOTE:: + + TTL serial connections often have no flow control and + so don't always like having massive chunks of text pasted into + them - and U-Boot may drop characters while it's busy. So don't + do that. + + If using Minicom, you may find it helps to bring up the "Termimal + settings" dialog (C^A T), then configure "Newline tx delay" to + some small but non-zero value. + +When you turn the router on you should be greeted with some messages +from U-Boot, followed by the instruction to hit some key to stop +autoboot. Do this and you will get to the prompt. If you didn't see +anything, the strong likelihood is that TX and RX are the wrong way +around. If you see garbage, try a different speed. + +Interesting commands to try first in U-Boot are :command:`help` and +:command:`printenv`. + +You will also need to configure a TFTP server on a network that's +accessible to the device: how you do that will vary according to which +TFTP server you're using and so is out of scope for this document. + + + +Buildiing and installing the image +================================== + +Follow the device-specific instructions for "TFTP install": usually, +the steps are + +* build the `outputs.mtdimage` output +* copy :file:`result/firmware.bin` to your TFTP server +* copy/paste the commands in :file:`result/flash.scr` one at a time into the U-Boot command line +* reset the device + +You should now see messages from U-Boot, then from the Linux kernel +and eventually a shell prompt. + +.. NOTE:: Before you reboot, check which networks the device is + plugged into, and disconnect as necessary. If you've just + installed a DHCP server or anything similar that responds to + broadcasts, you may not want it to do that on the network + that you temporarily connected it to for installing it. + + + +Flashing from OpenWrt +********************* + +.. CAUTION:: Untested! A previous version of these instructions + (without the -e flag) led to bricking the device + when flashing a jffs2 image. If you are reading + this message, nobody has yet reported on whether the + new instructions are any better. + +If your device is running OpenWrt then it probably has the +:command:`mtd` command installed. Build the `outputs.mtdimage` output +(as you would for a TFTP install) and then transfer +:file:`result/firmware.bin` onto the device using e.g. +:command:`scp`. Now flash as follows: + +.. code-block:: console + + mtd -e -r write /tmp/firmware.bin firmware + +The options to this command are for "erase before writing" and "reboot +after writing". + +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. + + +Flashing from Liminix +********************* + +If the device is already running Liminix and has been configured with +:command:`levitate`, you can use that to safely flash your new image. +Refer to :ref:`levitate` for an explanation. + +If the device is running Liminix but doesn't have :command:`levitate` +your options are more limited. You may attempt to use +:command:`flashcp` but it doesn't always work: as it copies the new +image over the top of the active root filesystem, surprise may ensue. +Consider instead using a serial connection: you may need one anyway +after trying flashcp if it corrupts the image. + +flashcp (not generally recommended) +=================================== + +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" + +Copy :file:`result/firmware.bin` to the device and now run (in this +example) + +.. code-block:: console + + flashcp -v firmware.bin /dev/mtd3 + +