f61e737b54
Changed my mind about "installer" as a first-class concept, at least in the current implementation. Not every documented output is an installer
126 lines
3.5 KiB
Nix
126 lines
3.5 KiB
Nix
{
|
|
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
|
|
*******
|
|
|
|
This output provides a UBIFS filesystem image and a small U-Boot script
|
|
to make the manual installation process very slightly simpler. You will
|
|
need a serial connection and a network connection to a TFTP server
|
|
containing the filesystem image it creates.
|
|
|
|
.. warning:: 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.
|
|
|
|
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
|
|
'';
|
|
};
|
|
};
|
|
}
|