2023-03-03 00:01:26 +01:00
|
|
|
{
|
|
|
|
config
|
|
|
|
, pkgs
|
|
|
|
, lib
|
|
|
|
, ...
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
inherit (lib) mkOption types concatStringsSep;
|
|
|
|
inherit (config.boot) tftp;
|
|
|
|
in {
|
2023-07-13 20:24:59 +02:00
|
|
|
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 = ''
|
2023-11-09 23:43:50 +01:00
|
|
|
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.
|
2023-07-13 20:24:59 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-03-03 00:01:26 +01:00
|
|
|
};
|
2023-07-13 20:24:59 +02:00
|
|
|
|
2023-03-03 00:01:26 +01:00
|
|
|
config = {
|
|
|
|
kernel = {
|
|
|
|
config = {
|
|
|
|
MTD_SPLIT_UIMAGE_FW = "y";
|
2023-10-07 23:41:15 +02:00
|
|
|
} // lib.optionalAttrs (pkgs.stdenv.isMips) {
|
2023-09-27 23:10:17 +02:00
|
|
|
# https://stackoverflow.com/questions/26466470/can-the-logical-erase-block-size-of-an-mtd-device-be-increased
|
|
|
|
MTD_SPI_NOR_USE_4K_SECTORS = "n";
|
2023-03-03 00:01:26 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-03-24 18:32:46 +01:00
|
|
|
programs.busybox.applets = [
|
|
|
|
"flashcp"
|
|
|
|
];
|
|
|
|
|
2023-07-13 20:24:59 +02:00
|
|
|
system.outputs = {
|
|
|
|
firmware =
|
2023-09-26 00:20:28 +02:00
|
|
|
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
|
2023-03-03 00:01:26 +01:00
|
|
|
'';
|
2023-07-13 20:24:59 +02:00
|
|
|
flashimage =
|
|
|
|
let o = config.system.outputs; in
|
2023-08-28 19:24:14 +02:00
|
|
|
# could use trivial-builders.linkFarmFromDrvs here?
|
2023-07-13 20:24:59 +02:00
|
|
|
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
|
|
|
|
'';
|
2023-03-03 00:01:26 +01:00
|
|
|
|
2023-07-13 20:24:59 +02:00
|
|
|
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$(printf %x ${tftp.loadAddress}) result/firmware.bin
|
|
|
|
erase 0x$(printf %x ${flash.address}) +${flash.size}
|
|
|
|
cp.b 0x$(printf %x ${tftp.loadAddress}) 0x$(printf %x ${flash.address}) \''${filesize}
|
|
|
|
echo command line was ${builtins.toJSON (concatStringsSep " " config.boot.commandLine)}
|
|
|
|
EOF
|
|
|
|
'';
|
|
|
|
};
|
2023-03-03 00:01:26 +01:00
|
|
|
};
|
|
|
|
}
|