blob: df913de8089335739bf4d8508cc7bf89dcd109d3 [file] [log] [blame]
Simon Glass02741682013-05-26 07:07:58 -07001# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""crosfw - Chrome OS Firmware build/flash script.
6
7Builds a firmware image for any board and writes it to the board. The image
8can be pure upstream or include Chrome OS components (-V). Some device
9tree parameters can be provided, including silent console (-C) and secure
10boot (-S). Use -i for a faster incremental build. The image is written to
11the board by default using USB/em100 (or sdcard with -x). Use -b to specify
12the board to build. Options can be added to ~/.crosfwrc - see the script for
13details.
14
15It can also flash SPI by writing a 'magic flasher' U-Boot with a payload
16to the board.
17
Simon Glass02741682013-05-26 07:07:58 -070018The script is normally run from within the U-Boot directory which is
19.../src/third_party/u-boot/files
20
21Example 1: Build upstream image for coreboot and write to a 'link':
22
23 crosfw -b link
24
25Example 2: Build verified boot image (V) for daisy/snow and boot in secure
26 mode (S) so that breaking in on boot is not possible.
27
28 crosfw -b daisy -VS
29 crosfw -b daisy -VSC (no console output)
30
31Example 3: Build a magic flasher (F) with full verified boot for peach_pit,
32 but with console enabled, write to SD card (x)
33
34 crosfw -b peach_pit -VSFx
35
36This sript does not use an ebuild. It does a similar thing to the
37chromeos-u-boot ebuild, and runs cros_bundle_firmware to produce various
38types of image, a little like the chromeos-bootimage ebuild.
39
40The purpose of this script is to make it easier and faster to perform
41common firmware build tasks without changing boards, manually updating
42device tree files or lots of USE flags and complexity in the ebuilds.
43
44This script has been tested with snow, link and peach_pit. It builds for
45peach_pit by default. Note that it will also build any upstream ARM
46board - e.g. "-b snapper9260" will build an image for that board.
47
48Mostly you can use the script inside and outside the chroot. The main
49limitation is that dut-control doesn't really work outside the chroot,
50so writing the image to the board over USB is not possible, nor can the
51board be automatically reset on x86 platforms.
52
53For an incremental build (faster), run with -i
54
55To get faster clean builds, install ccache, and create ~/.crosfwrc with
56this line:
57
Simon Glass6ddc7f12013-07-18 15:22:41 -060058 USE_CCACHE = True
Simon Glass02741682013-05-26 07:07:58 -070059
60(make sure ~/.ccache is not on NFS, or set CCACHE_DIR)
61
62Other options are the default board to build, and verbosity (0-4), e.g.:
63
Simon Glass6ddc7f12013-07-18 15:22:41 -060064 DEFAULT_BOARD = 'daisy'
65 VERBOSE = 1
Simon Glass02741682013-05-26 07:07:58 -070066
67It is possible to use multiple servo boards, each on its own port. Add
68these lines to your ~/.crosfwrc to set the servo port to use for each
69board:
70
71 SERVO_PORT['link'] = 8888
72 SERVO_PORT['daisy'] = 9999
73 SERVO_PORT['peach_pit'] = 7777
74
Simon Glassb89ae892013-07-18 15:23:35 -060075All builds appear in the <outdir>/<board> subdirectory and images are written
76to <outdir>/<uboard>/out, where <uboard> is the U-Boot name for the board (in
77the U-Boot boards.cfg file)
78
79The value for <outdir> defaults to /tmp/crosfw but can be configured in your
80~/.crosfwrc file, e.g.:"
81
82 OUT_DIR = '/tmp/u-boot'
Simon Glass02741682013-05-26 07:07:58 -070083
84For the -a option here are some useful options:
85
86--add-blob cros-splash /dev/null
87--gbb-flags -force-dev-switch-on
88--add-node-enable /spi@131b0000/cros-ecp@0 1
89--verify --full-erase
90--bootcmd "cros_test sha"
91--gbb-flags -force-dev-switch-on
92--bmpblk ~/trunk/src/third_party/u-boot/bmp.bin
93
94For example: -a "--gbb-flags -force-dev-switch-on"
95
96Note the standard bmpblk is at:
97 /home/$USER/trunk/src/third_party/chromiumos-overlay/sys-boot/
98 chromeos-bootimage/files/bmpblk.bin"
99"""
100
Mike Frysinger383367e2014-09-16 15:06:17 -0400101from __future__ import print_function
102
Simon Glass02741682013-05-26 07:07:58 -0700103import glob
Simon Glass02741682013-05-26 07:07:58 -0700104import multiprocessing
105import os
106import re
107import sys
108
Aviv Keshetb7519e12016-10-04 00:50:00 -0700109from chromite.lib import constants
Simon Glass02741682013-05-26 07:07:58 -0700110from chromite.lib import commandline
111from chromite.lib import cros_build_lib
Ralph Nathan91874ca2015-03-19 13:29:41 -0700112from chromite.lib import cros_logging as logging
Simon Glass02741682013-05-26 07:07:58 -0700113from chromite.lib import osutils
114from chromite.lib import parallel
115
116
117arch = None
118board = None
119compiler = None
120default_board = None
121family = None
122in_chroot = True
123
Simon Glass02741682013-05-26 07:07:58 -0700124logging.basicConfig(format='%(message)s')
125kwargs = {'print_cmd': False, 'error_code_ok': True,
Ralph Nathan23a12212015-03-25 10:27:54 -0700126 'debug_level': logging.getLogger().getEffectiveLevel()}
Simon Glass02741682013-05-26 07:07:58 -0700127
128outdir = ''
129
130 # If you have multiple boards connected on different servo ports, put lines
131# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
132SERVO_PORT = {}
133
134smdk = None
135src_root = os.path.join(constants.SOURCE_ROOT, 'src')
136in_chroot = cros_build_lib.IsInsideChroot()
137
138uboard = ''
139
140default_board = 'peach_pit'
141use_ccache = False
142vendor = None
143verbose = False
144
145# Special cases for the U-Boot board config, the SOCs and default device tree
146# since the naming is not always consistent.
147# x86 has a lot of boards, but to U-Boot they are all the same
148UBOARDS = {
149 'daisy': 'smdk5250',
150 'peach': 'smdk5420',
151}
152for b in ['alex', 'butterfly', 'emeraldlake2', 'link', 'lumpy', 'parrot',
153 'stout', 'stumpy']:
154 UBOARDS[b] = 'coreboot-x86'
155 UBOARDS['chromeos_%s' % b] = 'chromeos_coreboot'
156
157SOCS = {
158 'coreboot-x86': '',
159 'chromeos_coreboot': '',
160 'daisy': 'exynos5250-',
161 'peach': 'exynos5420-',
162}
163
164DEFAULT_DTS = {
165 'daisy': 'snow',
166 'daisy_spring': 'spring',
167 'peach_pit': 'peach-pit',
168}
169
Simon Glassb89ae892013-07-18 15:23:35 -0600170OUT_DIR = '/tmp/crosfw'
171
Simon Glass02741682013-05-26 07:07:58 -0700172rc_file = os.path.expanduser('~/.crosfwrc')
173if os.path.exists(rc_file):
174 execfile(rc_file)
175
176
177def Log(msg):
178 """Print out a message if we are in verbose mode.
179
180 Args:
181 msg: Message to print
182 """
183 if verbose:
Ralph Nathan03047282015-03-23 11:09:32 -0700184 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700185
186
187def Dumper(flag, infile, outfile):
188 """Run objdump on an input file.
189
190 Args:
191 flag: Flag to pass objdump (e.g. '-d').
192 infile: Input file to process.
193 outfile: Output file to write to.
194 """
195 result = cros_build_lib.RunCommand(
196 [CompilerTool('objdump'), flag, infile],
197 log_stdout_to_file=outfile, **kwargs)
198 if result.returncode:
199 sys.exit()
200
201
202def CompilerTool(tool):
203 """Returns the cross-compiler tool filename.
204
205 Args:
206 tool: Tool name to return, e.g. 'size'.
207
208 Returns:
209 Filename of requested tool.
210 """
211 return '%s%s' % (compiler, tool)
212
213
214def ParseCmdline(argv):
215 """Parse all command line options.
216
217 Args:
218 argv: Arguments to parse.
219
220 Returns:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400221 The parsed options object
Simon Glass02741682013-05-26 07:07:58 -0700222 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400223 parser = commandline.ArgumentParser(description=__doc__)
224 parser.add_argument('-a', '--cbfargs', action='append',
225 help='Pass extra arguments to cros_bundle_firmware')
226 parser.add_argument('-b', '--board', type=str, default=default_board,
227 help='Select board to build (daisy/peach_pit/link)')
228 parser.add_argument('-B', '--build', action='store_false', default=True,
229 help="Don't build U-Boot, just configure device tree")
230 parser.add_argument('-C', '--console', action='store_false', default=True,
231 help='Permit console output')
232 parser.add_argument('-d', '--dt', default='seaboard',
233 help='Select name of device tree file to use')
234 parser.add_argument('-D', '--nodefaults', dest='use_defaults',
235 action='store_false', default=True,
236 help="Don't select default filenames for those not given")
237 parser.add_argument('-F', '--flash', action='store_true', default=False,
238 help='Create magic flasher for SPI flash')
239 parser.add_argument('-M', '--mmc', action='store_true', default=False,
240 help='Create magic flasher for eMMC')
241 parser.add_argument('-i', '--incremental', action='store_true', default=False,
242 help="Don't reconfigure and clean")
243 parser.add_argument('-k', '--kernel', action='store_true', default=False,
244 help='Send kernel to board also')
245 parser.add_argument('-O', '--objdump', action='store_true', default=False,
246 help='Write disassembly output')
247 parser.add_argument('-r', '--run', action='store_false', default=True,
248 help='Run the boot command')
249 parser.add_argument('--ro', action='store_true', default=False,
250 help='Create Chrome OS read-only image')
251 parser.add_argument('--rw', action='store_true', default=False,
252 help='Create Chrome OS read-write image')
253 parser.add_argument('-s', '--separate', action='store_false', default=True,
254 help='Link device tree into U-Boot, instead of separate')
255 parser.add_argument('-S', '--secure', action='store_true', default=False,
256 help='Use vboot_twostop secure boot')
257 parser.add_argument('--small', action='store_true', default=False,
258 help='Create Chrome OS small image')
259 parser.add_argument('-t', '--trace', action='store_true', default=False,
260 help='Enable trace support')
261 parser.add_argument('-v', '--verbose', type=int, default=0,
262 help='Make cros_bundle_firmware verbose')
263 parser.add_argument('-V', '--verified', action='store_true', default=False,
264 help='Include Chrome OS verified boot components')
265 parser.add_argument('-w', '--write', action='store_false', default=True,
266 help="Don't write image to board using usb/em100")
267 parser.add_argument('-x', '--sdcard', action='store_true', default=False,
268 help='Write to SD card instead of USB/em100')
269 parser.add_argument('-z', '--size', action='store_true', default=False,
270 help='Display U-Boot image size')
Simon Glassf67f93e2016-08-04 20:29:51 -0600271 parser.add_argument('target', nargs='?', default='all',
Mike Frysinger4e91d822015-06-04 02:01:40 -0400272 help='The target to work on')
Simon Glass02741682013-05-26 07:07:58 -0700273 return parser.parse_args(argv)
274
275
Simon Glassc1a323a2016-08-04 20:29:51 -0600276def FindCompiler(gcc, cros_prefix):
277 """Look up the compiler for an architecture.
278
279 Args:
280 gcc: GCC architecture, either 'arm' or 'aarch64'
281 cros_prefix: Full Chromium OS toolchain prefix
282 """
283 if in_chroot:
284 # Use the Chromium OS toolchain.
285 prefix = cros_prefix
286 else:
287 prefix = glob.glob('/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc' % gcc)
288 if not prefix:
Simon Glassd0557f02016-11-15 08:51:34 -0700289 cros_build_lib.Die("""Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600290Install a Linaro toolchain from:
291https://launchpad.net/linaro-toolchain-binaries
Simon Glassd0557f02016-11-15 08:51:34 -0700292or see cros/commands/cros_chrome_sdk.py.""" % gcc)
Simon Glassc1a323a2016-08-04 20:29:51 -0600293 prefix = re.sub('gcc$', '', prefix[0])
294 return prefix
295
296
Simon Glass02741682013-05-26 07:07:58 -0700297def SetupBuild(options):
298 """Set up parameters needed for the build.
299
300 This checks the current environment and options and sets up various things
301 needed for the build, including 'base' which holds the base flags for
302 passing to the U-Boot Makefile.
303
304 Args:
305 options: Command line options
306
307 Returns:
308 Base flags to use for U-Boot, as a list.
309 """
Don Garrett25f309a2014-03-19 14:02:12 -0700310 # pylint: disable=W0603
Simon Glass02741682013-05-26 07:07:58 -0700311 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
312
313 if not verbose:
314 verbose = options.verbose != 0
315
Ralph Nathan23a12212015-03-25 10:27:54 -0700316 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700317
318 Log('Building for %s' % options.board)
319
Simon Glass9d9bf942013-07-10 16:32:42 -0700320 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
321 # But don't mess up upstream boards which use _ in their name.
Simon Glass02741682013-05-26 07:07:58 -0700322 parts = options.board.split('_')
Simon Glass9d9bf942013-07-10 16:32:42 -0700323 if parts[0] in ['daisy', 'peach']:
324 board = parts[0]
325 else:
326 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700327
328 # To allow this to be run from 'cros_sdk'
329 if in_chroot:
330 os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))
331
332 base_board = board
333
334 if options.verified:
335 base_board = 'chromeos_%s' % base_board
336
337 uboard = UBOARDS.get(base_board, base_board)
338 Log('U-Boot board is %s' % uboard)
339
340 # Pull out some information from the U-Boot boards config file
341 family = None
Simon Glasseb0c5352016-07-20 09:29:34 -0600342 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
343 if os.path.exists('MAINTAINERS'):
344 board_format = PRE_KBUILD
345 else:
346 board_format = PRE_KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700347 with open('boards.cfg') as f:
348 for line in f:
Simon Glasseb0c5352016-07-20 09:29:34 -0600349 if 'genboardscfg' in line:
350 board_format = KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700351 if uboard in line:
352 if line[0] == '#':
353 continue
354 fields = line.split()
355 if not fields:
356 continue
357 arch = fields[1]
358 fields += [None, None, None]
Simon Glasseb0c5352016-07-20 09:29:34 -0600359 if board_format == PRE_KBUILD:
360 smdk = fields[3]
361 vendor = fields[4]
362 family = fields[5]
363 elif board_format in (PRE_KCONFIG, KCONFIG):
364 smdk = fields[5]
365 vendor = fields[4]
366 family = fields[3]
Simon Glass02741682013-05-26 07:07:58 -0700367 break
368 if not arch:
369 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
370
371 vboot = os.path.join('build', board, 'usr')
372 if arch == 'x86':
373 family = 'em100'
374 if in_chroot:
375 compiler = 'i686-pc-linux-gnu-'
376 else:
377 compiler = '/opt/i686/bin/i686-unknown-elf-'
378 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600379 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
380 elif arch == 'aarch64':
381 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
382 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
383 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700384 elif arch == 'sandbox':
385 compiler = ''
386 else:
387 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
388
389 if not options.build:
390 options.incremental = True
391
392 cpus = multiprocessing.cpu_count()
393
Simon Glassb89ae892013-07-18 15:23:35 -0600394 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700395 base = [
396 'make',
397 '-j%d' % cpus,
398 'O=%s' % outdir,
399 'ARCH=%s' % arch,
400 'CROSS_COMPILE=%s' % compiler,
401 '--no-print-directory',
402 'HOSTSTRIP=true',
403 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
404 'QEMU_ARCH=']
405
406 if options.verbose < 2:
407 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600408 elif options.verbose > 2:
409 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700410
411 if options.ro and options.rw:
412 cros_build_lib.Die('Cannot specify both --ro and --rw options')
413 if options.ro:
414 base.append('CROS_RO=1')
415 options.small = True
416
417 if options.rw:
418 base.append('CROS_RW=1')
419 options.small = True
420
421 if options.small:
422 base.append('CROS_SMALL=1')
423 else:
424 base.append('CROS_FULL=1')
425
426 if options.verified:
427 base += [
428 'VBOOT=%s' % vboot,
429 'MAKEFLAGS_VBOOT=DEBUG=1',
430 'QUIET=1',
431 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
432 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700433 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700434
435 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
436 # to a recent change, the need for which I didn't fully understand. But
437 # U-Boot doesn't normally use this. We have added an option to U-Boot to
438 # enable use of <stdint.h> and without it vboot will fail to build. So we
439 # need to enable it where ww can. We can't just enable it always since
440 # that would prevent this script from building other non-Chrome OS boards
441 # with a different (older) toolchain, or Chrome OS boards without vboot.
442 # So use USE_STDINT if the toolchain supports it, and not if not. This
443 # file was originally part of glibc but has recently migrated to the
444 # compiler so it is reasonable to use it with a stand-alone program like
445 # U-Boot. At this point the comment has got long enough that we may as
446 # well include some poetry which seems to be sorely lacking the code base,
447 # so this is from Ogden Nash:
448 # To keep your marriage brimming
449 # With love in the loving cup,
450 # Whenever you're wrong, admit it;
451 # Whenever you're right, shut up.
452 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Yu-Ju Hong3add4432014-01-30 11:46:15 -0800453 result = cros_build_lib.RunCommand(cmd,
454 input='#include <stdint.h>',
455 capture_output=True,
456 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700457 if result.returncode == 0:
458 base.append('USE_STDINT=1')
459
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600460 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700461 if options.trace:
462 base.append('FTRACE=1')
463 if options.separate:
464 base.append('DEV_TREE_SEPARATE=1')
465
466 if options.incremental:
467 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600468 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700469 if not os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700470 logging.warning('No build found for %s - dropping -i' % board)
Simon Glass02741682013-05-26 07:07:58 -0700471 options.incremental = False
472
Simon Glassef7e4372016-07-20 09:38:47 -0600473 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700474 if os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700475 logging.warning("Warning: '%s' exists, try 'make distclean'" % config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700476
477 # For when U-Boot supports ccache
478 # See http://patchwork.ozlabs.org/patch/245079/
479 if use_ccache:
480 os.environ['CCACHE'] = 'ccache'
481
482 return base
483
484
485def RunBuild(options, base, target, queue):
486 """Run the U-Boot build.
487
488 Args:
489 options: Command line options.
490 base: Base U-Boot flags.
491 target: Target to build.
492 queue: A parallel queue to add jobs to.
493 """
494 Log('U-Boot build flags: %s' % ' '.join(base))
495
496 # Reconfigure U-Boot.
497 if not options.incremental:
498 # Ignore any error from this, some older U-Boots fail on this.
499 cros_build_lib.RunCommand(base + ['distclean'], **kwargs)
500 result = cros_build_lib.RunCommand(base + ['%s_config' % uboard], **kwargs)
501 if result.returncode:
502 sys.exit()
503
504 # Do the actual build.
505 if options.build:
506 result = cros_build_lib.RunCommand(base + [target], **kwargs)
507 if result.returncode:
508 sys.exit()
509
510 files = ['%s/u-boot' % outdir]
511 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
512 if spl:
513 files += spl
514 if options.size:
Simon Glassc7d266d2013-07-18 15:15:57 -0600515 result = cros_build_lib.RunCommand([CompilerTool('size')] + files,
516 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700517 if result.returncode:
518 sys.exit()
519
520 # Create disassembly files .dis and .Dis (full dump)
521 for f in files:
522 base = os.path.splitext(f)[0]
523 if options.objdump:
524 queue.put(('-d', f, base + '.dis'))
525 queue.put(('-D', f, base + '.Dis'))
526 else:
527 # Remove old files which otherwise might be confusing
528 osutils.SafeUnlink(base + '.dis')
529 osutils.SafeUnlink(base + '.Dis')
530
531 Log('Output directory %s' % outdir)
532
533
534def WriteFirmware(options):
535 """Write firmware to the board.
536
537 This uses cros_bundle_firmware to create a firmware image and write it to
538 the board.
539
540 Args:
541 options: Command line options
542 """
543 flash = []
544 kernel = []
545 run = []
546 secure = []
547 servo = []
548 silent = []
549 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600550 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700551
552 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
553
554 if options.use_defaults:
555 bl1 = []
556 bmpblk = []
557 ecro = []
558 ecrw = []
559 defaults = []
560 else:
561 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
562 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
563 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
564 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
565 defaults = ['-D']
566
567 if arch == 'x86':
568 seabios = ['--seabios',
569 '##/build/%s/firmware/seabios.cbfs' % options.board]
570 else:
571 seabios = []
572
573 if options.sdcard:
574 dest = 'sd:.'
575 elif arch == 'x86':
576 dest = 'em100'
577 elif arch == 'sandbox':
578 dest = ''
579 else:
580 dest = 'usb'
581
582 port = SERVO_PORT.get(options.board, '')
583 if port:
584 servo = ['--servo', '%d' % port]
585
586 if options.flash:
587 flash = ['-F', 'spi']
588
Simon Glass46411592013-07-22 22:35:01 -0600589 # The small builds don't have the command line interpreter so cannot
590 # run the magic flasher script. So use the standard U-Boot in this
591 # case.
592 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700593 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600594 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
595
Michael Prattc88035d2013-07-31 16:27:29 -0700596 if options.mmc:
597 flash = ['-F', 'sdmmc']
598
Simon Glass02741682013-05-26 07:07:58 -0700599 if options.verbose:
600 verbose_arg = ['-v', '%s' % options.verbose]
601
602 if options.secure:
603 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
604
605 if not options.verified:
606 # Make a small image, without GBB, etc.
607 secure.append('-s')
608
609 if options.kernel:
610 kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]
611
612 if not options.console:
613 silent = ['--add-config-int', 'silent-console', '1']
614
615 if not options.run:
616 run = ['--bootcmd', 'none']
617
618 if arch != 'sandbox' and not in_chroot and servo:
619 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700620 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700621 dest = ''
622 servo = []
623 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700624 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700625 servo = []
626
627 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700628 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700629
630 if dest:
631 dest = ['-w', dest]
632 else:
633 dest = []
634
635 soc = SOCS.get(board)
636 if not soc:
637 soc = SOCS.get(uboard, '')
638 dt_name = DEFAULT_DTS.get(options.board, options.board)
639 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
640 Log('Device tree: %s' % dts_file)
641
642 if arch == 'sandbox':
643 uboot_fname = '%s/u-boot' % outdir
644 else:
645 uboot_fname = '%s/u-boot.bin' % outdir
646
Simon Glass46411592013-07-22 22:35:01 -0600647 if options.ro:
648 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
649 # ebuild one as RW.
650 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
651 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700652 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600653 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
654 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700655 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
656 '-b', options.board,
657 '-d', dts_file,
658 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
659 '-u', uboot_fname,
660 '-O', '%s/out' % outdir,
661 '-M', family]
662
663 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600664 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700665 if other:
666 cbf += other
667 if options.cbfargs:
668 for item in options.cbfargs:
669 cbf += item.split(' ')
670 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
671 (src_root, src_root))
672 Log(' '.join(cbf))
673 result = cros_build_lib.RunCommand(cbf, **kwargs)
674 if result.returncode:
675 cros_build_lib.Die('cros_bundle_firmware failed')
676
677 if not dest or not result.returncode:
Ralph Nathan03047282015-03-23 11:09:32 -0700678 logging.info('Image is available at %s/out/image.bin' % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700679 else:
680 if result.returncode:
681 cros_build_lib.Die('Failed to write image to board')
682 else:
Ralph Nathan03047282015-03-23 11:09:32 -0700683 logging.info('Image written to board with %s' % ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700684
685
686def main(argv):
687 """Main function for script to build/write firmware.
688
689 Args:
690 argv: Program arguments.
691 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400692 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700693 base = SetupBuild(options)
694
695 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400696 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700697
698 if options.write:
699 WriteFirmware(options)
700
701 if options.objdump:
702 Log('Writing diasssembly files')