mirror of
https://github.com/openwrt-xiaomi/xmir-patcher.git
synced 2026-09-22 22:57:55 +03:00
[read_info] Add reading MTD info from flattened device tree
This commit is contained in:
+73
-10
@@ -166,11 +166,7 @@ class DevInfo():
|
||||
mtdtbl = re.findall(r'mtd([0-9]+): ([0-9a-fA-F]+) ([0-9a-fA-F]+) "(.*?)"', mtd_list)
|
||||
if len(mtdtbl) <= 1:
|
||||
return [ ]
|
||||
mtd_max_num = -1
|
||||
for i, mtd in enumerate(mtdtbl):
|
||||
mtdid = int(mtd[0])
|
||||
if mtdid > mtd_max_num:
|
||||
mtd_max_num = mtdid
|
||||
mtd_max_num = max( [ int(mtd[0]) for i, mtd in enumerate(mtdtbl) ] )
|
||||
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):
|
||||
@@ -193,20 +189,26 @@ class DevInfo():
|
||||
if partlist[0]['addr'] == 0:
|
||||
if partlist[0]['size'] > 0x00800000: # 8MiB:
|
||||
self.allpartnum = 0 # detect "ALL" part
|
||||
fdt_info = self.get_part_from_fdt(partlist, verbose)
|
||||
if self.verbose:
|
||||
print("MTD partitions:")
|
||||
err_addr = -1
|
||||
for i, part in enumerate(partlist):
|
||||
size = part['size']
|
||||
name = part['name']
|
||||
addr = part['addr']
|
||||
if addr < 0:
|
||||
if part['addr'] < 0:
|
||||
if name in fdt_info:
|
||||
if size == fdt_info[name]['size']:
|
||||
part['addr'] = fdt_info[name]['addr']
|
||||
if part['addr'] < 0:
|
||||
if name == "m25p80":
|
||||
addr = 0xFFFFFFFF
|
||||
part['addr'] = 0xFFFFFFFF
|
||||
else:
|
||||
if self.dmesg and re.search(f'mounted UBI device ., volume ., name "{name}"', self.dmesg):
|
||||
addr = 0xFFFFFFFF
|
||||
part['addr'] = addr
|
||||
part['addr'] = 0xFFFFFFFF
|
||||
if part['addr'] < 0 and fdt_info:
|
||||
part['addr'] = 0xFFFFFFFF
|
||||
addr = part['addr']
|
||||
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
|
||||
@@ -262,6 +264,67 @@ class DevInfo():
|
||||
info[mtd_num]["device"] = mtd_info[5].strip()
|
||||
return info
|
||||
|
||||
def get_part_from_fdt(self, partlist, verbose = None):
|
||||
verbose = verbose if verbose is not None else self.verbose
|
||||
fn = 'mtd_fdt.txt'
|
||||
fdtpath = '/sys/firmware/devicetree/base/**/'
|
||||
execgrep = '-exec grep -l "^fixed-partitions" {} +'
|
||||
hexfmt = "'1/1 \"%02x\"'"
|
||||
trim = r"tr -d '\n'"
|
||||
cmd = f'fn=/tmp/{fn};'
|
||||
cmd += f'rm -f $fn;'
|
||||
cmd += f'dlist=$( find {fdtpath} -type f -name compatible {execgrep} );'
|
||||
cmd += f'[ -z "$dlist" ] && dlist=$( find {fdtpath} -type f -name nand-bus-width );'
|
||||
cmd += f'for trgfile in $dlist ; do'
|
||||
cmd += f' bdir=$( dirname $trgfile );'
|
||||
cmd += f' echo "" >>$fn;'
|
||||
cmd += f' echo "PARTLIST:$bdir" >>$fn;'
|
||||
cmd += f' plist=$( find $bdir/**/ -mindepth 1 -maxdepth 1 -type f -name label );'
|
||||
cmd += f' for label in $plist ; do'
|
||||
cmd += f' pdir=$( dirname $label );'
|
||||
cmd += f' preg=$( cat $pdir/reg | hexdump -v -n8 -e {hexfmt} );' # bigendian
|
||||
cmd += ' echo "0x${preg:0:8}|0x${preg:8:8}|$(cat $label | tr -d ''\\n'')" >>$fn;'
|
||||
cmd += f' done;'
|
||||
cmd += f'done'
|
||||
fdt_text = self.run_command(cmd, fn)
|
||||
if not fdt_text:
|
||||
return { }
|
||||
fdt_dev = [ ]
|
||||
mtd_list = None
|
||||
for line in fdt_text.split('\n'):
|
||||
line = line.strip()
|
||||
if line.startswith('PARTLIST:'):
|
||||
if mtd_list:
|
||||
fdt_dev.append(mtd_list)
|
||||
mtd_list = { }
|
||||
if line.startswith('0x'):
|
||||
data = line.split('|')
|
||||
name = data[2].strip()
|
||||
if name:
|
||||
mtd_list[name] = { 'addr': int(data[0], 0), 'size': int(data[1], 0) }
|
||||
if mtd_list:
|
||||
fdt_dev.append(mtd_list)
|
||||
if not fdt_dev:
|
||||
return { }
|
||||
if len(fdt_dev) == 1:
|
||||
return fdt_dev[0]
|
||||
scores = [ 0 ] * len(fdt_dev)
|
||||
for i, mtd_list in enumerate(fdt_dev):
|
||||
for _, (name, mtd) in enumerate(mtd_list.items()):
|
||||
for part in partlist:
|
||||
if part['name'] == name and part['size'] == mtd['size']:
|
||||
if part['addr'] == mtd['addr']:
|
||||
scores[i] += 1
|
||||
elif part['addr'] < 0:
|
||||
pass #nothing
|
||||
else:
|
||||
scores[i] -= 1
|
||||
max_scores = max(scores)
|
||||
if max_scores <= 0:
|
||||
return { }
|
||||
devnum = scores.index(max_scores)
|
||||
return fdt_dev[devnum]
|
||||
|
||||
def get_part_num(self, name_or_addr, comptype = None):
|
||||
if not self.partlist:
|
||||
return -2
|
||||
|
||||
Reference in New Issue
Block a user