forked from Imagelibrary/littlefs
Added dbgblock.py for quicker hex dumps
This script is basically the same as xxd, but with the other debug script's block address format: $ ./scripts/dbgblock.py disk -B4096 1 block 0x1, size 20 off data 00000000: 00 00 00 00 00 03 00 08 6c 69 74 74 6c 65 66 73 ........littlefs 00000010: 40 03 00 0c 80 04 00 02 02 00 d0 03 00 16 c0 04 @............... ...
This commit is contained in:
125
scripts/dbgblock.py
Executable file
125
scripts/dbgblock.py
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
|
||||
|
||||
# parse some rbyd addr encodings
|
||||
# 0xa -> [0xa]
|
||||
# 0xa.b -> ([0xa], b)
|
||||
# 0x{a,b} -> [0xa, 0xb]
|
||||
def rbydaddr(s):
|
||||
s = s.strip()
|
||||
b = 10
|
||||
if s.startswith('0x') or s.startswith('0X'):
|
||||
s = s[2:]
|
||||
b = 16
|
||||
elif s.startswith('0o') or s.startswith('0O'):
|
||||
s = s[2:]
|
||||
b = 8
|
||||
elif s.startswith('0b') or s.startswith('0B'):
|
||||
s = s[2:]
|
||||
b = 2
|
||||
|
||||
trunk = None
|
||||
if '.' in s:
|
||||
s, s_ = s.split('.', 1)
|
||||
trunk = int(s_, b)
|
||||
|
||||
if s.startswith('{') and '}' in s:
|
||||
ss = s[1:s.find('}')].split(',')
|
||||
else:
|
||||
ss = [s]
|
||||
|
||||
addr = []
|
||||
for s in ss:
|
||||
if trunk is not None:
|
||||
addr.append((int(s, b), trunk))
|
||||
else:
|
||||
addr.append(int(s, b))
|
||||
|
||||
return addr
|
||||
|
||||
def xxd(data, width=16):
|
||||
for i in range(0, len(data), width):
|
||||
yield '%-*s %-*s' % (
|
||||
3*width,
|
||||
' '.join('%02x' % b for b in data[i:i+width]),
|
||||
width,
|
||||
''.join(
|
||||
b if b >= ' ' and b <= '~' else '.'
|
||||
for b in map(chr, data[i:i+width])))
|
||||
|
||||
def main(disk, block=None, *,
|
||||
block_size=None,
|
||||
seek=None,
|
||||
size=None):
|
||||
# flatten block, default to block 0
|
||||
if not block:
|
||||
block = [0]
|
||||
|
||||
if len(block) > 1:
|
||||
print("error: More than one block address?")
|
||||
sys.exit(-1)
|
||||
|
||||
block = block[0]
|
||||
|
||||
with open(disk, 'rb') as f:
|
||||
# if block_size is omitted, assume the block device is one big block
|
||||
if block_size is None:
|
||||
f.seek(0, os.SEEK_END)
|
||||
block_size = f.tell()
|
||||
|
||||
# block may also encode an offset
|
||||
block, off, size = (
|
||||
block[0] if isinstance(block, tuple) else block,
|
||||
seek if seek is not None
|
||||
else block[1] if isinstance(block, tuple)
|
||||
else None,
|
||||
size if size is not None else block_size)
|
||||
|
||||
print('block %s, size %d' % (
|
||||
'0x%x.%x' % (block, off)
|
||||
if off is not None
|
||||
else '0x%x' % block,
|
||||
size))
|
||||
|
||||
# read the block
|
||||
f.seek((block * block_size) + (off or 0))
|
||||
data = f.read(size)
|
||||
|
||||
# print header
|
||||
print('%-8s %s' % ('off', 'data'))
|
||||
|
||||
# render the hex view
|
||||
for o, line in enumerate(xxd(data)):
|
||||
print('%08x: %s' % ((off or 0) + 16*o, line))
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
import sys
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Debug block devices.",
|
||||
allow_abbrev=False)
|
||||
parser.add_argument(
|
||||
'disk',
|
||||
help="File containing the block device.")
|
||||
parser.add_argument(
|
||||
'block',
|
||||
nargs='?',
|
||||
type=rbydaddr,
|
||||
help="Block address.")
|
||||
parser.add_argument(
|
||||
'-B', '--block-size',
|
||||
type=lambda x: int(x, 0),
|
||||
help="Block size in bytes.")
|
||||
parser.add_argument(
|
||||
'-s', '--seek',
|
||||
type=lambda x: int(x, 0),
|
||||
help="Start at this offset.")
|
||||
parser.add_argument(
|
||||
'-n', '--size',
|
||||
type=lambda x: int(x, 0),
|
||||
help="Show this many bytes.")
|
||||
sys.exit(main(**{k: v
|
||||
for k, v in vars(parser.parse_intermixed_args()).items()
|
||||
if v is not None}))
|
||||
Reference in New Issue
Block a user