ubimage.nix (3620B)
1 { 2 config 3 , pkgs 4 , lib 5 , ... 6 }: 7 let 8 inherit (lib) mkIf mkEnableOption mkOption types concatStringsSep; 9 cfg = config.boot.tftp; 10 instructions = pkgs.writeText "env.scr" '' 11 setenv serverip ${cfg.serverip} 12 setenv ipaddr ${cfg.ipaddr} 13 setenv loadaddr ${lib.toHexString cfg.loadAddress} 14 ''; 15 in { 16 options.system.outputs = { 17 ubimage = mkOption { 18 type = types.package; 19 description = '' 20 ubimage 21 ******* 22 23 This output provides a UBIFS filesystem image and a small U-Boot script 24 to make the manual installation process very slightly simpler. You will 25 need a serial connection and a network connection to a TFTP server 26 containing the filesystem image it creates. 27 28 .. warning:: These steps were tested on a Belkin RT3200 (also known as 29 Linksys E8450). Other devices may be set up differently, 30 so use them as inspiration and don't just paste them 31 blindly. 32 33 1) determine which MTD device is being used for UBI, and the partition name: 34 35 .. code-block:: console 36 37 uboot> ubi part 38 Device 0: ubi0, MTD partition ubi 39 40 In this case the important value is ``ubi0`` 41 42 2) list the available volumes and create a new one on which to install Liminix 43 44 .. code-block:: console 45 46 uboot> ubi info l 47 [ copious output scrolls past ] 48 49 Expect there to be existing volumes and for some or all of them to be 50 important. Unless you know what you're doing, don't remove anything 51 whose name suggests it's related to uboot, or any kind of backup or 52 recovery partition. To see how much space is free: 53 54 .. code-block:: console 55 56 uboot> ubi info 57 [ ... ] 58 UBI: available PEBs: 823 59 60 Now we can make our new root volume 61 62 .. code-block:: console 63 64 uboot> ubi create liminix - 65 66 3) transfer the root filesystem from the build system and write it 67 to the new volume. Paste the environment variable settings from 68 :file:`result/env.scr` into U-Boot, then run 69 70 .. code-block:: console 71 72 uboot> tftpboot ''${loadaddr} result/rootfs 73 uboot> ubi write ''${loadaddr} liminix $filesize 74 75 Now we have the root filesystem installed on the device. You 76 can even mount it and poke around using ``ubifsmount ubi0:liminix; 77 ubifsls /`` 78 79 4) optional: before you configure the device to boot into Liminix 80 automatically, you can try booting it by hand to see if it works: 81 82 .. code-block:: console 83 84 uboot> ubifsmount ubi0:liminix 85 uboot> ubifsload ''${loadaddr} boot/uimage 86 uboot> bootm ''${loadaddr} 87 88 Once you've done this and you're happy with it, reset the device to 89 U-Boot. You don't need to recreate the volume but you do need to 90 repeat step 3. 91 92 5) Instructions for configuring autoboot are likely to be very 93 device-dependent. On the Linksys E8450/Belkin RT3200, the environment 94 variable `boot_production` governs what happens on a normal boot, so 95 you could do 96 97 .. code-block:: console 98 99 uboot> setenv boot_production 'led $bootled_pwr on ; ubifsmount ubi0:liminix; ubifsload ''${loadaddr} boot/uimage; bootm ''${loadaddr}' 100 101 On other devices, some detective work may be needed. Try running 102 `printenv` and look for likely commands, try looking at the existing 103 boot process, maybe even try looking for documentation for that device. 104 105 6) Now you can reboot the device into Liminix 106 107 .. code-block:: console 108 109 uboot> reset 110 ''; 111 }; 112 }; 113 114 config = mkIf (config.rootfsType == "ubifs") { 115 system.outputs = { 116 ubimage = 117 let o = config.system.outputs; in 118 pkgs.runCommand "ubimage" {} '' 119 mkdir $out 120 cd $out 121 ln -s ${o.rootfs} rootfs 122 ln -s ${instructions} env.scr 123 ''; 124 }; 125 }; 126 }