blob: 8f37048ec052cab3f9c874c6fba1a827de6a3add [file] [log] [blame]
rjw03fe4c02022-02-16 10:40:11 +08001# SPDX-License-Identifier: MediaTekProprietary
xjb04a4022021-11-25 15:01:52 +08002#!/usr/bin/python
3
4import os
5import os.path
6import sys
7import platform
8import argparse
9import shlex
10import subprocess
11import time
12import re
13
14################################################################################
15# check python version
16if sys.hexversion >= 0x02070000:
17 pass
18else:
19 print('Please install Python 2.7.x or newer to run this script')
20 exit(1)
21
22# override input() in python2
23try:
24 input = raw_input
25except NameError:
26 pass
27
28################################################################################
29
30verbose = False
31for_nata = False
32skipFlash = False
33
34fbtool = 'fbtool.py'
35fastboot = 'fastboot'
36
37system = platform.system()
38machine = platform.machine()
39product_out = os.path.abspath('.')
40
41if 'Windows' in system or 'CYGWIN' in system:
42 fastboot += '.exe'
43elif 'Linux' in system:
44 if 'x86_64' in machine:
45 fastboot += '-linux-x86_64'
46 elif 'arm' in machine or 'aarch64' in machine:
47 fastboot += '-linux-arm'
48elif 'Darwin' in system:
49 fastboot += '-darwin'
50
51# Generate image list from procedure list
52
53
54def getImageList(procs):
55 imgs = []
56 try:
57 for p in procs:
58 if p[0] == 'fastboot' and p[1] == 'flash' and p[3] not in imgs:
59 imgs.append(p[3])
60 except Exception as e:
61 print(e)
62 return imgs
63
64
65def call(cmd):
66 '''cmd: the command list for subprocess.call'''
67 if verbose:
68 print('call:', ' '.join(cmd))
69 if for_nata is True:
70 return subprocess.call(cmd, stdout=sys.stdout, stderr=subprocess.STDOUT, shell=True)
71 else:
72 return subprocess.call(cmd)
73
74def check_output(cmd):
75 '''cmd: the command list for subprocess.check_output'''
76 if verbose:
77 print('check_output:', ' '.join(cmd))
78 return subprocess.check_output(formatArgsForSubprocess(cmd), stderr=subprocess.STDOUT)
79
80
81def checkImage(filename, needreboot=True, _verbose=False):
82 filepath = os.path.join(product_out, filename)
83 if os.path.exists(filepath):
84 if _verbose:
85 print(filename.rjust(39, ' ') + ':' + ' PASS')
86 return filepath
87 if needreboot:
88 print(filename.rjust(39, ' ') + ':' + ' FAIL')
89 if args.nata:
90 print('[AT] Image not exist!')
91 else:
92 call([fastboot, 'reboot'])
93 exit(1)
94 return None
95
96# return 0 if success
97
98
99def cmdRun(cmd, dryrun=False):
100 ret = 1
101 raw_cmd = []
102 if cmd[0] == 'daWait':
103 daWait()
104 print('')
105 return 0
106 elif cmd[0] == 'fbWait':
107 fbWait()
108 print('')
109 return 0
110 elif cmd[0] == 'fastboot': # processing fastboot commands
111 cmd[0] = fastboot
112 if cmd[1] == 'flash':
113 # check if image path exits and valid
114 filepath = checkImage(cmd[3], False, False)
115 if filepath != None:
116 if 'CYGWIN' in system:
117 p = subprocess.check_output(
118 'cygpath --absolute --mixed %s' % filepath)
119 if p:
120 filepath = p.strip()
121 raw_cmd += [cmd[0], cmd[1], cmd[2], filepath]
122 else:
123 raw_cmd += cmd
124 else:
125 print('FAIL: Unknown command!')
126 return -1
127 if dryrun:
128 print(' '.join(raw_cmd))
129 ret = 0
130 else:
131 ret = call(raw_cmd)
132 # Bypass fastboot continue
133 if cmd[1] == 'continue':
134 ret = 0
135 if ret == 0 and cmd[0] == 'fastboot' and cmd[1] == 'reboot-bootloader' and not dryrun:
136 fbWait()
137 return ret
138
139
140def daWait(secs=60):
141 print('Waiting for DA mode')
142 ret = None
143 for i in range(secs):
144 sys.stdout.write('.')
145 sys.stdout.flush()
146 time.sleep(1)
147 ret = check_output('python %s ' % fbtool)
148 if ret != None and len(ret) != 0:
149 print('')
150 print('datool - device detected: ')
151 break
rjw03fe4c02022-02-16 10:40:11 +0800152 if i == secs - 1:
153 print('No device detected. Please ensure that datool is running')
154 exit(1)
xjb04a4022021-11-25 15:01:52 +0800155
156
157def fbWait(secs=60):
158 print('Waiting for fastboot mode')
159 ret = None
160 for i in range(secs):
161 sys.stdout.write('.')
162 sys.stdout.flush()
163 time.sleep(1)
164 ret = check_output('%s devices' % fastboot)
165 if ret != None and len(ret) != 0:
166 print('')
167 print('Fastboot - device detected: %s' % (ret.split())[0])
168 break
rjw03fe4c02022-02-16 10:40:11 +0800169 if i == secs - 1:
170 print('No device detected. Please ensure that fastboot is running on the target device')
171 exit(1)
xjb04a4022021-11-25 15:01:52 +0800172
173
174def cmdReboot(toBootloader=True):
175 if toBootloader:
176 call([fastboot, 'reboot-bootloader'])
177 fbWait()
178 else:
179 call([fastboot, 'reboot'])
180
181
182def formatArgsForSubprocess(cmd):
183 if not 'Windows' in system:
184 return shlex.split(cmd)
185 else:
186 return cmd
187
188
189if __name__ == '__main__':
190 # parse args
191 parser = argparse.ArgumentParser(
192 description='''
193Auto device flasher, Python 2.7.x required
194''',
195 formatter_class=argparse.RawTextHelpFormatter)
196 parser.add_argument('partition', nargs='?', default='all',
197 help='partition to flash [default: all] , not include test partition')
198 parser.add_argument('-d', '--dryrun', action='store_true', default=False,
199 help='dryrun for debug, no image would be flashed')
200 parser.add_argument('-u', '--user', action='store_true', default=False,
201 help='Flash user data partition')
202 parser.add_argument('-b', '--boot', action='store_true', default=False,
203 help='Flash boot partition')
204 parser.add_argument('-t', '--test', action='store_true', default=False,
205 help='Flash test partition')
206 parser.add_argument('-v', '--verbose', action='store_true', default=False,
207 help='print more information while flashing')
208 parser.add_argument('-n', '--nata', action = 'store_true', default = False,
209 help = 'Flash image in nata')
210 parser.add_argument('--toolsdir', default=None,
211 help='''\
212The tools dir where to find fbtool and fastboot.
213Path priority order:
214 1. --toolsdir specified
215 2. current directory
216 3. $PATH
217''')
218 parser.add_argument('--productdir', default=None,
219 help='''\
220The product out directory where to find images.
221Path priority order:
222 1. --productdir specified
223 2. current directory
224''')
225
226 args = parser.parse_args()
227 verbose = args.verbose
228 if args.dryrun:
229 verbose = True
230
231 print('')
232 parser.print_usage()
233 print('')
234 print(''.center(80, '*'))
235 print(('Running flasher on ' + platform.platform()).center(80))
236 print(''.center(80, '*'))
237 print('')
238
239 if args.nata:
240 for_nata = True
241 args.toolsdir = os.path.abspath(os.path.dirname(__file__))
242 args.productdir = args.toolsdir
243 print ('[AT] Flash Dir: %s' %args.productdir)
244
245 try:
246 from flashproc import getFlashProc
247 except ImportError as e:
248 print('ImportError:', e)
249 print('')
250 exit(1)
251 try:
252 from flashproc import getFlashUserProc
253 except:
254 getFlashUserProc = getFlashProc
255 try:
256 from flashproc import getFlashBootProc
257 except:
258 getFlashBootProc = getFlashProc
259 try:
260 from flashproc import getFlashTestProc
261 except:
262 getFlashTestProc = getFlashProc
263
264 # check flash tools
265 toolsdir = ''
266 try:
267 if args.toolsdir:
268 toolsdir = os.path.abspath(args.toolsdir)
269 fbtool = os.path.join(toolsdir, fbtool)
270 fastboot = os.path.join(toolsdir, fastboot)
271 if not os.path.exists(fbtool) or not os.path.exists(fastboot):
272 raise Exception(str(toolsdir))
273 else:
274 toolsdir = os.path.abspath('.')
275 if os.path.exists(os.path.join(toolsdir, fbtool)) and os.path.exists(os.path.join(toolsdir, fastboot)):
276 fbtool = os.path.join(toolsdir, fbtool)
277 fastboot = os.path.join(toolsdir, fastboot)
278 except Exception as e:
279 print('Can not find fbtool or fastboot in %s' % str(e))
280 print('')
281 exit(1)
282
283 devProduct = 'DEFAULT'
284
285 procs = getFlashProc(devProduct)
286 if args.user:
287 procs = getFlashUserProc(devProduct)
288 if args.boot:
289 procs = getFlashBootProc(devProduct)
290 if args.test:
291 procs = getFlashTestProc(devProduct)
292 if procs:
293 if verbose:
294 print('Flash procedure'.center(80))
295 print(''.center(80, '-'))
296 for p in procs:
297 print('fastboot', ' '.join(p))
298 print('')
299 else:
300 print('Can not retrieve flash procedure according to product type of', devProduct)
301 print('Exit !')
302 exit(1)
303
304 # check image path
305 if args.productdir:
306 # take user specific product directory
307 product_out = os.path.abspath(args.productdir)
308 else:
309 # check current directory
310 product_out = os.path.abspath('.')
311 for img in getImageList(procs):
312 if checkImage(img, False, False) is None:
313 product_out = None
314 break
315 if product_out is None:
316 product_out = os.getenv('PRODUCT_OUT', '.')
317 product_out = os.path.abspath(product_out)
318
319 print(''.center(80, '*'))
320 print('* flash images under:'.ljust(79, ' ') + '*')
321 print('* ' + product_out.ljust(73, ' ') + '*')
322 print(''.center(80, '*'))
323 print('')
324
325 # check images
326 print('Checking image'.center(80))
327 print(''.center(80, '-'))
328 images = getImageList(procs)
329 try:
330 for img in images:
331 checkImage(img, _verbose=True)
332 except Exception as e:
333 print(e)
334 time.sleep(2)
335 if args.nata:
336 print ('[AT] Check image fail, stop to flash!')
337 else:
338 cmdReboot(False)
339 input('Fail, press enter to exit: ')
340 exit(1)
341 # For NATA
342 if args.nata:
343 #POWER OFF
344 print ('[AT] POWER PIN KEY:0, %s' %time.ctime())
345 time.sleep(2)
346 #PRESS DOWNLOAD KEY
347 print ('[AT] DOWNLOAD KEY:1, %s' %time.ctime())
348 time.sleep(2)
349 #POWER ON
350 print ('[AT] POWER PIN KEY:1, %s' %time.ctime())
351 time.sleep(2)
352
353 # align 4kb for modem related images
354 os.system('python align_4kb.py \"%s\"' % checkImage('md1img.img', False, False))
355 os.system('python align_4kb.py \"%s\"' % checkImage('md1dsp.img', False, False))
356
357 # flash images
358 print('')
359 print('Start flashing'.center(80))
360 print(''.center(80, '-'))
361 try:
362 for proc in procs:
363 if skipFlash == False:
364 if 0 != cmdRun(proc, args.dryrun):
365 raise Exception('<<FAILED>> %s' % ' '.join(proc))
366 else:
367 if proc[0] == 'fastboot' and proc[1] == 'flash':
368 print('Skip flashing', proc[3])
369 except Exception as e:
370 print(e)
371 if args.nata:
372 #RELEASE DOWNLOAD KEY
373 print ('[AT] DOWNLOAD KEY:0, %s' %time.ctime())
374 time.sleep(2)
375 time.sleep(2)
376 cmdReboot(False)
377 exit(1)
378
379 if args.nata:
380 #RELEASE DOWNLOAD KEY
381 print ('[AT] DOWNLOAD KEY:0, %s' %time.ctime())
rjw03fe4c02022-02-16 10:40:11 +0800382 sys.stdout.flush()
xjb04a4022021-11-25 15:01:52 +0800383 time.sleep(2)
384 time.sleep(2)
385 cmdReboot(False)
386 print('')
387 if args.nata:
388 print ('[AT] Flash Success')
389 else:
390 print('Success')