diff --git a/ci.nix b/ci.nix index c0f91c3..8e940f8 100644 --- a/ci.nix +++ b/ci.nix @@ -53,7 +53,7 @@ let src = ./.; buildPhase = '' cat ${json} | fennel --correlate doc/parse-options.fnl > doc/modules-generated.rst - cat ${json} | fennel --correlate doc/parse-options-outputs.fnl ${concatStringsSep " " installers} > doc/installers-generated.rst + cat ${json} | fennel --correlate doc/parse-options-outputs.fnl > doc/outputs-generated.rst cp ${(import ./doc/hardware.nix)} doc/hardware.rst make -C doc html ''; diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix index 069a78b..0e8197e 100644 --- a/devices/belkin-rt3200/default.nix +++ b/devices/belkin-rt3200/default.nix @@ -1,4 +1,4 @@ -rec { +{ description = '' Belkin RT-3200 / Linksys E8450 ****************************** @@ -17,7 +17,6 @@ rec { - b/g/n wireless using MediaTek MT7622BV (MT7615E driver) - a/n/ac/ax wireless using MediaTek MT7915E ''; - installer = "ubimage"; system = { crossSystem = { @@ -161,7 +160,7 @@ rec { maxLEBcount = "1024"; # guessing }; - defaultOutput = installer; + defaultOutput = "ubimage"; # the kernel expects this to be on a 2MB boundary. U-Boot # (I don't know why) has a default of 0x41080000, which isn't. # We put it at the 32MB mark so that tftpboot can put its rootfs diff --git a/devices/gl-ar750/default.nix b/devices/gl-ar750/default.nix index c18e512..f997097 100644 --- a/devices/gl-ar750/default.nix +++ b/devices/gl-ar750/default.nix @@ -1,11 +1,3 @@ - -# I like GL.iNet devices because they're relatively accessible to -# DIY users: the serial port connections have headers preinstalled -# and don't need soldering - -# 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 - rec { system = { crossSystem = { diff --git a/devices/gl-mt300a/default.nix b/devices/gl-mt300a/default.nix index c45d394..1286940 100644 --- a/devices/gl-mt300a/default.nix +++ b/devices/gl-mt300a/default.nix @@ -1,6 +1,6 @@ # GL.iNet GL-MT300A -rec { +{ system = { crossSystem = { config = "mipsel-unknown-linux-musl"; @@ -13,34 +13,11 @@ rec { description = '' GL.iNet GL-MT300A - ******************** + ***************** The GL-MT300A is based on a MT7620 chipset. - The GL.iNet pocket router range makes nice cheap hardware for - playing with Liminix or similar projects. The manufacturers seem - open to the DIY market, and the devices have a reasonable amount - of RAM and are much easier to get serial connections than many - COTS routers. - - Wire up the serial connection: this probably involves opening - the box, locating the serial header pins (TX, RX and GND) and - connecting a USB TTL converter - e.g. a PL2303 based device - to - it. The defunct OpenWRT wiki has a guide with some pictures. (If - you don't have a USB TTL converter to hand, other options are - available. For example, use the GPIO pins on a Raspberry Pi.) - - Run a terminal emulator such as Minicom on whatever is on the - other end of the link. I use 115200 8N1 and find it also helps - to set "Line tx delay" to 1ms, "backspace sends DEL" and - "lineWrap on". - - When you turn the router on you should be greeted with some - messages from U-Boot and a little bit of ASCII art, followed by - the instruction to hit SPACE to stop autoboot. Do this and you - will get a gl-mt300a> prompt. - - For flashing from uboot, the firmware partition is from + For flashing from U-Boot, the firmware partition is from 0xbc050000 to 0xbcfd0000. WiFi on this device is provided by the rt2800soc module. It @@ -54,7 +31,6 @@ rec { OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-mt300a ''; - installer = "flashimage"; module = { pkgs, config, lib, ...}: let @@ -67,7 +43,7 @@ rec { in { imports = [ ../../modules/arch/mipsel.nix ]; hardware = { - defaultOutput = installer; + defaultOutput = "flashimage"; loadAddress = "0x80000000"; entryPoint = "0x80000000"; diff --git a/devices/gl-mt300n-v2/default.nix b/devices/gl-mt300n-v2/default.nix index 8f7a966..0198b6c 100644 --- a/devices/gl-mt300n-v2/default.nix +++ b/devices/gl-mt300n-v2/default.nix @@ -1,4 +1,4 @@ -rec { +{ system = { crossSystem = { config = "mipsel-unknown-linux-musl"; @@ -23,7 +23,6 @@ rec { OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-mt300n_v2 ''; - installer = "flashimage"; module = { pkgs, config, lib, ...}: let @@ -50,7 +49,7 @@ rec { }; }; hardware = { - defaultOutput = installer; + defaultOutput = "flashimage"; loadAddress = "0x80000000"; entryPoint = "0x80000000"; diff --git a/devices/qemu-aarch64/default.nix b/devices/qemu-aarch64/default.nix index 28f3477..f04f274 100644 --- a/devices/qemu-aarch64/default.nix +++ b/devices/qemu-aarch64/default.nix @@ -2,7 +2,7 @@ # emulator. The default output is a directory containing separate # kernel ("Image" format) and root filesystem (squashfs or jffs2) # images -rec { +{ system = { crossSystem = { config = "aarch64-unknown-linux-musl"; @@ -64,7 +64,7 @@ rec { klibBuild = config.system.outputs.kernel.modulesupport; }; in { - defaultOutput = installer; + defaultOutput = "vmroot"; loadAddress = "0x0"; entryPoint = "0x0"; rootDevice = "/dev/mtdblock0"; diff --git a/devices/qemu-armv7l/default.nix b/devices/qemu-armv7l/default.nix index 3c73e54..97747c9 100644 --- a/devices/qemu-armv7l/default.nix +++ b/devices/qemu-armv7l/default.nix @@ -2,7 +2,7 @@ # emulator. The default output is a directory containing separate # kernel ("Image" format) and root filesystem (squashfs or jffs2) # images -rec { +{ system = { crossSystem = { config = "armv7l-unknown-linux-musleabihf"; @@ -66,7 +66,7 @@ rec { klibBuild = config.system.outputs.kernel.modulesupport; }; in { - defaultOutput = installer; + defaultOutput = "vmroot"; loadAddress = "0x00010000"; entryPoint = "0x00010000"; rootDevice = "/dev/mtdblock0"; diff --git a/devices/qemu/default.nix b/devices/qemu/default.nix index 5582674..b5a2755 100644 --- a/devices/qemu/default.nix +++ b/devices/qemu/default.nix @@ -1,4 +1,7 @@ -rec { +# This "device" generates images that can be used with the QEMU +# emulator. The default output is a directory containing separate +# kernel (uncompressed vmlinux) and initrd (squashfs) images +{ system = { crossSystem = { config = "mips-unknown-linux-musl"; @@ -33,8 +36,6 @@ rec { in the Development manual. ''; - installer = "vmroot"; - module = {pkgs, config, ... }: { imports = [ ../../modules/arch/mipseb.nix ]; kernel = { @@ -70,7 +71,7 @@ rec { klibBuild = config.system.outputs.kernel.modulesupport; }; in { - defaultOutput = installer; + defaultOutput = "vmroot"; rootDevice = "/dev/mtdblock0"; flash.eraseBlockSize = "65536"; # c.f. pkgs/run-liminix-vm/run-liminix-vm.sh networkInterfaces = diff --git a/doc/admin.rst b/doc/admin.rst index efd72c1..49fb11d 100644 --- a/doc/admin.rst +++ b/doc/admin.rst @@ -117,7 +117,7 @@ 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 the :ref:`development manual `. +to :ref:`serial`. Flashing from OpenWrt diff --git a/doc/development.rst b/doc/development.rst index 8acfeec..7969817 100644 --- a/doc/development.rst +++ b/doc/development.rst @@ -88,6 +88,68 @@ 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 +==== + .. _tftp server: How you get your image onto hardware will vary according to the @@ -151,6 +213,8 @@ U-Boot to transfer the kernel and filesystem over TFTP and boot the kernel from RAM. +.. _bng: + Networking ========== diff --git a/doc/installers.rst b/doc/installers.rst deleted file mode 100644 index 5b8f548..0000000 --- a/doc/installers.rst +++ /dev/null @@ -1,8 +0,0 @@ -Installers -########## - -There are a number of different routes to getting -Liminix onto devices, and which one you should use -(or are able to use) varies according to the device. - -.. include:: installers-generated.rst diff --git a/doc/outputs.rst b/doc/outputs.rst new file mode 100644 index 0000000..e0e8d30 --- /dev/null +++ b/doc/outputs.rst @@ -0,0 +1,13 @@ +Outputs +####### + +Liminix *outputs* are artefacts that can be installed or run somehow +on a target device, or "installers" which run on a target device +to perform the installation. + +There are different outputs because different target devices need +different artefacts or have different ways to get that artefact +installed. The options available for a particular device are described in +the section for that device. + +.. include:: outputs-generated.rst diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 2cf438b..ade81f8 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -137,20 +137,12 @@ unbrick if necessary. work here, but you accept the slightly greater bricking risk if it doesn't. -You may want to acquire a `USB TTL serial cable -`_ -when you start working with Liminix on real hardware. You -won't *need* it for this example, assuming it works, but it +You may want to read and inwardly digest the Develoment Manual section +:ref:`serial` when you start working with Liminix on real hardware. You +won't *need* serial access for this example, assuming it works, but it allows you to see the boot monitor and kernel messages, and to login directly to -the device if for some reason it doesn't bring its network up. You have options -here: the FTDI-based cables are the Rolls Royce of serial cables, -whereas the ones based on PL2303 and CP2102 chipsets are cheaper but -also fussier - or you could even get creative and use e.g. a -`Raspberry Pi `_ or other SBC with a UART and -TX/RX/GND header pins. Make sure that the voltages are compatible: -this is a 3.3v device and you don't want to be sending it 5v or (even -worse) 12v. +the device if for some reason it doesn't bring its network up. Now we can build Liminix. Although we could use the same example configuration as we did for Qemu, you might not want to plug a DHCP