Skip to content

Instantly share code, notes, and snippets.

@hlandau
Last active August 2, 2018 23:02
Show Gist options
  • Save hlandau/186c6d635124ac911de2c7fccf78aad7 to your computer and use it in GitHub Desktop.
Save hlandau/186c6d635124ac911de2c7fccf78aad7 to your computer and use it in GitHub Desktop.
PNOR info dumping script (dumps partition table of OpenPOWER PNOR firmware images)
#!/usr/bin/env python3
import sys, struct, io
def read_hdr(f):
d = f.read(12*4)
dMagic = d[0:4]
magic, version, size, entrySize, entryCount, blockSize, blockCount, resv0, resv1, resv2, resv3, checksum = struct.unpack('>' + 'I'*12, d)
print('''
PNOR Header
Magic: {magic:#010x} ({dMagic})
Version: {version:10}
Size: {size:10}
Entry Size: {entrySize:10}
Entry Count: {entryCount:10}
Block Size: {blockSize:10}
Block Count: {blockCount:10}
Reserved: {resv0:#010x} {resv1:#010x} {resv2:#010x} {resv3:#010x}
Checksum: {checksum:#x}'''.format(**locals()))
return locals()
def print_legend():
print('''
Name Base Size PID ID Type Flags
Reserved Checksum
User
--------------------------------------------------------------------------------------------''')
units = [' B', 'KiB', 'MiB', 'GiB']
def niceSize(sz):
i = 0
u = ' B'
while sz >= 1024:
i = i+1
u = units[i]
sz = sz//1024
return '{0:9} {1}'.format(sz, u)
types={1:'DATA',2:'LOGICAL',3:'PARTITION'}
last_end = None
def read_item(f, hdr):
global last_end
d = f.read(hdr['entrySize'])
assert len(d) == hdr['entrySize']
blockSize = hdr['blockSize']
dName, d = d[0:16], d[16:]
dName = dName.rstrip(b'\x00').decode('ascii')
x = struct.unpack('>'+'I'*28, d[0:28*4])
base, size, pid, id, type, flags, actual, resv0, resv1, resv2, resv3 = x[0:11]
d = d[11:]
user = struct.unpack('>'+'I'*16, d[0:16*4])
(cksum,) = struct.unpack('>I', d[16*4:16*4+4])
if base > last_end:
print(' (gap: {0} blocks)'.format(base-last_end))
flagdec = ''
if (flags & 0x01) != 0:
flagdec += ' PROTECTED'
if (flags & 0x02) != 0:
flagdec += ' U_BOOT_ENV'
print('{dName:16} {base:#010x} {size:#010x} {pid:#010x} {id:#010x} {type:#010x} {flags:#010x} {flagdec}'.format(**locals()))
print(' r {resv0:#010x} {resv1:#010x} {resv2:#010x} {resv3:#010x} ck={cksum:#010x}'.format(**locals()))
i = 0
while len(user) > 0:
ex = ''
if i == 0:
ex = ' size {0}'.format(niceSize(size*blockSize))
elif i == 1:
ex = ' type {0:>13}'.format(types.get(type, str(type)))
elif i == 2:
ex = ' -s {0:#x} -n {1:#x}'.format(base*blockSize,size*blockSize)
i = i+1
print(' u {0:#010x} {1:#010x} {2:#010x} {3:#010x}{4}'.format(user[0],user[1],user[2],user[3],ex))
user = user[4:]
last_end = base+size
def run():
global last_end
with open('zaius.pnor', 'rb') as f:
hdr = read_hdr(f)
print_legend()
last_end = (12*4+hdr['entrySize']*hdr['entryCount']+hdr['blockSize'])//hdr['blockSize']
for i in range(hdr['entryCount']):
read_item(f, hdr)
return 0
if __name__ == '__main__':
sys.exit(run())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment