| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -166,11 +166,7 @@ class DevInfo():
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    mtdtbl = re.findall(r'mtd([0-9]+): ([0-9a-fA-F]+) ([0-9a-fA-F]+) "(.*?)"', mtd_list)
 | 
					 | 
					 | 
					 | 
					    mtdtbl = re.findall(r'mtd([0-9]+): ([0-9a-fA-F]+) ([0-9a-fA-F]+) "(.*?)"', mtd_list)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if len(mtdtbl) <= 1:
 | 
					 | 
					 | 
					 | 
					    if len(mtdtbl) <= 1:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return [ ]
 | 
					 | 
					 | 
					 | 
					      return [ ]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    mtd_max_num = -1
 | 
					 | 
					 | 
					 | 
					    mtd_max_num = max( [ int(mtd[0]) for i, mtd in enumerate(mtdtbl) ] )
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    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) ]
 | 
					 | 
					 | 
					 | 
					    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)
 | 
					 | 
					 | 
					 | 
					    mtd_info = self.get_part_info(mtd_max_num, verbose)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for i, mtd in enumerate(mtdtbl):
 | 
					 | 
					 | 
					 | 
					    for i, mtd in enumerate(mtdtbl):
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -193,20 +189,26 @@ class DevInfo():
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if partlist[0]['addr'] == 0:
 | 
					 | 
					 | 
					 | 
					    if partlist[0]['addr'] == 0:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if partlist[0]['size'] > 0x00800000:  # 8MiB:
 | 
					 | 
					 | 
					 | 
					      if partlist[0]['size'] > 0x00800000:  # 8MiB:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.allpartnum = 0  # detect "ALL" part
 | 
					 | 
					 | 
					 | 
					        self.allpartnum = 0  # detect "ALL" part
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    fdt_info = self.get_part_from_fdt(partlist, verbose)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self.verbose:
 | 
					 | 
					 | 
					 | 
					    if self.verbose:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      print("MTD partitions:")
 | 
					 | 
					 | 
					 | 
					      print("MTD partitions:")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    err_addr = -1
 | 
					 | 
					 | 
					 | 
					    err_addr = -1
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for i, part in enumerate(partlist):
 | 
					 | 
					 | 
					 | 
					    for i, part in enumerate(partlist):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      size = part['size']
 | 
					 | 
					 | 
					 | 
					      size = part['size']
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      name = part['name']
 | 
					 | 
					 | 
					 | 
					      name = part['name']
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      addr = part['addr']
 | 
					 | 
					 | 
					 | 
					      if part['addr'] < 0:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if 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":
 | 
					 | 
					 | 
					 | 
					        if name == "m25p80":
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          addr = 0xFFFFFFFF
 | 
					 | 
					 | 
					 | 
					          part['addr'] = 0xFFFFFFFF
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        else:
 | 
					 | 
					 | 
					 | 
					        else:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if self.dmesg and re.search(f'mounted UBI device ., volume ., name "{name}"', self.dmesg):
 | 
					 | 
					 | 
					 | 
					          if self.dmesg and re.search(f'mounted UBI device ., volume ., name "{name}"', self.dmesg):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            addr = 0xFFFFFFFF
 | 
					 | 
					 | 
					 | 
					            part['addr'] = 0xFFFFFFFF
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        part['addr'] = addr
 | 
					 | 
					 | 
					 | 
					      if part['addr'] < 0 and fdt_info:
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        part['addr'] = 0xFFFFFFFF
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      addr = part['addr']
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if mtd_info and i < len(mtd_info):
 | 
					 | 
					 | 
					 | 
					      if mtd_info and i < len(mtd_info):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if mtd_info[i]["ro"] is not None:
 | 
					 | 
					 | 
					 | 
					        if mtd_info[i]["ro"] is not None:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          part['ro'] = False if mtd_info[i]["ro"] == 0 else True
 | 
					 | 
					 | 
					 | 
					          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()
 | 
					 | 
					 | 
					 | 
					        info[mtd_num]["device"] = mtd_info[5].strip()
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return info    
 | 
					 | 
					 | 
					 | 
					    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):
 | 
					 | 
					 | 
					 | 
					  def get_part_num(self, name_or_addr, comptype = None):
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if not self.partlist:
 | 
					 | 
					 | 
					 | 
					    if not self.partlist:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return -2
 | 
					 | 
					 | 
					 | 
					      return -2
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |