blob: 61d7365d5bd65e80e27085516de7d1b50dc0679d [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]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700363 target = fields[6]
Simon Glasseb0c5352016-07-20 09:29:34 -0600364 elif board_format in (PRE_KCONFIG, KCONFIG):
365 smdk = fields[5]
366 vendor = fields[4]
367 family = fields[3]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700368 target = fields[0]
369
370 # Make sure this is the right target.
371 if target == uboard:
372 break
Simon Glass02741682013-05-26 07:07:58 -0700373 if not arch:
374 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
375
376 vboot = os.path.join('build', board, 'usr')
377 if arch == 'x86':
378 family = 'em100'
379 if in_chroot:
380 compiler = 'i686-pc-linux-gnu-'
381 else:
382 compiler = '/opt/i686/bin/i686-unknown-elf-'
383 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600384 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
385 elif arch == 'aarch64':
386 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
387 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
388 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700389 elif arch == 'sandbox':
390 compiler = ''
391 else:
392 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
393
394 if not options.build:
395 options.incremental = True
396
397 cpus = multiprocessing.cpu_count()
398
Simon Glassb89ae892013-07-18 15:23:35 -0600399 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700400 base = [
401 'make',
402 '-j%d' % cpus,
403 'O=%s' % outdir,
404 'ARCH=%s' % arch,
405 'CROSS_COMPILE=%s' % compiler,
406 '--no-print-directory',
407 'HOSTSTRIP=true',
408 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
409 'QEMU_ARCH=']
410
411 if options.verbose < 2:
412 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600413 elif options.verbose > 2:
414 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700415
416 if options.ro and options.rw:
417 cros_build_lib.Die('Cannot specify both --ro and --rw options')
418 if options.ro:
419 base.append('CROS_RO=1')
420 options.small = True
421
422 if options.rw:
423 base.append('CROS_RW=1')
424 options.small = True
425
426 if options.small:
427 base.append('CROS_SMALL=1')
428 else:
429 base.append('CROS_FULL=1')
430
431 if options.verified:
432 base += [
433 'VBOOT=%s' % vboot,
434 'MAKEFLAGS_VBOOT=DEBUG=1',
435 'QUIET=1',
436 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
437 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700438 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700439
440 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
441 # to a recent change, the need for which I didn't fully understand. But
442 # U-Boot doesn't normally use this. We have added an option to U-Boot to
443 # enable use of <stdint.h> and without it vboot will fail to build. So we
444 # need to enable it where ww can. We can't just enable it always since
445 # that would prevent this script from building other non-Chrome OS boards
446 # with a different (older) toolchain, or Chrome OS boards without vboot.
447 # So use USE_STDINT if the toolchain supports it, and not if not. This
448 # file was originally part of glibc but has recently migrated to the
449 # compiler so it is reasonable to use it with a stand-alone program like
450 # U-Boot. At this point the comment has got long enough that we may as
451 # well include some poetry which seems to be sorely lacking the code base,
452 # so this is from Ogden Nash:
453 # To keep your marriage brimming
454 # With love in the loving cup,
455 # Whenever you're wrong, admit it;
456 # Whenever you're right, shut up.
457 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Yu-Ju Hong3add4432014-01-30 11:46:15 -0800458 result = cros_build_lib.RunCommand(cmd,
459 input='#include <stdint.h>',
460 capture_output=True,
461 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700462 if result.returncode == 0:
463 base.append('USE_STDINT=1')
464
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600465 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700466 if options.trace:
467 base.append('FTRACE=1')
468 if options.separate:
469 base.append('DEV_TREE_SEPARATE=1')
470
471 if options.incremental:
472 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600473 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700474 if not os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700475 logging.warning('No build found for %s - dropping -i' % board)
Simon Glass02741682013-05-26 07:07:58 -0700476 options.incremental = False
477
Simon Glassef7e4372016-07-20 09:38:47 -0600478 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700479 if os.path.exists(config_mk):
Ralph Nathan446aee92015-03-23 14:44:56 -0700480 logging.warning("Warning: '%s' exists, try 'make distclean'" % config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700481
482 # For when U-Boot supports ccache
483 # See http://patchwork.ozlabs.org/patch/245079/
484 if use_ccache:
485 os.environ['CCACHE'] = 'ccache'
486
487 return base
488
489
490def RunBuild(options, base, target, queue):
491 """Run the U-Boot build.
492
493 Args:
494 options: Command line options.
495 base: Base U-Boot flags.
496 target: Target to build.
497 queue: A parallel queue to add jobs to.
498 """
499 Log('U-Boot build flags: %s' % ' '.join(base))
500
501 # Reconfigure U-Boot.
502 if not options.incremental:
503 # Ignore any error from this, some older U-Boots fail on this.
504 cros_build_lib.RunCommand(base + ['distclean'], **kwargs)
Simon Glass4e28d112016-11-16 13:52:48 -0700505 if os.path.exists('tools/genboardscfg.py'):
506 mtarget = 'defconfig'
507 else:
508 mtarget = 'config'
509 cmd = base + ['%s_%s' % (uboard, mtarget)]
Simon Glassc2fe94c2016-11-16 13:56:24 -0700510 result = cros_build_lib.RunCommand(cmd, capture_output=True,
511 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700512 if result.returncode:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700513 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output))
514 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700515
516 # Do the actual build.
517 if options.build:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700518 result = cros_build_lib.RunCommand(base + [target], capture_output=True,
519 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700520 if result.returncode:
Simon Glass08b33082017-01-23 12:16:40 -0700521 # The build failed, so output the results to stderr.
522 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output),
523 file=sys.stderr)
Simon Glassc2fe94c2016-11-16 13:56:24 -0700524 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700525
526 files = ['%s/u-boot' % outdir]
527 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
528 if spl:
529 files += spl
530 if options.size:
Simon Glassc7d266d2013-07-18 15:15:57 -0600531 result = cros_build_lib.RunCommand([CompilerTool('size')] + files,
532 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700533 if result.returncode:
534 sys.exit()
535
536 # Create disassembly files .dis and .Dis (full dump)
537 for f in files:
538 base = os.path.splitext(f)[0]
539 if options.objdump:
540 queue.put(('-d', f, base + '.dis'))
541 queue.put(('-D', f, base + '.Dis'))
542 else:
543 # Remove old files which otherwise might be confusing
544 osutils.SafeUnlink(base + '.dis')
545 osutils.SafeUnlink(base + '.Dis')
546
547 Log('Output directory %s' % outdir)
548
549
550def WriteFirmware(options):
551 """Write firmware to the board.
552
553 This uses cros_bundle_firmware to create a firmware image and write it to
554 the board.
555
556 Args:
557 options: Command line options
558 """
559 flash = []
560 kernel = []
561 run = []
562 secure = []
563 servo = []
564 silent = []
565 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600566 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700567
568 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
569
570 if options.use_defaults:
571 bl1 = []
572 bmpblk = []
573 ecro = []
574 ecrw = []
575 defaults = []
576 else:
577 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
578 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
579 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
580 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
581 defaults = ['-D']
582
583 if arch == 'x86':
584 seabios = ['--seabios',
585 '##/build/%s/firmware/seabios.cbfs' % options.board]
586 else:
587 seabios = []
588
589 if options.sdcard:
590 dest = 'sd:.'
591 elif arch == 'x86':
592 dest = 'em100'
593 elif arch == 'sandbox':
594 dest = ''
595 else:
596 dest = 'usb'
597
598 port = SERVO_PORT.get(options.board, '')
599 if port:
600 servo = ['--servo', '%d' % port]
601
602 if options.flash:
603 flash = ['-F', 'spi']
604
Simon Glass46411592013-07-22 22:35:01 -0600605 # The small builds don't have the command line interpreter so cannot
606 # run the magic flasher script. So use the standard U-Boot in this
607 # case.
608 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700609 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600610 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
611
Michael Prattc88035d2013-07-31 16:27:29 -0700612 if options.mmc:
613 flash = ['-F', 'sdmmc']
614
Simon Glass02741682013-05-26 07:07:58 -0700615 if options.verbose:
616 verbose_arg = ['-v', '%s' % options.verbose]
617
618 if options.secure:
619 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
620
621 if not options.verified:
622 # Make a small image, without GBB, etc.
623 secure.append('-s')
624
625 if options.kernel:
626 kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]
627
628 if not options.console:
629 silent = ['--add-config-int', 'silent-console', '1']
630
631 if not options.run:
632 run = ['--bootcmd', 'none']
633
634 if arch != 'sandbox' and not in_chroot and servo:
635 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700636 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700637 dest = ''
638 servo = []
639 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700640 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700641 servo = []
642
643 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700644 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700645
646 if dest:
647 dest = ['-w', dest]
648 else:
649 dest = []
650
651 soc = SOCS.get(board)
652 if not soc:
653 soc = SOCS.get(uboard, '')
654 dt_name = DEFAULT_DTS.get(options.board, options.board)
655 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
656 Log('Device tree: %s' % dts_file)
657
658 if arch == 'sandbox':
659 uboot_fname = '%s/u-boot' % outdir
660 else:
661 uboot_fname = '%s/u-boot.bin' % outdir
662
Simon Glass46411592013-07-22 22:35:01 -0600663 if options.ro:
664 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
665 # ebuild one as RW.
666 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
667 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700668 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600669 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
670 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700671 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
672 '-b', options.board,
673 '-d', dts_file,
674 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
675 '-u', uboot_fname,
676 '-O', '%s/out' % outdir,
677 '-M', family]
678
679 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600680 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700681 if other:
682 cbf += other
683 if options.cbfargs:
684 for item in options.cbfargs:
685 cbf += item.split(' ')
686 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
687 (src_root, src_root))
688 Log(' '.join(cbf))
689 result = cros_build_lib.RunCommand(cbf, **kwargs)
690 if result.returncode:
691 cros_build_lib.Die('cros_bundle_firmware failed')
692
693 if not dest or not result.returncode:
Ralph Nathan03047282015-03-23 11:09:32 -0700694 logging.info('Image is available at %s/out/image.bin' % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700695 else:
696 if result.returncode:
697 cros_build_lib.Die('Failed to write image to board')
698 else:
Ralph Nathan03047282015-03-23 11:09:32 -0700699 logging.info('Image written to board with %s' % ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700700
701
702def main(argv):
703 """Main function for script to build/write firmware.
704
705 Args:
706 argv: Program arguments.
707 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400708 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700709 base = SetupBuild(options)
710
711 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400712 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700713
714 if options.write:
715 WriteFirmware(options)
716
717 if options.objdump:
718 Log('Writing diasssembly files')