blob: ca690dd710ee5d3f6938f7448c8e530112084714 [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):
Mike Frysinger5d535ac2019-07-03 03:29:47 -0400175 with open(rc_file) as fp:
176 # pylint: disable=exec-used
177 exec(compile(fp.read(), rc_file, 'exec'))
Simon Glass02741682013-05-26 07:07:58 -0700178
179
180def Log(msg):
181 """Print out a message if we are in verbose mode.
182
183 Args:
184 msg: Message to print
185 """
186 if verbose:
Ralph Nathan03047282015-03-23 11:09:32 -0700187 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700188
189
190def Dumper(flag, infile, outfile):
191 """Run objdump on an input file.
192
193 Args:
194 flag: Flag to pass objdump (e.g. '-d').
195 infile: Input file to process.
196 outfile: Output file to write to.
197 """
198 result = cros_build_lib.RunCommand(
199 [CompilerTool('objdump'), flag, infile],
200 log_stdout_to_file=outfile, **kwargs)
201 if result.returncode:
202 sys.exit()
203
204
205def CompilerTool(tool):
206 """Returns the cross-compiler tool filename.
207
208 Args:
209 tool: Tool name to return, e.g. 'size'.
210
211 Returns:
212 Filename of requested tool.
213 """
214 return '%s%s' % (compiler, tool)
215
216
217def ParseCmdline(argv):
218 """Parse all command line options.
219
220 Args:
221 argv: Arguments to parse.
222
223 Returns:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400224 The parsed options object
Simon Glass02741682013-05-26 07:07:58 -0700225 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400226 parser = commandline.ArgumentParser(description=__doc__)
227 parser.add_argument('-a', '--cbfargs', action='append',
228 help='Pass extra arguments to cros_bundle_firmware')
229 parser.add_argument('-b', '--board', type=str, default=default_board,
230 help='Select board to build (daisy/peach_pit/link)')
231 parser.add_argument('-B', '--build', action='store_false', default=True,
232 help="Don't build U-Boot, just configure device tree")
233 parser.add_argument('-C', '--console', action='store_false', default=True,
234 help='Permit console output')
235 parser.add_argument('-d', '--dt', default='seaboard',
236 help='Select name of device tree file to use')
237 parser.add_argument('-D', '--nodefaults', dest='use_defaults',
238 action='store_false', default=True,
239 help="Don't select default filenames for those not given")
240 parser.add_argument('-F', '--flash', action='store_true', default=False,
241 help='Create magic flasher for SPI flash')
242 parser.add_argument('-M', '--mmc', action='store_true', default=False,
243 help='Create magic flasher for eMMC')
244 parser.add_argument('-i', '--incremental', action='store_true', default=False,
245 help="Don't reconfigure and clean")
246 parser.add_argument('-k', '--kernel', action='store_true', default=False,
247 help='Send kernel to board also')
248 parser.add_argument('-O', '--objdump', action='store_true', default=False,
249 help='Write disassembly output')
250 parser.add_argument('-r', '--run', action='store_false', default=True,
251 help='Run the boot command')
252 parser.add_argument('--ro', action='store_true', default=False,
253 help='Create Chrome OS read-only image')
254 parser.add_argument('--rw', action='store_true', default=False,
255 help='Create Chrome OS read-write image')
256 parser.add_argument('-s', '--separate', action='store_false', default=True,
257 help='Link device tree into U-Boot, instead of separate')
258 parser.add_argument('-S', '--secure', action='store_true', default=False,
259 help='Use vboot_twostop secure boot')
260 parser.add_argument('--small', action='store_true', default=False,
261 help='Create Chrome OS small image')
262 parser.add_argument('-t', '--trace', action='store_true', default=False,
263 help='Enable trace support')
264 parser.add_argument('-v', '--verbose', type=int, default=0,
265 help='Make cros_bundle_firmware verbose')
266 parser.add_argument('-V', '--verified', action='store_true', default=False,
267 help='Include Chrome OS verified boot components')
268 parser.add_argument('-w', '--write', action='store_false', default=True,
269 help="Don't write image to board using usb/em100")
270 parser.add_argument('-x', '--sdcard', action='store_true', default=False,
271 help='Write to SD card instead of USB/em100')
272 parser.add_argument('-z', '--size', action='store_true', default=False,
273 help='Display U-Boot image size')
Simon Glassf67f93e2016-08-04 20:29:51 -0600274 parser.add_argument('target', nargs='?', default='all',
Mike Frysinger4e91d822015-06-04 02:01:40 -0400275 help='The target to work on')
Simon Glass02741682013-05-26 07:07:58 -0700276 return parser.parse_args(argv)
277
278
Simon Glassc1a323a2016-08-04 20:29:51 -0600279def FindCompiler(gcc, cros_prefix):
280 """Look up the compiler for an architecture.
281
282 Args:
283 gcc: GCC architecture, either 'arm' or 'aarch64'
284 cros_prefix: Full Chromium OS toolchain prefix
285 """
286 if in_chroot:
287 # Use the Chromium OS toolchain.
288 prefix = cros_prefix
289 else:
290 prefix = glob.glob('/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc' % gcc)
291 if not prefix:
Simon Glassd0557f02016-11-15 08:51:34 -0700292 cros_build_lib.Die("""Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600293Install a Linaro toolchain from:
294https://launchpad.net/linaro-toolchain-binaries
Simon Glassd0557f02016-11-15 08:51:34 -0700295or see cros/commands/cros_chrome_sdk.py.""" % gcc)
Simon Glassc1a323a2016-08-04 20:29:51 -0600296 prefix = re.sub('gcc$', '', prefix[0])
297 return prefix
298
299
Simon Glass02741682013-05-26 07:07:58 -0700300def SetupBuild(options):
301 """Set up parameters needed for the build.
302
303 This checks the current environment and options and sets up various things
304 needed for the build, including 'base' which holds the base flags for
305 passing to the U-Boot Makefile.
306
307 Args:
308 options: Command line options
309
310 Returns:
311 Base flags to use for U-Boot, as a list.
312 """
Mike Frysinger27e21b72018-07-12 14:20:21 -0400313 # pylint: disable=global-statement
Simon Glass02741682013-05-26 07:07:58 -0700314 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
315
316 if not verbose:
317 verbose = options.verbose != 0
318
Ralph Nathan23a12212015-03-25 10:27:54 -0700319 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700320
321 Log('Building for %s' % options.board)
322
Simon Glass9d9bf942013-07-10 16:32:42 -0700323 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
324 # But don't mess up upstream boards which use _ in their name.
Simon Glass02741682013-05-26 07:07:58 -0700325 parts = options.board.split('_')
Simon Glass9d9bf942013-07-10 16:32:42 -0700326 if parts[0] in ['daisy', 'peach']:
327 board = parts[0]
328 else:
329 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700330
331 # To allow this to be run from 'cros_sdk'
332 if in_chroot:
333 os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))
334
335 base_board = board
336
337 if options.verified:
338 base_board = 'chromeos_%s' % base_board
339
340 uboard = UBOARDS.get(base_board, base_board)
341 Log('U-Boot board is %s' % uboard)
342
343 # Pull out some information from the U-Boot boards config file
344 family = None
Simon Glasseb0c5352016-07-20 09:29:34 -0600345 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
346 if os.path.exists('MAINTAINERS'):
347 board_format = PRE_KBUILD
348 else:
349 board_format = PRE_KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700350 with open('boards.cfg') as f:
351 for line in f:
Simon Glasseb0c5352016-07-20 09:29:34 -0600352 if 'genboardscfg' in line:
353 board_format = KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700354 if uboard in line:
355 if line[0] == '#':
356 continue
357 fields = line.split()
358 if not fields:
359 continue
360 arch = fields[1]
361 fields += [None, None, None]
Simon Glasseb0c5352016-07-20 09:29:34 -0600362 if board_format == PRE_KBUILD:
363 smdk = fields[3]
364 vendor = fields[4]
365 family = fields[5]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700366 target = fields[6]
Simon Glasseb0c5352016-07-20 09:29:34 -0600367 elif board_format in (PRE_KCONFIG, KCONFIG):
368 smdk = fields[5]
369 vendor = fields[4]
370 family = fields[3]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700371 target = fields[0]
372
373 # Make sure this is the right target.
374 if target == uboard:
375 break
Simon Glass02741682013-05-26 07:07:58 -0700376 if not arch:
377 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
378
379 vboot = os.path.join('build', board, 'usr')
380 if arch == 'x86':
381 family = 'em100'
382 if in_chroot:
383 compiler = 'i686-pc-linux-gnu-'
384 else:
385 compiler = '/opt/i686/bin/i686-unknown-elf-'
386 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600387 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
388 elif arch == 'aarch64':
389 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
390 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
391 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700392 elif arch == 'sandbox':
393 compiler = ''
394 else:
395 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
396
397 if not options.build:
398 options.incremental = True
399
400 cpus = multiprocessing.cpu_count()
401
Simon Glassb89ae892013-07-18 15:23:35 -0600402 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700403 base = [
404 'make',
405 '-j%d' % cpus,
406 'O=%s' % outdir,
407 'ARCH=%s' % arch,
408 'CROSS_COMPILE=%s' % compiler,
409 '--no-print-directory',
410 'HOSTSTRIP=true',
411 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
412 'QEMU_ARCH=']
413
414 if options.verbose < 2:
415 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600416 elif options.verbose > 2:
417 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700418
419 if options.ro and options.rw:
420 cros_build_lib.Die('Cannot specify both --ro and --rw options')
421 if options.ro:
422 base.append('CROS_RO=1')
423 options.small = True
424
425 if options.rw:
426 base.append('CROS_RW=1')
427 options.small = True
428
429 if options.small:
430 base.append('CROS_SMALL=1')
431 else:
432 base.append('CROS_FULL=1')
433
434 if options.verified:
435 base += [
436 'VBOOT=%s' % vboot,
437 'MAKEFLAGS_VBOOT=DEBUG=1',
438 'QUIET=1',
439 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
440 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700441 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700442
443 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
444 # to a recent change, the need for which I didn't fully understand. But
445 # U-Boot doesn't normally use this. We have added an option to U-Boot to
446 # enable use of <stdint.h> and without it vboot will fail to build. So we
447 # need to enable it where ww can. We can't just enable it always since
448 # that would prevent this script from building other non-Chrome OS boards
449 # with a different (older) toolchain, or Chrome OS boards without vboot.
450 # So use USE_STDINT if the toolchain supports it, and not if not. This
451 # file was originally part of glibc but has recently migrated to the
452 # compiler so it is reasonable to use it with a stand-alone program like
453 # U-Boot. At this point the comment has got long enough that we may as
454 # well include some poetry which seems to be sorely lacking the code base,
455 # so this is from Ogden Nash:
456 # To keep your marriage brimming
457 # With love in the loving cup,
458 # Whenever you're wrong, admit it;
459 # Whenever you're right, shut up.
460 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Yu-Ju Hong3add4432014-01-30 11:46:15 -0800461 result = cros_build_lib.RunCommand(cmd,
462 input='#include <stdint.h>',
463 capture_output=True,
464 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700465 if result.returncode == 0:
466 base.append('USE_STDINT=1')
467
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600468 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700469 if options.trace:
470 base.append('FTRACE=1')
471 if options.separate:
472 base.append('DEV_TREE_SEPARATE=1')
473
474 if options.incremental:
475 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600476 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700477 if not os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600478 logging.warning('No build found for %s - dropping -i', board)
Simon Glass02741682013-05-26 07:07:58 -0700479 options.incremental = False
480
Simon Glassef7e4372016-07-20 09:38:47 -0600481 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700482 if os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600483 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700484
485 # For when U-Boot supports ccache
486 # See http://patchwork.ozlabs.org/patch/245079/
487 if use_ccache:
488 os.environ['CCACHE'] = 'ccache'
489
490 return base
491
492
493def RunBuild(options, base, target, queue):
494 """Run the U-Boot build.
495
496 Args:
497 options: Command line options.
498 base: Base U-Boot flags.
499 target: Target to build.
500 queue: A parallel queue to add jobs to.
501 """
502 Log('U-Boot build flags: %s' % ' '.join(base))
503
504 # Reconfigure U-Boot.
505 if not options.incremental:
506 # Ignore any error from this, some older U-Boots fail on this.
507 cros_build_lib.RunCommand(base + ['distclean'], **kwargs)
Simon Glass4e28d112016-11-16 13:52:48 -0700508 if os.path.exists('tools/genboardscfg.py'):
509 mtarget = 'defconfig'
510 else:
511 mtarget = 'config'
512 cmd = base + ['%s_%s' % (uboard, mtarget)]
Simon Glassc2fe94c2016-11-16 13:56:24 -0700513 result = cros_build_lib.RunCommand(cmd, capture_output=True,
514 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700515 if result.returncode:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700516 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output))
517 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700518
519 # Do the actual build.
520 if options.build:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700521 result = cros_build_lib.RunCommand(base + [target], capture_output=True,
522 combine_stdout_stderr=True, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700523 if result.returncode:
Simon Glass08b33082017-01-23 12:16:40 -0700524 # The build failed, so output the results to stderr.
525 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output),
526 file=sys.stderr)
Simon Glassc2fe94c2016-11-16 13:56:24 -0700527 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700528
529 files = ['%s/u-boot' % outdir]
530 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
531 if spl:
532 files += spl
533 if options.size:
Simon Glassc7d266d2013-07-18 15:15:57 -0600534 result = cros_build_lib.RunCommand([CompilerTool('size')] + files,
535 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700536 if result.returncode:
537 sys.exit()
538
539 # Create disassembly files .dis and .Dis (full dump)
540 for f in files:
541 base = os.path.splitext(f)[0]
542 if options.objdump:
543 queue.put(('-d', f, base + '.dis'))
544 queue.put(('-D', f, base + '.Dis'))
545 else:
546 # Remove old files which otherwise might be confusing
547 osutils.SafeUnlink(base + '.dis')
548 osutils.SafeUnlink(base + '.Dis')
549
550 Log('Output directory %s' % outdir)
551
552
553def WriteFirmware(options):
554 """Write firmware to the board.
555
556 This uses cros_bundle_firmware to create a firmware image and write it to
557 the board.
558
559 Args:
560 options: Command line options
561 """
562 flash = []
563 kernel = []
564 run = []
565 secure = []
566 servo = []
567 silent = []
568 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600569 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700570
571 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
572
573 if options.use_defaults:
574 bl1 = []
575 bmpblk = []
576 ecro = []
577 ecrw = []
578 defaults = []
579 else:
580 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
581 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
582 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
583 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
584 defaults = ['-D']
585
586 if arch == 'x86':
587 seabios = ['--seabios',
588 '##/build/%s/firmware/seabios.cbfs' % options.board]
589 else:
590 seabios = []
591
592 if options.sdcard:
593 dest = 'sd:.'
594 elif arch == 'x86':
595 dest = 'em100'
596 elif arch == 'sandbox':
597 dest = ''
598 else:
599 dest = 'usb'
600
601 port = SERVO_PORT.get(options.board, '')
602 if port:
603 servo = ['--servo', '%d' % port]
604
605 if options.flash:
606 flash = ['-F', 'spi']
607
Simon Glass46411592013-07-22 22:35:01 -0600608 # The small builds don't have the command line interpreter so cannot
609 # run the magic flasher script. So use the standard U-Boot in this
610 # case.
611 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700612 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600613 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
614
Michael Prattc88035d2013-07-31 16:27:29 -0700615 if options.mmc:
616 flash = ['-F', 'sdmmc']
617
Simon Glass02741682013-05-26 07:07:58 -0700618 if options.verbose:
619 verbose_arg = ['-v', '%s' % options.verbose]
620
621 if options.secure:
622 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
623
624 if not options.verified:
625 # Make a small image, without GBB, etc.
626 secure.append('-s')
627
628 if options.kernel:
629 kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]
630
631 if not options.console:
632 silent = ['--add-config-int', 'silent-console', '1']
633
634 if not options.run:
635 run = ['--bootcmd', 'none']
636
637 if arch != 'sandbox' and not in_chroot and servo:
638 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700639 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700640 dest = ''
641 servo = []
642 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700643 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700644 servo = []
645
646 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700647 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700648
649 if dest:
650 dest = ['-w', dest]
651 else:
652 dest = []
653
654 soc = SOCS.get(board)
655 if not soc:
656 soc = SOCS.get(uboard, '')
657 dt_name = DEFAULT_DTS.get(options.board, options.board)
658 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
659 Log('Device tree: %s' % dts_file)
660
661 if arch == 'sandbox':
662 uboot_fname = '%s/u-boot' % outdir
663 else:
664 uboot_fname = '%s/u-boot.bin' % outdir
665
Simon Glass46411592013-07-22 22:35:01 -0600666 if options.ro:
667 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
668 # ebuild one as RW.
669 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
670 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700671 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600672 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
673 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700674 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
675 '-b', options.board,
676 '-d', dts_file,
677 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
678 '-u', uboot_fname,
679 '-O', '%s/out' % outdir,
680 '-M', family]
681
682 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600683 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700684 if other:
685 cbf += other
686 if options.cbfargs:
687 for item in options.cbfargs:
688 cbf += item.split(' ')
689 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
690 (src_root, src_root))
691 Log(' '.join(cbf))
692 result = cros_build_lib.RunCommand(cbf, **kwargs)
693 if result.returncode:
694 cros_build_lib.Die('cros_bundle_firmware failed')
695
696 if not dest or not result.returncode:
Lann Martinffb95162018-08-28 12:02:54 -0600697 logging.info('Image is available at %s/out/image.bin', outdir)
Simon Glass02741682013-05-26 07:07:58 -0700698 else:
699 if result.returncode:
700 cros_build_lib.Die('Failed to write image to board')
701 else:
Lann Martinffb95162018-08-28 12:02:54 -0600702 logging.info('Image written to board with %s', ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700703
704
705def main(argv):
706 """Main function for script to build/write firmware.
707
708 Args:
709 argv: Program arguments.
710 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400711 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700712 base = SetupBuild(options)
713
714 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400715 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700716
717 if options.write:
718 WriteFirmware(options)
719
720 if options.objdump:
721 Log('Writing diasssembly files')