diff --git a/read_info.py b/read_info.py index 30e232f..8fc8e5c 100644 --- a/read_info.py +++ b/read_info.py @@ -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