LPC Checksum
A Python script designed to calculate LPC firmware checksums, based on the C version by Roel Verdult. It functions both as a standalone application and as a Python module that can be integrated into build environments. The current version is 3.0.0, but its release cadence is stalled, with the last release approximately three years ago.
Warnings
- gotcha LPC microcontrollers require a specific checksum at address 0x1C in the interrupt vector table for the firmware to boot correctly. If this checksum is missing or incorrect (e.g., if a standard GNU toolchain doesn't generate it), the device will not boot or will enter ISP mode. This library directly addresses this issue.
- gotcha When calculating 32-bit checksums, improper handling of integer overflow can lead to incorrect results. An earlier version (v2.1.2) had a bug where modulo (%) was incorrectly used instead of bitwise AND (&) for 32-bit overflow, leading to discrepancies with C-based calculations. While fixed in current versions, it highlights a critical detail in checksum implementation.
- deprecated The `lpc-checksum` library's release cadence is stalled, with the last release (v3.0.0) dating back approximately three years ago. This indicates a lack of active development, which could mean slower responses to bug reports or no new feature additions.
Install
-
pip install lpc-checksum
Imports
- checksum
import lpc_checksum
Quickstart
import lpc_checksum
import os
# Create a dummy binary file for demonstration
dummy_firmware_path = 'firmware.bin'
with open(dummy_firmware_path, 'wb') as f:
f.write(b'\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
# Calculate and inject the checksum
try:
# The checksum function modifies the file in place by default
# or returns the checksum if read_only=True
print(f"Calculating checksum for {dummy_firmware_path}")
checksum_value = lpc_checksum.checksum(dummy_firmware_path, read_only=True)
print(f"Calculated checksum (read-only): 0x{checksum_value:08x}")
# To actually write the checksum to the file:
lpc_checksum.checksum(dummy_firmware_path)
print(f"Checksum injected into {dummy_firmware_path}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up the dummy file
if os.path.exists(dummy_firmware_path):
os.remove(dummy_firmware_path)
print(f"Cleaned up {dummy_firmware_path}")