blob: a6acb1a28c8437da1649d9efc3089cc7fb03fde5 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#!/usr/bin/env python
2
3import argparse
4import sys
5import os
6import math
7import shutil
8import pp_tbl
9import gen_nand_header
10import gen_nand_header_v11
11import randomizer
12from pad_ecc_by_sector import pad_ecc
13from randomizer import randomizer
14
15def padding(data, size):
16 return data + '\0' * (size - len(data))
17
18def main(argv):
19 parser = argparse.ArgumentParser()
20 parser.add_argument('nand_name', help = 'nand device name')
21 parser.add_argument('in_image', help = 'raw input image')
22 parser.add_argument('out_image', help = 'the output burn image ')
23 parser.add_argument('version', help= 'nand header version')
24 parser.add_argument('rand_en', help = 'if randomizer is enabled')
25 args = parser.parse_args()
26 version = float(args.version)
27 rand_en = int(args.rand_en)
28
29 if version == 2.0:
30 (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header.gen_header(args.nand_name)
31 bad_swap = 1
32 elif version == 1.1:
33 (vendor, fdm_size, fdmecc_size, ecc_strength, spare_size, page_size, ppen, ppb) = gen_nand_header_v11.gen_header(args.nand_name, 192, args.nand_name + '_header.bin')
34 bad_swap = 0
35
36 ecc_file = args.out_image
37 rand_file = args.out_image
38 if rand_en == 1:
39 ecc_file = args.nand_name + '_ecc.bin'
40 if ppen == 1:
41 paired = raw_input("insert empty paired page ? Y/y or N/n ")
42 if paired in ['Y', 'y']:
43 rand_file = args.nand_name + '_rand.bin'
44 ecc_file = args.nand_name + '_ecc.bin'
45 sector_size = 1024 if page_size > 512 else 512
46 sector_per_page = page_size / sector_size
47 sector_spare_size = spare_size / sector_per_page
48 # input image page size alignment #
49 file_len = os.path.getsize(args.in_image)
50 pages = int(math.ceil(float(file_len) / page_size))
51 in_file = "temp_in.bin"
52 with open(args.in_image, "rb") as f_in:
53 with open(in_file, "wb") as f_temp:
54 f_temp.write(padding(f_in.read(), pages * page_size))
55 pad_ecc(in_file, ecc_file, sector_size, fdm_size, fdmecc_size, ecc_strength, sector_spare_size, page_size, bad_swap)
56
57 if rand_en == 1:
58 randomizer(ecc_file, rand_file, "SS", 1, page_size, spare_size, sector_size, ppb, ppen, vendor)
59
60 # MT8516 force sector spare size from 56, 54, to be 52
61 if version == 1.1:
62 # spare settings must match 8516 BOOT ROM, The sector size default is 1024 bytes.
63 SPARES = [32, 52, 64, 80, 88, 96, 100, 104, 122, 124]
64 sector_spare_size_adjust = sector_spare_size
65
66 for i in range(len(SPARES)):
67 if (sector_spare_size <= SPARES[i]):
68 if sector_spare_size == SPARES[i]:
69 sector_spare_size_adjust = SPARES[i]
70 if (sector_spare_size < SPARES[i]) and (i != 0):
71 sector_spare_size_adjust = SPARES[i - 1]
72 break
73 k = 0
74 pad_data = (sector_spare_size - sector_spare_size_adjust) * sector_per_page
75 adjust_file = rand_file + '_adjust'
76 f_in = open(rand_file, "rb")
77 f_out = open(adjust_file, "wb")
78 for i in range(pages * sector_per_page):
79 f_in.seek(((sector_size + sector_spare_size) * i), 0)
80 sector_data = f_in.read(sector_size + sector_spare_size_adjust)
81 if (i % sector_per_page) == (sector_per_page - 1):
82 sector_data += '\xff' * pad_data
83 if (i) > 0 and (i % sector_per_page) == 0:
84 k = k + 1
85 f_out.seek(((sector_size + sector_spare_size) * i), 0)
86 else:
87 f_out.seek((sector_size + sector_spare_size_adjust) * i + (k * pad_data), 0)
88
89 f_out.write(sector_data)
90
91 f_in.close()
92 f_out.close()
93 shutil.copyfile(adjust_file, rand_file)
94 # remove temp files #
95 os.remove(adjust_file)
96 # insert empty paired page #
97 if ppen == 1 and paired in ['Y', 'y']:
98 if rand_en == 1:
99 pp_file = rand_file
100 else:
101 pp_file = ecc_file
102 if vendor == 'TSB':
103 PP = pp_tbl.TSB_PP
104 else:
105 raise Exception("unsupport %s pp table " % vendor)
106 f_pp = open(pp_file, "rb")
107 f_out = open(args.out_image, "wb")
108
109 if (os.path.getsize(in_file) % page_size) != 0:
110 raise Exception("input image size is not page size aligned")
111 page_number = os.path.getsize(in_file) / page_size
112 block_number = int(math.ceil(float(page_number) / (ppb / 2)))
113 print "page num %d block num %d" % (page_number, block_number)
114 for i in range(ppb * block_number):
115 if page_number > 0 and (i % ppb) in PP:
116 f_out.write(f_pp.read(page_size + spare_size))
117 page_number -= 1
118 else:
119 f_out.write('\xff' * (page_size + spare_size))
120 f_pp.close()
121 f_out.close()
122 # remove temp files #
123 os.remove(pp_file)
124
125 if rand_en == 1:
126 os.remove(ecc_file)
127
128 # remove temp files #
129 os.remove(args.nand_name + '_header.bin')
130 os.remove(in_file)
131
132if __name__ == "__main__":
133 sys.exit(main(sys.argv))