blob: ac43f3287130e048c484254c325ef0af9411c2d2 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Simon Glass02741682013-05-26 07:07:58 -07002# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""crosfw - Chrome OS Firmware build/flash script.
7
8Builds a firmware image for any board and writes it to the board. The image
9can be pure upstream or include Chrome OS components (-V). Some device
10tree parameters can be provided, including silent console (-C) and secure
11boot (-S). Use -i for a faster incremental build. The image is written to
12the board by default using USB/em100 (or sdcard with -x). Use -b to specify
13the board to build. Options can be added to ~/.crosfwrc - see the script for
14details.
15
16It can also flash SPI by writing a 'magic flasher' U-Boot with a payload
17to the board.
18
Simon Glass02741682013-05-26 07:07:58 -070019The script is normally run from within the U-Boot directory which is
20.../src/third_party/u-boot/files
21
22Example 1: Build upstream image for coreboot and write to a 'link':
23
24 crosfw -b link
25
26Example 2: Build verified boot image (V) for daisy/snow and boot in secure
27 mode (S) so that breaking in on boot is not possible.
28
29 crosfw -b daisy -VS
30 crosfw -b daisy -VSC (no console output)
31
32Example 3: Build a magic flasher (F) with full verified boot for peach_pit,
33 but with console enabled, write to SD card (x)
34
35 crosfw -b peach_pit -VSFx
36
37This sript does not use an ebuild. It does a similar thing to the
38chromeos-u-boot ebuild, and runs cros_bundle_firmware to produce various
39types of image, a little like the chromeos-bootimage ebuild.
40
41The purpose of this script is to make it easier and faster to perform
42common firmware build tasks without changing boards, manually updating
43device tree files or lots of USE flags and complexity in the ebuilds.
44
45This script has been tested with snow, link and peach_pit. It builds for
46peach_pit by default. Note that it will also build any upstream ARM
47board - e.g. "-b snapper9260" will build an image for that board.
48
49Mostly you can use the script inside and outside the chroot. The main
50limitation is that dut-control doesn't really work outside the chroot,
51so writing the image to the board over USB is not possible, nor can the
52board be automatically reset on x86 platforms.
53
54For an incremental build (faster), run with -i
55
56To get faster clean builds, install ccache, and create ~/.crosfwrc with
57this line:
58
Simon Glass6ddc7f12013-07-18 15:22:41 -060059 USE_CCACHE = True
Simon Glass02741682013-05-26 07:07:58 -070060
61(make sure ~/.ccache is not on NFS, or set CCACHE_DIR)
62
63Other options are the default board to build, and verbosity (0-4), e.g.:
64
Simon Glass6ddc7f12013-07-18 15:22:41 -060065 DEFAULT_BOARD = 'daisy'
66 VERBOSE = 1
Simon Glass02741682013-05-26 07:07:58 -070067
68It is possible to use multiple servo boards, each on its own port. Add
69these lines to your ~/.crosfwrc to set the servo port to use for each
70board:
71
72 SERVO_PORT['link'] = 8888
73 SERVO_PORT['daisy'] = 9999
74 SERVO_PORT['peach_pit'] = 7777
75
Simon Glassb89ae892013-07-18 15:23:35 -060076All builds appear in the <outdir>/<board> subdirectory and images are written
77to <outdir>/<uboard>/out, where <uboard> is the U-Boot name for the board (in
78the U-Boot boards.cfg file)
79
80The value for <outdir> defaults to /tmp/crosfw but can be configured in your
81~/.crosfwrc file, e.g.:"
82
83 OUT_DIR = '/tmp/u-boot'
Simon Glass02741682013-05-26 07:07:58 -070084
85For the -a option here are some useful options:
86
87--add-blob cros-splash /dev/null
88--gbb-flags -force-dev-switch-on
89--add-node-enable /spi@131b0000/cros-ecp@0 1
90--verify --full-erase
91--bootcmd "cros_test sha"
92--gbb-flags -force-dev-switch-on
93--bmpblk ~/trunk/src/third_party/u-boot/bmp.bin
94
95For example: -a "--gbb-flags -force-dev-switch-on"
96
97Note the standard bmpblk is at:
98 /home/$USER/trunk/src/third_party/chromiumos-overlay/sys-boot/
99 chromeos-bootimage/files/bmpblk.bin"
100"""
101
Mike Frysinger383367e2014-09-16 15:06:17 -0400102from __future__ import print_function
103
Simon Glass02741682013-05-26 07:07:58 -0700104import glob
Simon Glass02741682013-05-26 07:07:58 -0700105import multiprocessing
106import os
107import re
108import sys
109
Aviv Keshetb7519e12016-10-04 00:50:00 -0700110from chromite.lib import constants
Simon Glass02741682013-05-26 07:07:58 -0700111from chromite.lib import commandline
112from chromite.lib import cros_build_lib
Ralph Nathan91874ca2015-03-19 13:29:41 -0700113from chromite.lib import cros_logging as logging
Simon Glass02741682013-05-26 07:07:58 -0700114from chromite.lib import osutils
115from chromite.lib import parallel
116
117
118arch = None
119board = None
120compiler = None
121default_board = None
122family = None
123in_chroot = True
124
Simon Glass02741682013-05-26 07:07:58 -0700125logging.basicConfig(format='%(message)s')
126kwargs = {'print_cmd': False, 'error_code_ok': True,
Ralph Nathan23a12212015-03-25 10:27:54 -0700127 'debug_level': logging.getLogger().getEffectiveLevel()}
Simon Glass02741682013-05-26 07:07:58 -0700128
129outdir = ''
130
131 # If you have multiple boards connected on different servo ports, put lines
132# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
133SERVO_PORT = {}
134
135smdk = None
136src_root = os.path.join(constants.SOURCE_ROOT, 'src')
137in_chroot = cros_build_lib.IsInsideChroot()
138
139uboard = ''
140
141default_board = 'peach_pit'
142use_ccache = False
143vendor = None
144verbose = False
145
146# Special cases for the U-Boot board config, the SOCs and default device tree
147# since the naming is not always consistent.
148# x86 has a lot of boards, but to U-Boot they are all the same
149UBOARDS = {
150 'daisy': 'smdk5250',
151 'peach': 'smdk5420',
152}
153for b in ['alex', 'butterfly', 'emeraldlake2', 'link', 'lumpy', 'parrot',
154 'stout', 'stumpy']:
155 UBOARDS[b] = 'coreboot-x86'
156 UBOARDS['chromeos_%s' % b] = 'chromeos_coreboot'
157
158SOCS = {
159 'coreboot-x86': '',
160 'chromeos_coreboot': '',
161 'daisy': 'exynos5250-',
162 'peach': 'exynos5420-',
163}
164
165DEFAULT_DTS = {
166 'daisy': 'snow',
167 'daisy_spring': 'spring',
168 'peach_pit': 'peach-pit',
169}
170
Simon Glassb89ae892013-07-18 15:23:35 -0600171OUT_DIR = '/tmp/crosfw'
172
Simon Glass02741682013-05-26 07:07:58 -0700173rc_file = os.path.expanduser('~/.crosfwrc')
174if os.path.exists(rc_file):
175 execfile(rc_file)
176
177
178def Log(msg):
179 """Print out a message if we are in verbose mode.
180
181 Args:
182 msg: Message to print
183 """
184 if verbose:
Ralph Nathan03047282015-03-23 11:09:32 -0700185 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700186
187
188def Dumper(flag, infile, outfile):
189 """Run objdump on an input file.
190
191 Args:
192 flag: Flag to pass objdump (e.g. '-d').
193 infile: Input file to process.
194 outfile: Output file to write to.
195 """
196 result = cros_build_lib.RunCommand(
197 [CompilerTool('objdump'), flag, infile],
198 log_stdout_to_file=outfile, **kwargs)
199 if result.returncode:
200 sys.exit()
201
202
203def CompilerTool(tool):
204 """Returns the cross-compiler tool filename.
205
206 Args:
207 tool: Tool name to return, e.g. 'size'.
208
209 Returns:
210 Filename of requested tool.
211 """
212 return '%s%s' % (compiler, tool)
213
214
215def ParseCmdline(argv):
216 """Parse all command line options.
217
218 Args:
219 argv: Arguments to parse.
220
221 Returns:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400222 The parsed options object
Simon Glass02741682013-05-26 07:07:58 -0700223 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400224 parser = commandline.ArgumentParser(description=__doc__)
225 parser.add_argument('-a', '--cbfargs', action='append',
226 help='Pass extra arguments to cros_bundle_firmware')
227 parser.add_argument('-b', '--board', type=str, default=default_board,
228 help='Select board to build (daisy/peach_pit/link)')
229 parser.add_argument('-B', '--build', action='store_false', default=True,
230 help="Don't build U-Boot, just configure device tree")
231 parser.add_argument('-C', '--console', action='store_false', default=True,
232 help='Permit console output')
233 parser.add_argument('-d', '--dt', default='seaboard',
234 help='Select name of device tree file to use')
235 parser.add_argument('-D', '--nodefaults', dest='use_defaults',
236 action='store_false', default=True,
237 help="Don't select default filenames for those not given")
238 parser.add_argument('-F', '--flash', action='store_true', default=False,
239 help='Create magic flasher for SPI flash')
240 parser.add_argument('-M', '--mmc', action='store_true', default=False,
241 help='Create magic flasher for eMMC')
242 parser.add_argument('-i', '--incremental', action='store_true', default=False,
243 help="Don't reconfigure and clean")
244 parser.add_argument('-k', '--kernel', action='store_true', default=False,
245 help='Send kernel to board also')
246 parser.add_argument('-O', '--objdump', action='store_true', default=False,
247 help='Write disassembly output')
248 parser.add_argument('-r', '--run', action='store_false', default=True,
249 help='Run the boot command')
250 parser.add_argument('--ro', action='store_true', default=False,
251 help='Create Chrome OS read-only image')
252 parser.add_argument('--rw', action='store_true', default=False,
253 help='Create Chrome OS read-write image')
254 parser.add_argument('-s', '--separate', action='store_false', default=True,
255 help='Link device tree into U-Boot, instead of separate')
256 parser.add_argument('-S', '--secure', action='store_true', default=False,
257 help='Use vboot_twostop secure boot')
258 parser.add_argument('--small', action='store_true', default=False,
259 help='Create Chrome OS small image')
260 parser.add_argument('-t', '--trace', action='store_true', default=False,
261 help='Enable trace support')
262 parser.add_argument('-v', '--verbose', type=int, default=0,
263 help='Make cros_bundle_firmware verbose')
264 parser.add_argument('-V', '--verified', action='store_true', default=False,
265 help='Include Chrome OS verified boot components')
266 parser.add_argument('-w', '--write', action='store_false', default=True,
267 help="Don't write image to board using usb/em100")
268 parser.add_argument('-x', '--sdcard', action='store_true', default=False,
269 help='Write to SD card instead of USB/em100')
270 parser.add_argument('-z', '--size', action='store_true', default=False,
271 help='Display U-Boot image size')
Simon Glassf67f93e2016-08-04 20:29:51 -0600272 parser.add_argument('target', nargs='?', default='all',
Mike Frysinger4e91d822015-06-04 02:01:40 -0400273 help='The target to work on')
Simon Glass02741682013-05-26 07:07:58 -0700274 return parser.parse_args(argv)
275
276
Simon Glassc1a323a2016-08-04 20:29:51 -0600277def FindCompiler(gcc, cros_prefix):
278 """Look up the compiler for an architecture.
279
280 Args:
281 gcc: GCC architecture, either 'arm' or 'aarch64'
282 cros_prefix: Full Chromium OS toolchain prefix
283 """
284 if in_chroot:
285 # Use the Chromium OS toolchain.
286 prefix = cros_prefix
287 else:
288 prefix = glob.glob('/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc' % gcc)
289 if not prefix:
Simon Glassd0557f02016-11-15 08:51:34 -0700290 cros_build_lib.Die("""Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600291Install a Linaro toolchain from:
292https://launchpad.net/linaro-toolchain-binaries
Simon Glassd0557f02016-11-15 08:51:34 -0700293or see cros/commands/cros_chrome_sdk.py.""" % gcc)
Simon Glassc1a323a2016-08-04 20:29:51 -0600294 prefix = re.sub('gcc$', '', prefix[0])
295 return prefix
296
297
Simon Glass02741682013-05-26 07:07:58 -0700298def SetupBuild(options):
299 """Set up parameters needed for the build.
300
301 This checks the current environment and options and sets up various things
302 needed for the build, including 'base' which holds the base flags for
303 passing to the U-Boot Makefile.
304
305 Args:
306 options: Command line options
307
308 Returns:
309 Base flags to use for U-Boot, as a list.
310 """
Don Garrett25f309a2014-03-19 14:02:12 -0700311 # pylint: disable=W0603
Simon Glass02741682013-05-26 07:07:58 -0700312 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
313
314 if not verbose:
315 verbose = options.verbose != 0
316
Ralph Nathan23a12212015-03-25 10:27:54 -0700317 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700318
319 Log('Building for %s' % options.board)
320
Simon Glass9d9bf942013-07-10 16:32:42 -0700321 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
322 # But don't mess up upstream boards which use _ in their name.
Simon Glass02741682013-05-26 07:07:58 -0700323 parts = options.board.split('_')
Simon Glass9d9bf942013-07-10 16:32:42 -0700324 if parts[0] in ['daisy', 'peach']:
325 board = parts[0]
326 else:
327 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700328
329 # To allow this to be run from 'cros_sdk'
330 if in_chroot:
331 os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))
332
333 base_board = board
334
335 if options.verified:
336 base_board = 'chromeos_%s' % base_board
337
338 uboard = UBOARDS.get(base_board, base_board)
339 Log('U-Boot board is %s' % uboard)
340
341 # Pull out some information from the U-Boot boards config file
342 family = None
Simon Glasseb0c5352016-07-20 09:29:34 -0600343 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
344 if os.path.exists('MAINTAINERS'):
345 board_format = PRE_KBUILD
346 else:
347 board_format = PRE_KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700348 with open('boards.cfg') as f:
349 for line in f:
Simon Glasseb0c5352016-07-20 09:29:34 -0600350 if 'genboardscfg' in line:
351 board_format = KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700352 if uboard in line:
353 if line[0] == '#':
354 continue
355 fields = line.split()
356 if not fields:
357 continue
358 arch = fields[1]
359 fields += [None, None, None]
Simon Glasseb0c5352016-07-20 09:29:34 -0600360 if board_format == PRE_KBUILD:
361 smdk = fields[3]
362 vendor = fields[4]
363 family = fields[5]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700364 target = fields[6]
Simon Glasseb0c5352016-07-20 09:29:34 -0600365 elif board_format in (PRE_KCONFIG, KCONFIG):
366 smdk = fields[5]
367 vendor = fields[4]
368 family = fields[3]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700369 target = fields[0]
370
371 # Make sure this is the right target.
372 if target == uboard:
373 break
Simon Glass02741682013-05-26 07:07:58 -0700374 if not arch:
375 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
376
377 vboot = os.path.join('build', board, 'usr')
378 if arch == 'x86':
379 family = 'em100'
380 if in_chroot:
381 compiler = 'i686-pc-linux-gnu-'
382 else:
383 compiler = '/opt/i686/bin/i686-unknown-elf-'
384 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600385 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
386 elif arch == 'aarch64':
387 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
388 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
389 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700390 elif arch == 'sandbox':
391 compiler = ''
392 else:
393 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
394
395 if not options.build:
396 options.incremental = True
397
398 cpus = multiprocessing.cpu_count()
399
Simon Glassb89ae892013-07-18 15:23:35 -0600400 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700401 base = [
402 'make',
403 '-j%d' % cpus,
404 'O=%s' % outdir,
405 'ARCH=%s' % arch,
406 'CROSS_COMPILE=%s' % compiler,
407 '--no-print-directory',
408 'HOSTSTRIP=true',
409 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
410 'QEMU_ARCH=']
411
412 if options.verbose < 2:
413 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600414 elif options.verbose > 2:
415 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700416
417 if options.ro and options.rw:
418 cros_build_lib.Die('Cannot specify both --ro and --rw options')
419 if options.ro:
420 base.append('CROS_RO=1')
421 options.small = True
422
423 if options.rw:
424 base.append('CROS_RW=1')
425 options.small = True
426
427 if options.small:
428 base.append('CROS_SMALL=1')
429 else:
430 base.append('CROS_FULL=1')
431
432 if options.verified:
433 base += [
434 'VBOOT=%s' % vboot,
435 'MAKEFLAGS_VBOOT=DEBUG=1',
436 'QUIET=1',
437 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
438 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700439 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700440
441 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
442 # to a recent change, the need for which I didn't fully understand. But
443 # U-Boot doesn't normally use this. We have added an option to U-Boot to
444 # enable use of <stdint.h> and without it vboot will fail to build. So we
445 # need to enable it where ww can. We can't just enable it always since
446 # that would prevent this script from building other non-Chrome OS boards
447 # with a different (older) toolchain, or Chrome OS boards without vboot.
448 # So use USE_STDINT if the toolchain supports it, and not if not. This
449 # file was originally part of glibc but has recently migrated to the
450 # compiler so it is reasonable to use it with a stand-alone program like
451 # U-Boot. At this point the comment has got long enough that we may as
452 # well include some poetry which seems to be sorely lacking the code base,
453 # so this is from Ogden Nash:
454 # To keep your marriage brimming
455 # With love in the loving cup,
456 # Whenever you're wrong, admit it;
457 # Whenever you're right, shut up.
458 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Yu-Ju Hong3add4432014-01-30 11:46:15 -0800459 result = cros_build_lib.RunCommand(cmd,
460 input='#include <stdint.h>',
461 capture_output=True,
462 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700463 if result.returncode == 0:
464 base.append('USE_STDINT=1')
465
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600466 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700467 if options.trace:
468 base.append('FTRACE=1')
469 if options.separate:
470 base.append('DEV_TREE_SEPARATE=1')
471
472 if options.incremental:
473 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600474 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700475 if not os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700476 logging.warning('No build found for %s - dropping -i' % board)
Simon Glass02741682013-05-26 07:07:58 -0700477 options.incremental = False
478
Simon Glassef7e4372016-07-20 09:38:47 -0600479 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700480 if os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700481 logging.warning("Warning: '%s' exists, try 'make distclean'" % config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700482
483 # For when U-Boot supports ccache
484 # See http://patchwork.ozlabs.org/patch/245079/
485 if use_ccache:
486 os.environ['CCACHE'] = 'ccache'
487
488 return base
489
490
491def RunBuild(options, base, target, queue):
492 """Run the U-Boot build.
493
494 Args:
495 options: Command line options.
496 base: Base U-Boot flags.
497 target: Target to build.
498 queue: A parallel queue to add jobs to.
499 """
500 Log('U-Boot build flags: %s' % ' '.join(base))
501
502 # Reconfigure U-Boot.
503 if not options.incremental:
504 # Ignore any error from this, some older U-Boots fail on this.
505 cros_build_lib.RunCommand(base + ['distclean'], **kwargs)
Simon Glass4e28d112016-11-16 13:52:48 -0700506 if os.path.exists('tools/genboardscfg.py'):
507 mtarget = 'defconfig'
508 else:
509 mtarget = 'config'
510 cmd = base + ['%s_%s' % (uboard, mtarget)]
Simon Glassc2fe94c2016-11-16 13:56:24 -0700511 result = cros_build_lib.RunCommand(cmd, capture_output=True,
512 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700513 if result.returncode:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700514 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output))
515 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700516
517 # Do the actual build.
518 if options.build:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700519 result = cros_build_lib.RunCommand(base + [target], capture_output=True,
520 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700521 if result.returncode:
Simon Glass08b33082017-01-23 12:16:40 -0700522 # The build failed, so output the results to stderr.
523 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output),
524 file=sys.stderr)
Simon Glassc2fe94c2016-11-16 13:56:24 -0700525 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700526
527 files = ['%s/u-boot' % outdir]
528 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
529 if spl:
530 files += spl
531 if options.size:
Simon Glassc7d266d2013-07-18 15:15:57 -0600532 result = cros_build_lib.RunCommand([CompilerTool('size')] + files,
533 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700534 if result.returncode:
535 sys.exit()
536
537 # Create disassembly files .dis and .Dis (full dump)
538 for f in files:
539 base = os.path.splitext(f)[0]
540 if options.objdump:
541 queue.put(('-d', f, base + '.dis'))
542 queue.put(('-D', f, base + '.Dis'))
543 else:
544 # Remove old files which otherwise might be confusing
545 osutils.SafeUnlink(base + '.dis')
546 osutils.SafeUnlink(base + '.Dis')
547
548 Log('Output directory %s' % outdir)
549
550
551def WriteFirmware(options):
552 """Write firmware to the board.
553
554 This uses cros_bundle_firmware to create a firmware image and write it to
555 the board.
556
557 Args:
558 options: Command line options
559 """
560 flash = []
561 kernel = []
562 run = []
563 secure = []
564 servo = []
565 silent = []
566 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600567 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700568
569 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
570
571 if options.use_defaults:
572 bl1 = []
573 bmpblk = []
574 ecro = []
575 ecrw = []
576 defaults = []
577 else:
578 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
579 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
580 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
581 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
582 defaults = ['-D']
583
584 if arch == 'x86':
585 seabios = ['--seabios',
586 '##/build/%s/firmware/seabios.cbfs' % options.board]
587 else:
588 seabios = []
589
590 if options.sdcard:
591 dest = 'sd:.'
592 elif arch == 'x86':
593 dest = 'em100'
594 elif arch == 'sandbox':
595 dest = ''
596 else:
597 dest = 'usb'
598
599 port = SERVO_PORT.get(options.board, '')
600 if port:
601 servo = ['--servo', '%d' % port]
602
603 if options.flash:
604 flash = ['-F', 'spi']
605
Simon Glass46411592013-07-22 22:35:01 -0600606 # The small builds don't have the command line interpreter so cannot
607 # run the magic flasher script. So use the standard U-Boot in this
608 # case.
609 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700610 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600611 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
612
Michael Prattc88035d2013-07-31 16:27:29 -0700613 if options.mmc:
614 flash = ['-F', 'sdmmc']
615
Simon Glass02741682013-05-26 07:07:58 -0700616 if options.verbose:
617 verbose_arg = ['-v', '%s' % options.verbose]
618
619 if options.secure:
620 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
621
622 if not options.verified:
623 # Make a small image, without GBB, etc.
624 secure.append('-s')
625
626 if options.kernel:
627 kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]
628
629 if not options.console:
630 silent = ['--add-config-int', 'silent-console', '1']
631
632 if not options.run:
633 run = ['--bootcmd', 'none']
634
635 if arch != 'sandbox' and not in_chroot and servo:
636 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700637 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700638 dest = ''
639 servo = []
640 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700641 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700642 servo = []
643
644 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700645 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700646
647 if dest:
648 dest = ['-w', dest]
649 else:
650 dest = []
651
652 soc = SOCS.get(board)
653 if not soc:
654 soc = SOCS.get(uboard, '')
655 dt_name = DEFAULT_DTS.get(options.board, options.board)
656 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
657 Log('Device tree: %s' % dts_file)
658
659 if arch == 'sandbox':
660 uboot_fname = '%s/u-boot' % outdir
661 else:
662 uboot_fname = '%s/u-boot.bin' % outdir
663
Simon Glass46411592013-07-22 22:35:01 -0600664 if options.ro:
665 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
666 # ebuild one as RW.
667 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
668 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700669 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600670 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
671 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700672 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
673 '-b', options.board,
674 '-d', dts_file,
675 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
676 '-u', uboot_fname,
677 '-O', '%s/out' % outdir,
678 '-M', family]
679
680 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600681 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700682 if other:
683 cbf += other
684 if options.cbfargs:
685 for item in options.cbfargs:
686 cbf += item.split(' ')
687 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
688 (src_root, src_root))
689 Log(' '.join(cbf))
690 result = cros_build_lib.RunCommand(cbf, **kwargs)
691 if result.returncode:
692 cros_build_lib.Die('cros_bundle_firmware failed')
693
694 if not dest or not result.returncode:
Ralph Nathan03047282015-03-23 11:09:32 -0700695 logging.info('Image is available at %s/out/image.bin' % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700696 else:
697 if result.returncode:
698 cros_build_lib.Die('Failed to write image to board')
699 else:
Ralph Nathan03047282015-03-23 11:09:32 -0700700 logging.info('Image written to board with %s' % ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700701
702
703def main(argv):
704 """Main function for script to build/write firmware.
705
706 Args:
707 argv: Program arguments.
708 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400709 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700710 base = SetupBuild(options)
711
712 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400713 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700714
715 if options.write:
716 WriteFirmware(options)
717
718 if options.objdump:
719 Log('Writing diasssembly files')