Created
April 25, 2017 00:39
-
-
Save Cr4sh/79cb406a988ace1d9fb63723e9362199 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, os, socket | |
from struct import pack, unpack | |
from hexdump import hexdump | |
class OpenOcd: | |
COMMAND_TOKEN = '\x1a' | |
def __init__(self, verbose=False): | |
self.verbose = verbose | |
self.tclRpcIp = "127.0.0.1" | |
self.tclRpcPort = 6666 | |
self.bufferSize = 4096 | |
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
def __enter__(self): | |
self.sock.connect((self.tclRpcIp, self.tclRpcPort)) | |
return self | |
def __exit__(self, type, value, traceback): | |
try: self.send("exit") | |
finally: self.sock.close() | |
def send(self, cmd): | |
"""Send a command string to TCL RPC. Return the result that was read.""" | |
data = (cmd + OpenOcd.COMMAND_TOKEN).encode("utf-8") | |
if self.verbose: | |
print("<- ", data) | |
self.sock.send(data) | |
return self._recv() | |
def _recv(self): | |
"""Read from the stream until the token (\x1a) was received.""" | |
data = bytes() | |
while True: | |
chunk = self.sock.recv(self.bufferSize) | |
data += chunk | |
if OpenOcd.COMMAND_TOKEN in chunk: | |
break | |
if self.verbose: | |
print("-> ", data) | |
data = data.decode("utf-8").strip() | |
data = data[:-1] # strip trailing \x1a | |
return data | |
def readVariable(self, address): | |
raw = self.send("ocd_mdw 0x%x" % address).split(": ") | |
return None if (len(raw) < 2) else strToHex(raw[1]) | |
def readMemory(self, wordLen, address, n): | |
self.send("array unset output") # better to clear the array before | |
self.send("mem2array output %d 0x%x %d" % (wordLen, address, n)) | |
output = self.send("ocd_echo $output").split(" ") | |
return [int(output[2*i+1]) for i in range(len(output)//2)] | |
def writeVariable(self, address, value): | |
assert value is not None | |
self.send("mww 0x%x 0x%x" % (address, value)) | |
def writeMemory(self, wordLen, address, n, data): | |
array = " ".join(["%d 0x%x" % (a, b) for a, b in enumerate(data)]) | |
self.send("array unset buff") # better to clear the array before | |
self.send("array set buff { %s }" % array) | |
self.send("array2mem buff 0x%x %s %d" % (wordLen, address, n)) | |
def main(): | |
with OpenOcd() as ocd: | |
ocd.send('halt') | |
read = lambda addr, size: ''.join(map(lambda c: chr(c), ocd.readMemory(8, addr, size))) | |
addr, step = 0, 0x100000 | |
prev_ok, prev_addr = None, None | |
prev_data = '' | |
while addr < 0xffffffff: | |
try: | |
data = read(addr, 4) | |
ok = True | |
except ValueError: | |
ok = False | |
if prev_ok is True and not ok: | |
print('0x%.8x - 0x%.8x %.8x' % (prev_addr, addr + step - 1, unpack('I', prev_data)[0])) | |
if not prev_ok and ok: | |
prev_addr = addr | |
prev_data = data | |
addr += step | |
prev_ok = ok | |
return 0 | |
if __name__ == '__main__': | |
exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment