tftpboot.nix (2177B)
1 { 2 config 3 , pkgs 4 , lib 5 , ... 6 }: 7 let 8 inherit (lib) mkOption types concatStringsSep; 9 cfg = config.boot.tftp; 10 in { 11 imports = [ ./ramdisk.nix ]; 12 options.boot.tftp.freeSpaceBytes = mkOption { 13 type = types.int; 14 default = 0; 15 }; 16 options.system.outputs = { 17 tftpboot = mkOption { 18 type = types.package; 19 description = '' 20 Directory containing files needed for TFTP booting 21 ''; 22 }; 23 boot-scr = mkOption { 24 type = types.package; 25 description = '' 26 U-Boot commands to load and boot a kernel and rootfs over TFTP. 27 Copy-paste into the device boot monitor 28 ''; 29 }; 30 }; 31 config = { 32 boot.ramdisk.enable = true; 33 34 system.outputs = rec { 35 tftpboot = 36 let o = config.system.outputs; in 37 pkgs.runCommand "tftpboot" {} '' 38 mkdir $out 39 cd $out 40 ln -s ${o.rootfs} rootfs 41 ln -s ${o.kernel} vmlinux 42 ln -s ${o.manifest} manifest 43 ln -s ${o.kernel.headers} build 44 ln -s ${o.uimage} uimage 45 ln -s ${o.boot-scr} boot.scr 46 ''; 47 48 boot-scr = 49 let 50 inherit (pkgs.lib.trivial) toHexString; 51 o = config.system.outputs; 52 in 53 pkgs.buildPackages.runCommand "boot-scr" {} '' 54 uimageSize=$(($(stat -L -c %s ${o.uimage}) + 0x1000 &(~0xfff))) 55 rootfsStart=0x$(printf %x $((${cfg.loadAddress} + 0x100000 + $uimageSize))) 56 rootfsBytes=$(($(stat -L -c %s ${o.rootfs}) + 0x100000 &(~0xfffff))) 57 rootfsBytes=$(($rootfsBytes + ${toString cfg.freeSpaceBytes} )) 58 cmd="mtdparts=phram0:''${rootfsMb}M(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsBytes},${config.hardware.flash.eraseBlockSize} memmap=''${rootfsBytes}\$''${rootfsStart} root=/dev/mtdblock0"; 59 60 cat > $out << EOF 61 setenv serverip ${cfg.serverip} 62 setenv ipaddr ${cfg.ipaddr} 63 setenv bootargs 'liminix $cmd' 64 tftp 0x$(printf %x ${cfg.loadAddress}) result/uimage ; tftp 0x$(printf %x $rootfsStart) result/rootfs 65 bootm 0x$(printf %x ${cfg.loadAddress}) 66 EOF 67 ''; 68 }; 69 }; 70 }