#iphone devtree decoder by roxfanimport struct, re, binasciidef getDWord(f): return struct.unpack("<I",f.read(4))[0];def strDWord(s, pos=0): return struct.unpack("<I",s[pos:pos+4])[0];def parseDTProp(f, ident): name = f.read(32).rstrip('\0') l = getDWord(f) val = f.read(l) m = re.search(r"[\x00-\x1F\x80-\xFF]+", val) val1 = val #print m if m: if name=="compatible": val1 = val.replace('\0',";") elif name in ["name", "device_type"] or (m.start()==l-1 and val[m.start()]=='\0' and l!=4): val1 = val.rstrip('\0') elif l%4==0: v = "" for i in xrange(l/4): v+="0x%08X "%strDWord(val, i*4) val1 = v.rstrip(" ") else: val1 = binascii.hexlify(val) print ident, "%s=(%d)%s"%(name, l, val1) if (l%4): f.read(4-l%4) return name, l, valdef parseDTProp2(f): name = f.read(32).rstrip('\0') l = getDWord(f) val = f.read(l) if (l%4): f.read(4-l%4) return name, l, valdef parseDTEntry(f, ident): nProperties = getDWord(f) nChildren = getDWord(f) print ident, "<%d props>"%nProperties for p in xrange(nProperties): parseDTProp(f, ident) print ident, "<%d children>"%nChildren for c in xrange(nChildren): parseDTEntry(f, ident+" ")handlemap = {}def strtodwords(s): d = [] for i in xrange(len(s)/4): d.append(strDWord(s, i*4)) return dclass DTEntry: def __init__(self, f, parent = None, ident = ""): nProperties = getDWord(f) nChildren = getDWord(f) print ident, "<%d props>"%nProperties for p in xrange(nProperties): name, l, val = parseDTProp(f, ident) setattr(self, name, val) if parent and hasattr(self, "name"): self.name = self.name.rstrip('\0') self.path = parent.path + "/" + self.name else: self.path = "" if hasattr(self, "AAPL,phandle"): handlemap[strDWord(getattr(self, "AAPL,phandle"))] = self if hasattr(self, "ranges"): self.rlow = strDWord(self.ranges, 0) self.rstart = strDWord(self.ranges, 4) self.rlen = strDWord(self.ranges, 8) if parent and hasattr(parent, "rstart"): self.rstart += parent.rstart print "%s: base = %08X"%(self.path, self.rstart) if hasattr(self, "reg"): if parent and hasattr(parent, "rstart"): for i in xrange(len(self.reg)/8): regbase = strDWord(self.reg, i*8) reglen = strDWord(self.reg, i*8+4) print "%s: %08X:%08X"%(self.path, parent.rstart+regbase, reglen) self.parent = parent self.children = [] print ident, "<%d children>"%nChildren for c in xrange(nChildren): self.children.append(DTEntry(f, self, ident+" ")) def getpath(self): return self.path or "/" def getfullname(self): v = self.getpath() if hasattr(self, "device_type"): v+= " [%s]"%getattr(self, "device_type").rstrip('\0') return v def getfuncs(self): f = {} for a in self.__dict__: if a.startswith("function-"): f[a[9:]] = strtodwords(self.__dict__[a]) return f def dwattr(self, name, i=0): return strDWord(getattr(self, name), i*4) def dwlist(self, name, i=0): return strtodwords(getattr(self, name))def fourcc2str(dw): return chr(dw>>24)+chr((dw>>16)&0xFF)+chr((dw>>8)&0xFF)+chr(dw&0xFF)def hexlist(lst): s = "" for i in lst: s+="0x%08X, "%i if len(s): s=s[:-2] return sdt = file("DeviceTree.m68ap.img2","rb")dt.seek(0xc00)root = DTEntry(dt)gpio_funcs = {}int_map = {}dma_map = {}clock_map = {}for h in sorted(handlemap.keys()): o = handlemap[h] print "%08X: %s"%(h, o.getfullname()) fns = o.getfuncs() for fname in fns: fn = fns[fname] tag = fourcc2str(fn[1]) print "\t%s = %s['%s'](%s)"%(fname, handlemap[fn[0]].getpath(), tag, hexlist(fn[2:])) if tag=='GPIO': gpio_funcs[fn[2]] = "gpio_%s_%s"%(o.name, fname) if hasattr(o, "interrupt-parent"): parent = handlemap[o.dwattr("interrupt-parent")] print "\tinterrupt-parent = %s"%parent.getpath() if not parent in int_map: int_map[parent]={} for int in o.dwlist("interrupts"): int_map[parent][int] = o if hasattr(o, "clock-gates"): ids = o.dwlist("clock-ids") i = 0 for clk in o.dwlist("clock-gates"): id = ids[i] if not id in clock_map: clock_map[id]={} clock_map[id][clk] = o i+=0 if hasattr(o, "dma-parent"): parent = handlemap[o.dwattr("dma-parent")] print "\tdma-parent = %s"%parent.getpath() if not parent in dma_map: dma_map[parent]={} for dma in o.dwlist("dma-channels"): dma_map[parent][dma] = oprint "<gpio>"for f in sorted(gpio_funcs.keys()): print "0x%0X = %s"%(f, gpio_funcs[f])for o in int_map: print "<interrupts for %s>"%o.getpath() for p in sorted(int_map[o].keys()): print "\tint %08X = %s"%(p, int_map[o][p].getpath())for o in dma_map: print "<dma channels for %s>"%o.getpath() for p in sorted(dma_map[o].keys()): print "\tdma %08X = %s"%(p, dma_map[o][p].getpath())for id in sorted(clock_map.keys()): print "<clock gates for clock id %d>"%id for p in sorted(clock_map[id].keys()): print "\tgate %08X = %s"%(p, clock_map[id][p].getpath())