| #!/usr/bin/env python2 |
| # Copyright (c) 2014 Google Inc. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import struct |
| import sys |
| from io import SEEK_SET, SEEK_END |
| |
| class IDBTool: |
| def __init__(self): |
| print "Initialize IDBTool" |
| |
| def p_rc4(self, buf, length): |
| key = (124,78,3,4,85,5,9,7,45,44,123,56,23,13,23,17) |
| K = key * 16 |
| S = [i for i in range(256)] |
| |
| j = 0 |
| for i in range(256): |
| j = (j + S[i] + K[i]) % 256 |
| temp = S[i]; S[i] = S[j]; S[j] = temp; |
| |
| i = j = k = 0 |
| for x in range(length): |
| i = (i+1) % 256 |
| j = (j + S[i]) % 256 |
| temp = S[i]; S[i] = S[j]; S[j] = temp |
| k = (S[i] + S[j]) % 256 |
| buf[x] = struct.pack('B', ord(buf[x]) ^ S[k]) |
| |
| def makeIDB(self, chip, from_file, to_file, rc4_flag = False, align_flag = False): |
| try: |
| fin = open(from_file, 'rb') |
| except: |
| sys.exit("Failed to open file : " + from_file) |
| |
| try: |
| fin.seek(0, SEEK_END) |
| if (fin.tell() > 4 * 1024 * 1024): |
| sys.exit("Input file is more than 4MB") |
| fin.seek(0) |
| data = fin.read() |
| finally: |
| fin.close() |
| |
| data_len = len(data) |
| SECTOR_SIZE = 512 |
| PAGE_ALIGN = 4 |
| sectors = (data_len + 4 - 1) / SECTOR_SIZE + 1 |
| pages = (sectors - 1) / PAGE_ALIGN + 1 |
| sectors = pages * PAGE_ALIGN; |
| |
| buf = [B'\0'] * sectors * SECTOR_SIZE |
| buf[:4] = chip |
| buf[4 : 4+data_len] = data |
| |
| idblock = [B'\0'] * 4 * SECTOR_SIZE |
| blank = [B'\0'] * 4 * SECTOR_SIZE |
| idblock[:4] = ['\x55', '\xAA', '\xF0', '\x0F'] |
| |
| if (not rc4_flag): |
| idblock[8:12] = struct.pack("<I", 1) |
| else: |
| for i in range(sectors): |
| list_tmp = buf[SECTOR_SIZE*i : SECTOR_SIZE*(i+1)] |
| self.p_rc4(list_tmp, SECTOR_SIZE) |
| buf[SECTOR_SIZE*i : SECTOR_SIZE*(i+1)] = list_tmp |
| |
| idblock[12:16] = struct.pack("<HH", 4, 4); |
| idblock[506:510] = struct.pack("<HH", sectors, sectors); |
| self.p_rc4(idblock, SECTOR_SIZE) |
| |
| try: |
| fout = open(to_file, "wb+") |
| except: |
| sys.exit("Failed to open output file : " + to_file) |
| |
| try: |
| if (align_flag): |
| fout.write(''.join(idblock)) |
| fout.write(''.join(blank)) |
| |
| for s in xrange(0, sectors * SECTOR_SIZE, PAGE_ALIGN * SECTOR_SIZE): |
| fout.write(''.join(buf[s : s + PAGE_ALIGN * SECTOR_SIZE])) |
| fout.write(''.join(blank)) |
| else: |
| fout.write(''.join(idblock)) |
| fout.write(''.join(buf)) |
| fout.flush() |
| except: |
| sys.exit("Failed to write data to : " + to_file) |
| finally: |
| fout.close() |
| print "DONE" |
| |
| def usage(): |
| print "Usage: make_idb.py [--chip=RKXX] [--enable-rc4] [--enable-align] [--to=out] --from=in" |
| print " --chip: default is RK32" |
| |
| if __name__ == '__main__': |
| rc4_flag = align_flag = False |
| to_file = "IDBlock.bin" |
| chip = "RK32" |
| |
| for para in sys.argv[1:]: |
| if (para == "--enable-rc4"): |
| rc4_flag = True |
| elif (para == "--enable-align"): |
| align_flag = True |
| elif (para.startswith("--to=")): |
| to_file = para.split('=')[1] |
| elif (para.startswith("--from=")): |
| from_file = para.split('=')[1] |
| elif (para.startswith("--chip=")): |
| chip = para.split('=')[1] |
| elif (para == "--help" or para == "-h"): |
| usage() |
| sys.exit() |
| else: |
| usage() |
| sys.exit() |
| if ('from_file' not in vars() or to_file == ''): |
| usage() |
| sys.exit() |
| |
| idbtool = IDBTool() |
| idbtool.makeIDB(chip, from_file, to_file, rc4_flag, align_flag) |