Flash Checksum Hierarchy
The three checksum tiers, the block descriptor table, and a standalone fixer.
The three checksum tiers, the block descriptor table, and a standalone fixer.
While Section 10 documents the serial SPI EEPROM (ST 95040 / 95080) memory map and checksum algorithms, the 1024 KB AMD AM29F800BB parallel flash ROM containing the engine executable code and calibration tables enforces an entirely independent, multi-tiered cryptographic and mathematical integrity architecture.
Whenever an engineer modifies a fuel map (KRKTE), ignition table (KFZW), boost ceiling (LDRXN), or DTC table (CLA*), flashing the resulting binary without recalculating the main flash checksums results in an immediate engine no-start condition, accompanied by VCDS Diagnostic Trouble Code P0601 / 16985 (Internal Control Module: Memory Check Sum Error).
| Tier 1: 16-Bit Additive Sums | Tier 2: Complement Pairs | Tier 3: Bosch CRC32 / CRC16 |
|---|---|---|
| • Multipage 16-bit blocks | • Paired inverse 16-bit words | • Cyclic redundancy polynomials |
| • Calculated per memory bank | • Word_A + Word_B = 0xFFFF | • Blocks 0x01FBxx & 0x07FBxx |
| • Stored in checksum headers | • Immediate startup validation | • Full flash segmentation sync |
11.1. The Three Checksum Tiers Explained#
Bosch Motronic ME7.5 firmware implements three distinct mathematical verification mechanisms distributed across the 1024 KB memory space:
1. Tier 1: 16-Bit Multipage Additive Checksums (Simple Word Sums)#
- Scope: The flash memory is divided into 14 to 18 discrete logical blocks (varying by project family, e.g. 21D vs 24B).
- Algorithm: The C167 CPU computes the 16-bit summation of all 16-bit words (u16) across the block: \text{Sum}_{16} = \left( \sum_{i=0}^{N-1} \text{Word}_{16}[i] \right) \pmod{2^{16}}
- Location: The target sums are stored in a centralized table structure located near offset
0x01FB00–0x01FC00(Bank 0) and0x07FB00–0x07FC00(Bank 1). - Execution: Evaluated both during the initial microcontroller cold-boot self-test and periodically during engine idle task loops.
2. Tier 2: 16-Bit Inverse Complement Word Pairs#
- Scope: Placed at strategic memory boundaries directly before and after major calibration sections.
- Rule: Two adjacent 16-bit words (\text{Word}_A and \text{Word}_B) must satisfy: \text{Word}_A + \text{Word}_B = \text{0xFFFF} \quad (\text{or } \text{Word}_B = \text{Word}_A \oplus \text{0xFFFF})
- Function: Serves as a rapid, single-cycle hardware sanity check. If flash write corruption or bit-flipping occurs, the bitwise complement condition fails instantly, triggering emergency shutdown before full arithmetic checks execute.
3. Tier 3: Bosch Proprietary CRC16 / CRC32 Polynomial Blocks#
- Scope: High-security cyclic redundancy verification covering the core executable microcode segments (
0x000000–0x00FFFFand0x020000–0x07FFFF). - Polynomial: Standard IEEE 802.3 CRC32 polynomial: P(x) = x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} + x^{11} + x^{10} + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 Represented in hexadecimal as
0xEDB88320(reversed) or0x04C11DB7(standard). - Seed & Final XOR: Standard initial value
0xFFFFFFFF, post-inverted with0xFFFFFFFF. - Validation: When modifying calibration maps, only the calibration CRC block changes; when patching assembly microcode (e.g. adding Launch Control), both the code CRC block and the main flash master CRC must be re-signed.
11.2. Checksum Block Descriptor Table Layout (06A906032LP)#
In 06A906032LP (and all mature 24B binaries), the master checksum configuration table starts at offset 0x01FB80. Each descriptor entry occupies 12 bytes:
| Offset in Flash | Field Name | Data Type | Description |
|---|---|---|---|
| Entry + 0x00 | Start Address | u32 (LE) | Physical flash start offset |
| Entry + 0x04 | End Address | u32 (LE) | Physical flash end offset (inclusive) |
| Entry + 0x08 | Stored Checksum | u16 (LE) | Calculated 16-bit expected sum |
| Entry + 0x0A | Checksum Type / Flags | u16 (LE) | 0x0001 = Additive, 0x0002 = CRC32 |
Typical Block Partitioning in a 1024 KB ME7.5 Binary#
- Block 1 (
0x000000–0x003FFF): Interrupt Vector Table & Early Boot Routine. - Block 2 (
0x004000–0x007FFF): Core OS Kernel & Task Dispatcher (B_10ms,B_20ms). - Block 3 (
0x008000–0x00FFFF): Communications & KWP2000 Diagnostic Handlers. - Block 4 (
0x010000–0x013FFF): Primary Ignition & Knock Detection Tables (KFZW,KFZW2). - Block 5 (
0x014000–0x017FFF): Torque Model & Throttle Translation (KFMIRL,KFMIOP,KFPED). - Block 6 (
0x018000–0x01BFFF): Fueling, Lambda & MAF Linearization (KRKTE,LAMFA,MLHFM). - Block 7 (
0x01C000–0x01FFFF): Boost Control PID & Diagnostic Codewords (LDRXN,ESKONF,CD*). - Block 8 (
0x020000–0x07FFFF): Extended Code Segment (C167 Functions). - Block 9 (
0x080000–0x0FFFFF): Upper Flash Mirror & Secondary Calibration Data.
11.3. Standalone Main Flash Checksum Engine Implementation (me7_flash_checksum.py)#
Below is the standalone Python verification engine that parses, verifies, and recalculates ME7.5 1024 KB binary checksums:
#!/usr/bin/env python3
"""
Bosch ME7.5 1024 KB Flash Checksum Verification & Recalculation Engine
Target Platform: AMD AM29F800BB Parallel Flash (1048576 Bytes)
Compatible with: 06A906032LP, PL, SK, HS, CL, DL, JJ, HN
"""
import struct
import sys
import zlib
def verify_and_fix_me7_checksums(bin_path, output_path=None):
with open(bin_path, 'rb') as f:
data = bytearray(f.read())
if len(data) != 1048576:
print(f"Error: Invalid file size {len(data)} bytes. Must be exactly 1,048,576 bytes.")
return False
print(f"Loaded {bin_path} (1024 KB). Scanning for ME7.5 Checksum Descriptors...")
# Locate master descriptor table in Segment 1 (typically around 0x01FB80)
# Search for signature start addresses: 0x00000000 followed by valid end address
descriptor_offset = None
for candidate in [0x01FB80, 0x01FB00, 0x01FA80, 0x01FC00]:
start_addr, end_addr = struct.unpack_from('<II', data, candidate)
if start_addr == 0x00000000 and 0x00001000 <= end_addr <= 0x000FFFFF:
descriptor_offset = candidate
break
if descriptor_offset is None:
print("Warning: Could not auto-detect descriptor table. Using standard 24B offset 0x01FB80.")
descriptor_offset = 0x01FB80
print(f"Checksum table detected at 0x{descriptor_offset:06X}")
fixed_count = 0
# Process up to 16 descriptor blocks
for block_idx in range(16):
entry_offset = descriptor_offset + (block_idx * 12)
start_addr, end_addr, stored_sum, flags = struct.unpack_from('<IIHH', data, entry_offset)
# Terminating condition or invalid entry
if start_addr >= end_addr or end_addr >= len(data):
break
# Calculate 16-bit word summation
calc_sum = 0
block_bytes = data[start_addr:end_addr + 1]
# Unpack as little-endian 16-bit words
word_count = len(block_bytes) // 2
words = struct.unpack(f'<{word_count}H', block_bytes[:word_count * 2])
calc_sum = sum(words) & 0xFFFF
status = "OK" if calc_sum == stored_sum else "FAIL"
print(f"Block {block_idx:02d} [0x{start_addr:06X}..0x{end_addr:06X}]: "
f"Stored=0x{stored_sum:04X}, Calc=0x{calc_sum:04X} -> {status}")
if calc_sum != stored_sum:
# Fix checksum in descriptor table
struct.pack_into('<H', data, entry_offset + 8, calc_sum)
fixed_count += 1
# Verify and fix complement pairs in Segment 1
# Check complement pairs at 0x01FBEE and 0x01FBF0
comp1, comp2 = struct.unpack_from('<HH', data, 0x01FBEE)
if (comp1 + comp2) & 0xFFFF != 0xFFFF:
new_comp2 = (~comp1) & 0xFFFF
struct.pack_into('<H', data, 0x01FBF0, new_comp2)
print(f"Fixed Complement Pair at 0x01FBEE: 0x{comp1:04X} + 0x{new_comp2:04X} = 0xFFFF")
fixed_count += 1
if fixed_count > 0 and output_path:
with open(output_path, 'wb') as f:
f.write(data)
print(f"Successfully corrected {fixed_count} checksum(s). Written to {output_path}.")
elif fixed_count == 0:
print("All flash checksums are 100% valid. No corrections required.")
return True
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python3 me7_flash_checksum.py <input.bin> [output_fixed.bin]")
sys.exit(1)
out_file = sys.argv[2] if len(sys.argv) > 2 else sys.argv[1]
verify_and_fix_me7_checksums(sys.argv[1], out_file)
Related#
Cross-referenced on shared calibration symbols, not on subject matter — these are the chapters that touch the same maps.
- Chapter 6 — Memory Geometry & Axes —
MLHFM,KFZW2,KFPED,KFMIOP,LAMFA,KFMIRL - Chapter 45 — Pattern Matching & XDF Porting —
KFZW2,KFMIOP,LAMFA,KFMIRL,LDRXN,KRKTE - Chapter 3 — Benchmark Calibrations —
KFZW2,KFPED,KFMIOP,LAMFA,KFMIRL,LDRXN - Chapter 25 — Troubleshooting & Failsafes —
KFMIOP,LAMFA,KFMIRL,LDRXN,KFZW - Chapter 16 — Torque Model & Inversion —
KFPED,KFMIOP,KFMIRL,LDRXN - Chapter 44 — High-Lift Camshafts —
KFMIOP,KFMIRL,ESKONF,KFZW
← Previous chapter · Contents · Next chapter →
Related
Cross-referenced on shared calibration symbols, not on subject matter — these are the chapters that touch the same maps.