rp2040/tools/boot2_pre_crc.py

56 lines
1.7 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import binascii
import struct
import argparse
def calculate_mpeg2_crc32(data):
"""
Calculate MPEG-2 style CRC32 (Polynomial: 0x04C11DB7, Initial: 0xFFFFFFFF)
Note: Result is NOT inverted (unlike standard CRC32)
"""
crc = 0xFFFFFFFF
for byte in data:
crc ^= byte << 24
for _ in range(8):
if crc & 0x80000000:
crc = (crc << 1) ^ 0x04C11DB7
else:
crc = crc << 1
crc &= 0xFFFFFFFF
return crc
def process_file(filename):
try:
with open(filename, 'rb+') as f:
# Verify exact 256 bytes size
f.seek(0, 2)
if f.tell() != 256:
raise ValueError(f"File must be exactly 256 bytes (got {f.tell()} bytes)")
f.seek(0)
data = f.read(252)
if len(data) != 252:
raise ValueError("Couldn't read 252 bytes from file")
crc = calculate_mpeg2_crc32(data)
f.seek(252)
f.write(struct.pack('<I', crc))
print(f"Success: Updated {filename} with CRC32 0x{crc:08X} at offset 252")
return True
except Exception as e:
print(f"Error processing {filename}: {str(e)}")
return False
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Calculate MPEG-2 CRC32 for first 252 bytes and write to last 4 bytes of 256-byte file')
parser.add_argument('filename', help='Binary file to process (must be 256 bytes)')
args = parser.parse_args()
if not process_file(args.filename):
exit(1)