liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

mtdimage.nix (3984B)


      1 {
      2   config,
      3   pkgs,
      4   lib,
      5   ...
      6 }:
      7 let
      8   inherit (lib) mkOption types concatStringsSep;
      9   inherit (config.boot) tftp;
     10 in
     11 {
     12   options.system.outputs = {
     13     firmware = mkOption {
     14       type = types.package;
     15       internal = true; # component of mtdimage
     16       description = ''
     17         Binary image (combining kernel, FDT, rootfs, initramfs
     18         if needed, etc) for the target device.
     19       '';
     20     };
     21     flash-scr = mkOption {
     22       type = types.package;
     23       internal = true; # component of mtdimage
     24       description = ''
     25         Copy-pastable U-Boot commands to TFTP download the
     26         image and write it to flash
     27       '';
     28     };
     29     mtdimage = mkOption {
     30       type = types.package;
     31       description = ''
     32         mtdimage
     33         **********
     34 
     35         This creates an image called :file:`firmware.bin` suitable for
     36         squashfs or jffs2 systems. It can be flashed from U-Boot (if
     37         you have a serial console connection), or on some devices from
     38         the vendor firmware, or from Liminix when using
     39         :ref:`levitate`
     40 
     41         If you are flashing from U-Boot, the file
     42         :file:`flash.scr` is a sequence of commands
     43         which you can paste at the U-Boot prompt to
     44         to transfer the firmware file from a TFTP server and
     45         write it to flash. **Please read the script before
     46         running it: flash operations carry the potential to
     47         brick your device**
     48 
     49         .. NOTE::
     50 
     51            TTL serial connections typically have no form of flow
     52            control and so don't always like having massive chunks of
     53            text pasted into them - and U-Boot may drop characters
     54            while it's busy. So don't necessarily expect to copy-paste
     55            the whole of :file:`flash.scr` into a terminal emulator and
     56            have it work just like that. You may need to paste each
     57            line one at a time, or even retype it.
     58       '';
     59     };
     60   };
     61 
     62   config = {
     63     kernel = {
     64       config =
     65         {
     66           # this needs to be conditional on "not qemu"
     67           MTD_SPLIT_UIMAGE_FW = "y";
     68         }
     69         // lib.optionalAttrs (pkgs.stdenv.isMips) {
     70           # https://stackoverflow.com/questions/26466470/can-the-logical-erase-block-size-of-an-mtd-device-be-increased
     71           MTD_SPI_NOR_USE_4K_SECTORS = "n";
     72         };
     73     };
     74 
     75     programs.busybox.applets = [
     76       "flashcp"
     77     ];
     78 
     79     system.outputs = {
     80       firmware =
     81         let
     82           o = config.system.outputs;
     83           bs = toString config.hardware.flash.eraseBlockSize;
     84         in
     85         pkgs.runCommand "firmware" { } ''
     86           dd if=${o.uimage} of=$out bs=${bs} conv=sync
     87           dd if=${o.rootfs} of=$out bs=${bs} conv=sync,nocreat,notrunc oflag=append
     88         '';
     89       mtdimage =
     90         let
     91           o = config.system.outputs;
     92         in
     93         # could use trivial-builders.linkFarmFromDrvs here?
     94         pkgs.runCommand "mtdimage" { } ''
     95           mkdir $out
     96           cd $out
     97           ln -s ${o.firmware} firmware.bin
     98           ln -s ${o.rootfs} rootfs
     99           ln -s ${o.kernel} vmlinux
    100           ln -s ${o.manifest} manifest
    101           ln -s ${o.kernel.headers} build
    102           ln -s ${o.uimage} uimage
    103           ln -s ${o.dtb} dtb
    104           ln -s ${o.flash-scr} flash.scr
    105         '';
    106 
    107       flash-scr =
    108         let
    109           inherit (pkgs.lib.trivial) toHexString;
    110           inherit (config.hardware) flash;
    111         in
    112         pkgs.buildPackages.runCommand "" { } ''
    113           imageSize=$(stat -L -c %s ${config.system.outputs.firmware})
    114           cat > $out << EOF
    115           setenv serverip ${tftp.serverip}
    116           setenv ipaddr ${tftp.ipaddr}
    117           tftp 0x${toHexString tftp.loadAddress} result/firmware.bin
    118           erase 0x${toHexString flash.address} +0x${toHexString flash.size}
    119           cp.b 0x${toHexString tftp.loadAddress} 0x${toHexString flash.address} \''${filesize}
    120           echo command line was ${builtins.toJSON (concatStringsSep " " config.boot.commandLine)}
    121           EOF
    122         '';
    123     };
    124   };
    125 }