commit 7cfb92e3ced96ca6d71768e616ca437fba421bcc
parent 22882dabee5e6ae75cf6b6b500e694a8185d9fd3
Author: Daniel Barlow <dan@telent.net>
Date: Fri, 10 Nov 2023 21:17:20 +0000
more doc
Diffstat:
15 files changed, 190 insertions(+), 146 deletions(-)
diff --git a/ci.nix b/ci.nix
@@ -42,6 +42,7 @@ let
installers = map (f: "system.outputs.${f}") [
"vmroot"
"flashimage"
+ "ubimage"
];
inherit (pkgs.lib) concatStringsSep;
in pkgs.stdenv.mkDerivation {
diff --git a/devices/belkin-rt3200/default.nix b/devices/belkin-rt3200/default.nix
@@ -1,4 +1,4 @@
-{
+rec {
description = ''
Belkin RT-3200 / Linksys E8450
******************************
@@ -17,6 +17,7 @@
- b/g/n wireless using MediaTek MT7622BV (MT7615E driver)
- a/n/ac/ax wireless using MediaTek MT7915E
'';
+ installer = "ubimage";
system = {
crossSystem = {
@@ -160,7 +161,7 @@
maxLEBcount = "1024"; # guessing
};
- defaultOutput = "ubimage";
+ defaultOutput = installer;
# 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-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";
@@ -54,6 +54,7 @@
OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-mt300a
'';
+ installer = "flashimage";
module = { pkgs, config, lib, ...}:
let
@@ -66,7 +67,7 @@
in {
imports = [ ../../modules/arch/mipsel.nix ];
hardware = {
- defaultOutput = "flashimage";
+ defaultOutput = installer;
loadAddress = "0x80000000";
entryPoint = "0x80000000";
diff --git 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,6 +23,7 @@
OpenWrt web page: https://openwrt.org/toh/gl.inet/gl-mt300n_v2
'';
+ installer = "flashimage";
module = { pkgs, config, lib, ...}:
let
@@ -49,7 +50,7 @@
};
};
hardware = {
- defaultOutput = "flashimage";
+ defaultOutput = installer;
loadAddress = "0x80000000";
entryPoint = "0x80000000";
diff --git a/devices/qemu-aarch64/default.nix b/devices/qemu-aarch64/default.nix
@@ -2,16 +2,29 @@
# 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";
};
};
- # this device is described by the "qemu" device
- description = "";
+ description = ''
+ QEMU Aarch64
+ ************
+
+ This target produces an image for
+ the `QEMU "virt" platform <https://www.qemu.org/docs/master/system/arm/virt.html>`_ using a 64 bit CPU type.
+
+ ARM targets differ from MIPS in that the kernel format expected
+ by QEMU is an "Image" (raw binary file) rather than an ELF
+ file, but this is taken care of by :command:`run.sh`. Check the
+ documentation for the :ref:`QEMU` (MIPS) target for more information.
+ '';
+
+ # this device is described by the "qemu" device
+ installer = "vmroot";
module = {pkgs, config, ... }: {
imports = [ ../../modules/arch/aarch64.nix ];
@@ -51,7 +64,7 @@
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
- defaultOutput = "vmroot";
+ defaultOutput = installer;
loadAddress = "0x0";
entryPoint = "0x0";
rootDevice = "/dev/mtdblock0";
diff --git 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";
@@ -10,7 +10,19 @@
};
# this device is described by the "qemu" device
- description = "";
+ description = ''
+ QEMU ARM v7
+ ***********
+
+ This target produces an image for
+ the `QEMU "virt" platform <https://www.qemu.org/docs/master/system/arm/virt.html>`_ using a 32 bit CPU type.
+
+ ARM targets differ from MIPS in that the kernel format expected
+ by QEMU is an "Image" (raw binary file) rather than an ELF
+ file, but this is taken care of by :command:`run.sh`. Check the
+ documentation for the :ref:`QEMU` (MIPS) target for more information.
+ '';
+ installer = "vmroot";
module = {pkgs, config, ... }: {
imports = [ ../../modules/arch/arm.nix ];
@@ -54,7 +66,7 @@
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
- defaultOutput = "vmroot";
+ defaultOutput = installer;
loadAddress = "0x00010000";
entryPoint = "0x00010000";
rootDevice = "/dev/mtdblock0";
diff --git a/devices/qemu/default.nix b/devices/qemu/default.nix
@@ -1,7 +1,4 @@
-# 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
-{
+rec {
system = {
crossSystem = {
config = "mips-unknown-linux-musl";
@@ -13,24 +10,21 @@
};
description = ''
- QEMU
- ****
+ QEMU MIPS
+ *********
- This is not a hardware device. This target produces an image for
+ This target produces an image for
QEMU, the "generic and open source machine emulator and
virtualizer".
- Liminix can build QEMU for both MIPS (:code:`qemu` device) and Aarch64 (:code:`qemu-aarch64` device)
-
MIPS QEMU emulates a "Malta" board, which was an ATX form factor
evaluation board made by MIPS Technologies, but mostly in Liminix
we use paravirtualized devices (Virtio) instead of emulating
- hardware. For Aarch64 we use the QEMU "virt" board.
+ hardware.
Building an image for QEMU results in a :file:`result/` directory
- containing ``run.sh`` ``vmlinux``, ``rootfs`` and possibly
- (architecture-dependent) ``Image``. To invoke the emulator,
- run ``run.sh``.
+ containing ``run.sh`` ``vmlinux``, and ``rootfs`` files. To invoke
+ the emulator, run ``run.sh``.
The configuration includes two emulated "hardware" ethernet
devices and the kernel :code:`mac80211_hwsim` module to
@@ -39,6 +33,8 @@
in the Development manual.
'';
+ installer = "vmroot";
+
module = {pkgs, config, ... }: {
imports = [ ../../modules/arch/mipseb.nix ];
kernel = {
@@ -74,7 +70,7 @@
klibBuild = config.system.outputs.kernel.modulesupport;
};
in {
- defaultOutput = "vmroot";
+ defaultOutput = installer;
rootDevice = "/dev/mtdblock0";
flash.eraseBlockSize = "65536"; # c.f. pkgs/run-liminix-vm/run-liminix-vm.sh
networkInterfaces =
diff --git a/doc/development.rst b/doc/development.rst
@@ -56,6 +56,8 @@ Any VM started by a :command:`run.sh` script is connected to "lan" and
"access", and the emulated border network gateway (see below) runs
PPPoE and is connected to "access" and "world".
+.. _border-network-gateway:
+
Border Network Gateway
----------------------
diff --git a/doc/hardware.nix b/doc/hardware.nix
@@ -1,15 +1,15 @@
with import <nixpkgs> {} ;
let
- devices =
- builtins.readDir ../devices;
+ devices = builtins.readDir ../devices;
+ inherit (builtins) stringLength;
texts = lib.mapAttrsToList (n: t:
let d = import ../devices/${n}/default.nix;
d' = {
- description = "no description for ${n}";
+ description = "${n}\n${substring 0 (stringLength n) "********************************"}\n";
} // d;
installer =
- if d ? installer
+ if d ? description && d ? installer
then ''
The default installation route for this device is
diff --git a/modules/all-modules.nix b/modules/all-modules.nix
@@ -11,7 +11,6 @@
./dnsmasq
./ext4fs.nix
./firewall
- ./flashimage.nix
./hardware.nix
./hostapd
./hostname.nix
@@ -24,6 +23,8 @@
./ntp
./outputs.nix
./outputs/vmroot.nix
+ ./outputs/ubimage.nix
+ ./outputs/flashimage.nix
./ppp
./ramdisk.nix
./squashfs.nix
@@ -31,7 +32,6 @@
./standard.nix
./tftpboot.nix
./ubifs.nix
- ./ubimage.nix
./users.nix
./vlan
./watchdog
diff --git a/modules/outputs.nix b/modules/outputs.nix
@@ -12,6 +12,8 @@ in
imports = [
./squashfs.nix
./outputs/vmroot.nix
+ ./outputs/flashimage.nix
+ ./outputs/ubimage.nix
];
options = {
system.outputs = {
diff --git a/modules/flashimage.nix b/modules/outputs/flashimage.nix
diff --git a/modules/outputs/ubimage.nix b/modules/outputs/ubimage.nix
@@ -0,0 +1,127 @@
+{
+ config
+, pkgs
+, lib
+, ...
+}:
+let
+ inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep;
+ cfg = config.boot.tftp;
+ instructions = pkgs.writeText "env.scr" ''
+ setenv serverip ${cfg.serverip}
+ setenv ipaddr ${cfg.ipaddr}
+ setenv loadaddr ${cfg.loadAddress}
+'';
+in {
+ options.system.outputs = {
+ ubimage = mkOption {
+ type = types.package;
+ description = ''
+ubimage
+*******
+
+First-time installation of a UBIFS Liminix system presently can only
+be done from the U-Boot command line (or from a ramdisk-based recovery
+system: see "kexecboot" but we don't have detailed instructions for
+this process yet).
+
+These steps were tested on a Belkin RT3200 (also known as Linksys
+E8450). Other devices may be set up differently, so use them as
+inspiration and don't just paste them blindly. Consult the Liminix
+manual for how to connect a serial cable to your device and get into
+U-Boot
+
+1) determine which MTD device is being used for UBI and the partition name:
+
+.. code-block:: console
+
+ uboot> ubi part
+ Device 0: ubi0, MTD partition ubi
+
+In this case the important value is ``ubi0``
+
+2) list the available volumes and create a new one on which to install Liminix
+
+.. code-block:: console
+
+ uboot> ubi info l
+ [ copious output scrolls past ]
+
+Expect there to be existing volumes and for some or all of them to be
+important. Unless you know what you're doing, don't remove anything
+whose name suggests it's related to uboot, or any kind of backup or
+recovery partition. To see how much space is free:
+
+.. code-block:: console
+
+ uboot> ubi info
+ [ ... ]
+ UBI: available PEBs: 823
+
+Now we can make our new root volume
+
+.. code-block:: console
+
+ uboot> ubi create liminix -
+
+3) transfer the root filesystem from the build system and write it
+to the new volume. Paste the environment variable settings from
+:file:`result/env.scr` into U-Boot, then run
+
+.. code-block:: console
+
+ uboot> tftpboot ''${loadaddr} result/rootfs
+ uboot> ubi write ''${loadaddr} liminix $filesize
+
+Now we have the root filesystem installed on the device. You
+can even mount it and poke around using ``ubifsmount ubi0:liminix;
+ubifsls /``
+
+4) optional: before you configure the device to boot into Liminix
+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> 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.
+
+5) Instructions for configuring autoboot are likely to be very
+device-dependent. On the Linksys E8450/Belkin RT3200, the environment
+variable `boot_production` governs what happens on a normal boot, so
+you could do
+
+.. code-block:: console
+
+ uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix; ubifsload ''${loadaddr} boot/uimage; bootm ''${loadaddr}'
+
+On other devices, some detective work may be needed. Try running
+`printenv` and look for likely commands, try looking at the existing
+boot process, maybe even try looking for documentation for that device.
+
+6) Now you can reboot the device into Liminix
+
+.. code-block:: console
+
+ uboot> reset
+ '';
+ };
+ };
+
+ 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
+ '';
+ };
+ };
+}
diff --git a/modules/standard.nix b/modules/standard.nix
@@ -5,7 +5,7 @@
imports = [
./tftpboot.nix
./kexecboot.nix
- ./flashimage.nix
+ ./outputs/flashimage.nix
./jffs2.nix
./ubifs.nix
];
diff --git a/modules/ubimage.nix b/modules/ubimage.nix
@@ -1,112 +0,0 @@
-{
- config
-, pkgs
-, lib
-, ...
-}:
-let
- inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep;
- loadaddr = config.boot.tftp.loadAddress;
- cfg = config.boot.tftp;
- instructions = pkgs.writeText "INSTALL.md" ''
-
-# First-time installation
-
-First-time installation of a UBIFS Liminix system presently can only
-be done from the U-Boot command line (or from a ramdisk-based recovery
-system: see "kexecboot" but we don't have detailed instructions for
-this process yet).
-
-These steps were tested on a Belkin RT3200 (also known as Linksys
-E8450). Other devices may be set up differently, so use them as
-inspiration and don't just paste them blindly. Consult the Liminix
-manual for how to connect a serial cable to your device and get into
-U-Boot
-
-1) determine which MTD device is being used for UBI and the partition name:
-
- uboot> ubi part
- Device 0: ubi0, MTD partition ubi
-
-In this case the important value is `ubi0`
-
-2) list the available volumes and create a new one on which to install Liminix
-
- uboot> ubi info l
- [ copious output scrolls past ]
-
-Expect there to be existing volumes and for some or all of them to be
-important. Unless you know what you're doing, don't remove anything
-whose name suggests it's related to uboot, or any kind of backup or
-recovery partition. To see how much space is free:
-
- uboot> ubi info
- [ ... ]
- UBI: available PEBs: 823
-
-Now we can make our new root volume
-
- uboot> ubi create liminix -
-
-3) transfer the root filesystem from the build system and write it
-to the new volume
-
- uboot> setenv serverip ${cfg.serverip}
- uboot> setenv ipaddr ${cfg.ipaddr}
- uboot> tftpboot ${loadaddr} result/rootfs
- uboot> ubi write ${loadaddr} liminix $filesize
-
-Now we have the root filesystem installed on the device. You
-can even mount it and poke around using `ubifsmount ubi0:liminix;
-ubifsls /`
-
-4) optional: before you configure the device to boot into Liminix
-automatically, you can try booting it by hand to see if it works:
-
- uboot> ubifsmount ubi0:liminix
- uboot> ubifsload ${loadaddr} boot/uimage
- 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.
-
-5) Instructions for configuring autoboot are likely to be very
-device-dependent. On the Linksys E8450/Belkin RT3200, the environment
-variable `boot_production` governs what happens on a normal boot, so
-you could do
-
- uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix; ubifsload ${loadaddr} boot/uimage; bootm ${loadaddr}'
-
-On other devices, some detective work may be needed. Try running
-`printenv` and look for likely commands, try looking at the existing
-boot process, maybe even try looking for documentation for that device.
-
-6) Now you can reboot the device into Liminix
-
- uboot> reset
-
-'';
-in {
- options.system.outputs = {
- ubimage = mkOption {
- type = types.package;
- description = ''
- UBIFS image and instructions to install it
- '';
- };
- };
-
- 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} INSTALL
- '';
- };
- };
-}