[read_info] Improved algorithm for generation a list of partitions

pull/24/head
remittor 1 year ago
parent 16052e69b0
commit 4de08dfd07

@ -166,19 +166,24 @@ class DevInfo():
mtdtbl = re.findall(r'mtd([0-9]+): ([0-9a-fA-F]+) ([0-9a-fA-F]+) "(.*?)"', mtd_list)
if len(mtdtbl) <= 1:
return [ ]
partlist = [ ]
mtd_max_num = len(mtdtbl) - 1
addr_list = self.get_part_addr_table(mtd_max_num, verbose)
mtd_max_num = -1
for i, mtd in enumerate(mtdtbl):
mtdid = int(mtd[0])
if mtdid > mtd_max_num:
mtd_max_num = mtdid
partlist = [ { 'addr': -1, 'size': -1, 'name': None } for i in range(mtd_max_num + 1) ]
mtd_info = self.get_part_info(mtd_max_num, verbose)
for i, mtd in enumerate(mtdtbl):
mtdid = int(mtd[0])
if mtdid != i:
raise ValueError(f"Incorrect mtd id = {mtdid}")
addr = -1
size = int(mtd[1], 16)
name = mtd[3]
if addr_list and len(addr_list) > 1:
addr = addr_list[i]
partlist.append( {'addr': addr, 'size': size, 'name': name} )
if mtd_info and mtdid < len(mtd_info):
if mtd_info[mtdid]["addr"] is not None:
addr = mtd_info[mtdid]["addr"]
partlist[mtdid]['addr'] = addr
partlist[mtdid]['size'] = size
partlist[mtdid]['name'] = name
pass
self.get_part_addr_dmesg(partlist)
if partlist[0]['addr'] < 0:
@ -188,7 +193,6 @@ class DevInfo():
if partlist[0]['addr'] == 0:
if partlist[0]['size'] > 0x00800000: # 8MiB:
self.allpartnum = 0 # detect "ALL" part
ro_list = self.get_part_readonly(mtd_max_num)
if self.verbose:
print("MTD partitions:")
err_addr = -1
@ -203,8 +207,9 @@ class DevInfo():
if self.dmesg and re.search(f'mounted UBI device ., volume ., name "{name}"', self.dmesg):
addr = 0xFFFFFFFF
part['addr'] = addr
if ro_list and ro_list[i] >= 0:
part['ro'] = False if ro_list[i] == 0 else True
if mtd_info and i < len(mtd_info):
if mtd_info[i]["ro"] is not None:
part['ro'] = False if mtd_info[i]["ro"] == 0 else True
if verbose:
xaddr = ("0x%08X" % addr) if addr >= 0 else "??????????"
ro = '?'
@ -220,49 +225,43 @@ class DevInfo():
self.partlist = partlist
return self.partlist
def get_part_addr_table(self, mtd_max_num, verbose = None):
def get_part_info(self, mtd_max_num, verbose = None):
verbose = verbose if verbose is not None else self.verbose
fn = 'mtd_addr.txt'
fn = 'mtd_info.txt'
mtd_dev = '/sys/class/mtd/mtd$i'
dn = '2>/dev/null'
trim = r"tr -d '\n'"
a2f = f"tee -ia /tmp/{fn}" # append to file
delim = f"echo -n '|' >> /tmp/{fn}"
cmd = f'rm -f /tmp/{fn} ;'
cmd += f'for i in $(seq 0 {mtd_max_num}) ; do'
cmd += f' echo "" >> /tmp/{fn} ;'
cmd += f' echo -n $i= >> /tmp/{fn} ;'
cmd += f' cat /sys/class/mtd/mtd$i/offset >> /tmp/{fn} ;'
cmd += f" cat {mtd_dev}/offset {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f" cat {mtd_dev}/type {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f" cat {mtd_dev}/flags {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f" cat {mtd_dev}/mtdblock$i/ro {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f" cat {mtd_dev}/dev {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f" readlink -f {mtd_dev}/device {dn} | {trim} | {a2f} ; {delim} ;"
cmd += f'done'
addr_table = self.run_command(cmd, fn)
if not addr_table:
out_text = self.run_command(cmd, fn)
if not out_text:
return [ ]
addr_list = [ -1 ] * (mtd_max_num + 1)
for line in addr_table.split('\n'):
info = [ { "addr": None, "ro": None } for i in range(mtd_max_num + 1) ]
for line in out_text.split('\n'):
line = line.strip()
if '=' in line:
data = line.split('=')
mtd_num = int(data[0])
if len(data[1]) >= 1:
addr_list[mtd_num] = int(data[1])
return addr_list
mtd_info = data[1].split('|')
info[mtd_num]["addr"] = int(mtd_info[0], 0) if len(mtd_info[0]) > 0 else None
info[mtd_num]["type"] = mtd_info[1].strip()
info[mtd_num]["flags"] = int(mtd_info[2], 0) if len(mtd_info[2]) > 0 else None
info[mtd_num]["ro"] = int(mtd_info[3], 0) if len(mtd_info[3]) > 0 else None
info[mtd_num]["dev"] = mtd_info[4].strip()
info[mtd_num]["device"] = mtd_info[5].strip()
return info
def get_part_readonly(self, mtd_max_num):
fn = 'mtd_ro.txt'
cmd = f'rm -f /tmp/{fn} ;'
cmd += f'for i in $(seq 0 {mtd_max_num}) ; do'
cmd += f' echo "" >> /tmp/{fn} ;'
cmd += f' echo -n $i= >> /tmp/{fn} ;'
cmd += f' cat /sys/class/mtd/mtd$i/mtdblock$i/ro >> /tmp/{fn} ;'
cmd += f'done'
ro_table = self.run_command(cmd, fn)
if not ro_table:
return [ ]
ro_list = [ -1 ] * (mtd_max_num + 1)
for line in ro_table.split('\n'):
line = line.strip()
if '=' in line:
data = line.split('=')
mtd_num = int(data[0])
if len(data[1]) >= 1:
ro_list[mtd_num] = int(data[1])
return ro_list
def get_part_num(self, name_or_addr, comptype = None):
if not self.partlist:
return -2

Loading…
Cancel
Save