#!/usr/bin/env python3 """Find the count=0 sentinel in the BCM4500 firmware data at 0x4000+.""" import sys sys.path.insert(0, 'tools') from skywalker_lib import SkyWalker1 CMD_EEPROM_READ = 0xC0 sw = SkyWalker1() sw.open() def ee(addr, length): return sw._vendor_in(CMD_EEPROM_READ, value=addr, index=length, length=length) print('=== Scanning for count=0 sentinel from 0x4000 ===') print() blocks = 0 total_bytes = 0 addr = 0x4000 while addr < 0x8000: data = ee(addr, 20) count = data[0] if count == 0: print(f' SENTINEL FOUND at 0x{addr:04X} after {blocks} blocks ({total_bytes} payload bytes)') break if count > 16: print(f' INVALID count=0x{count:02X} at 0x{addr:04X} after {blocks} blocks') # Show context for ctx_addr in range(max(0x4000, addr - 60), addr + 60, 20): d = ee(ctx_addr, 20) marker = ' ← INVALID' if ctx_addr == addr else '' print(f' 0x{ctx_addr:04X}: count={d[0]:3d} A9=0x{d[1]:02X} AA=0x{d[2]:02X}{marker}') break # Valid block a9 = data[1] aa = data[2] ab_bytes = count total_bytes += ab_bytes if blocks < 5 or blocks % 100 == 0: ab = data[4:4 + min(count, 8)] print(f' Block {blocks:4d} @ 0x{addr:04X}: count={count:2d} A9=0x{a9:02X} AA=0x{aa:02X} ' f'AB=[{ab.hex(" ")}{"..." if count > 8 else ""}]') blocks += 1 addr += 20 else: print(f' NO SENTINEL found before 0x8000 ({blocks} blocks scanned)') print() print(f'Summary: {blocks} blocks, {total_bytes} payload bytes') print(f'Address range: 0x4000 - 0x{addr:04X}') # Show the sentinel and what follows if addr < 0x8000: print() print(f'--- Data around sentinel at 0x{addr:04X} ---') for a in range(max(0x4000, addr - 40), addr + 60, 20): d = ee(a, 20) cnt = d[0] if cnt == 0: print(f' 0x{a:04X}: [SENTINEL count=0] rest: {d[1:].hex(" ")}') elif 1 <= cnt <= 16: print(f' 0x{a:04X}: count={cnt} A9=0x{d[1]:02X} AA=0x{d[2]:02X}') else: print(f' 0x{a:04X}: [non-PLL: 0x{cnt:02X}] {d[:16].hex(" ")}') sw.close() print() print('=== Done ===')