117 lines
3.8 KiB
Nix
117 lines
3.8 KiB
Nix
{
|
|
config
|
|
, pkgs
|
|
, lib
|
|
, ...
|
|
}:
|
|
let
|
|
inherit (lib) mkOption types concatStringsSep;
|
|
inherit (config.boot) tftp;
|
|
in {
|
|
options.system.outputs = {
|
|
firmware = mkOption {
|
|
type = types.package;
|
|
internal = true; # component of flashimage
|
|
description = ''
|
|
Binary image (combining kernel, FDT, rootfs, initramfs
|
|
if needed, etc) for the target device.
|
|
'';
|
|
};
|
|
flash-scr = mkOption {
|
|
type = types.package;
|
|
internal = true; # component of flashimage
|
|
description = ''
|
|
Copy-pastable U-Boot commands to TFTP download the
|
|
image and write it to flash
|
|
'';
|
|
};
|
|
flashimage = mkOption {
|
|
type = types.package;
|
|
description = ''
|
|
flashimage
|
|
**********
|
|
|
|
This creates an image called :file:`firmware.bin` suitable for
|
|
squashfs or jffs2 systems. It can be flashed from U-Boot (if
|
|
you have a serial console connection), or on some devices from
|
|
the vendor firmware, or from a Liminix kexecboot system.
|
|
|
|
If you are flashing from U-Boot, the file
|
|
:file:`flash.scr` is a sequence of commands
|
|
which you can paste at the U-Boot prompt to
|
|
to transfer the firmware file from a TFTP server and
|
|
write it to flash. **Please read the script before
|
|
running it: flash operations carry the potential to
|
|
brick your device**
|
|
|
|
.. NOTE::
|
|
|
|
TTL serial connections typically have no form of flow
|
|
control and so don't always like having massive chunks of
|
|
text pasted into them - and U-Boot may drop characters
|
|
while it's busy. So don't necessarily expect to copy-paste
|
|
the whole of :file:`flash.scr` into a terminal emulator and
|
|
have it work just like that. You may need to paste each
|
|
line one at a time, or even retype it.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = {
|
|
kernel = {
|
|
config = {
|
|
MTD_SPLIT_UIMAGE_FW = "y";
|
|
} // lib.optionalAttrs (pkgs.stdenv.isMips) {
|
|
# https://stackoverflow.com/questions/26466470/can-the-logical-erase-block-size-of-an-mtd-device-be-increased
|
|
MTD_SPI_NOR_USE_4K_SECTORS = "n";
|
|
};
|
|
};
|
|
|
|
programs.busybox.applets = [
|
|
"flashcp"
|
|
];
|
|
|
|
system.outputs = {
|
|
firmware =
|
|
let
|
|
o = config.system.outputs;
|
|
bs = config.hardware.flash.eraseBlockSize;
|
|
in pkgs.runCommand "firmware" {} ''
|
|
dd if=${o.uimage} of=$out bs=${bs} conv=sync
|
|
dd if=${o.rootfs} of=$out bs=${bs} conv=sync,nocreat,notrunc oflag=append
|
|
'';
|
|
flashimage =
|
|
let o = config.system.outputs; in
|
|
# could use trivial-builders.linkFarmFromDrvs here?
|
|
pkgs.runCommand "flashimage" {} ''
|
|
mkdir $out
|
|
cd $out
|
|
ln -s ${o.firmware} firmware.bin
|
|
ln -s ${o.rootfs} rootfs
|
|
ln -s ${o.kernel} vmlinux
|
|
ln -s ${o.manifest} manifest
|
|
ln -s ${o.kernel.headers} build
|
|
ln -s ${o.uimage} uimage
|
|
ln -s ${o.dtb} dtb
|
|
ln -s ${o.flash-scr} flash.scr
|
|
'';
|
|
|
|
flash-scr =
|
|
let
|
|
inherit (pkgs.lib.trivial) toHexString;
|
|
inherit (config.hardware) flash;
|
|
in
|
|
pkgs.buildPackages.runCommand "" {} ''
|
|
imageSize=$(stat -L -c %s ${config.system.outputs.firmware})
|
|
cat > $out << EOF
|
|
setenv serverip ${tftp.serverip}
|
|
setenv ipaddr ${tftp.ipaddr}
|
|
tftp 0x${toHexString tftp.loadAddress} result/firmware.bin
|
|
erase 0x$(printf %x ${flash.address}) +${flash.size}
|
|
cp.b 0x${toHexString tftp.loadAddress} 0x$(printf %x ${flash.address}) \''${filesize}
|
|
echo command line was ${builtins.toJSON (concatStringsSep " " config.boot.commandLine)}
|
|
EOF
|
|
'';
|
|
};
|
|
};
|
|
}
|