diff options
| author | Loïc Guégan <manzerbredes@mailbox.org> | 2025-03-24 09:33:49 +0100 |
|---|---|---|
| committer | Loïc Guégan <manzerbredes@mailbox.org> | 2025-03-24 09:33:49 +0100 |
| commit | 7741f014456df395b655b72d9ebb848af72cc37e (patch) | |
| tree | 5ddae273929780ac7c0af2a26b64ba1a382e4b05 /tools/pad_checksum.py | |
| parent | d3ecfe3498d73d3ba924063bc1001cca3f333170 (diff) | |
Init repository
Diffstat (limited to 'tools/pad_checksum.py')
| -rwxr-xr-x | tools/pad_checksum.py | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/tools/pad_checksum.py b/tools/pad_checksum.py new file mode 100755 index 0000000..d301756 --- /dev/null +++ b/tools/pad_checksum.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +import argparse +import binascii +import struct +import sys + + +def any_int(x): + try: + return int(x, 0) + except: + raise argparse.ArgumentTypeError("expected an integer, not '{!r}'".format(x)) + + +def bitrev(x, width): + return int("{:0{w}b}".format(x, w=width)[::-1], 2) + + +parser = argparse.ArgumentParser() +parser.add_argument("ifile", help="Input file (binary)") +parser.add_argument("ofile", help="Output file (assembly)") +parser.add_argument("-p", "--pad", help="Padded size (bytes), including 4-byte checksum, default 256", + type=any_int, default=256) +parser.add_argument("-s", "--seed", help="Checksum seed value, default 0", + type=any_int, default=0) +args = parser.parse_args() + +try: + idata = open(args.ifile, "rb").read() +except: + sys.exit("Could not open input file '{}'".format(args.ifile)) + +if len(idata) > args.pad - 4: + sys.exit("Input file size ({} bytes) too large for final size ({} bytes)".format(len(idata), args.pad)) + +idata_padded = idata + bytes(args.pad - 4 - len(idata)) + +# Our bootrom CRC32 is slightly bass-ackward but it's best to work around for now (FIXME) +# 100% worth it to save two Thumb instructions +checksum = bitrev( + (binascii.crc32(bytes(bitrev(b, 8) for b in idata_padded), args.seed ^ 0xffffffff) ^ 0xffffffff) & 0xffffffff, 32) +odata = idata_padded + struct.pack("<L", checksum) + +try: + with open(args.ofile, "w") as ofile: + ofile.write("// Padded and checksummed version of: {}\n\n".format(args.ifile)) + ofile.write(".cpu cortex-m0plus\n") + ofile.write(".thumb\n\n") + ofile.write(".section .boot2, \"ax\"\n\n") + for offs in range(0, len(odata), 16): + chunk = odata[offs:min(offs + 16, len(odata))] + ofile.write(".byte {}\n".format(", ".join("0x{:02x}".format(b) for b in chunk))) +except: + sys.exit("Could not open output file '{}'".format(args.ofile)) |
