blob: 06c1bec903dda97b495017ced14211463b591cde [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
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500108import subprocess
Simon Glass02741682013-05-26 07:07:58 -0700109import sys
110
Aviv Keshetb7519e12016-10-04 00:50:00 -0700111from chromite.lib import constants
Simon Glass02741682013-05-26 07:07:58 -0700112from chromite.lib import commandline
113from chromite.lib import cros_build_lib
Ralph Nathan91874ca2015-03-19 13:29:41 -0700114from chromite.lib import cros_logging as logging
Simon Glass02741682013-05-26 07:07:58 -0700115from chromite.lib import osutils
116from chromite.lib import parallel
117
118
119arch = None
120board = None
121compiler = None
122default_board = None
123family = None
124in_chroot = True
125
Simon Glass02741682013-05-26 07:07:58 -0700126logging.basicConfig(format='%(message)s')
Mike Frysingerf5a3b2d2019-12-12 14:36:17 -0500127kwargs = {'print_cmd': False, 'check': False,
Ralph Nathan23a12212015-03-25 10:27:54 -0700128 'debug_level': logging.getLogger().getEffectiveLevel()}
Simon Glass02741682013-05-26 07:07:58 -0700129
130outdir = ''
131
132 # If you have multiple boards connected on different servo ports, put lines
133# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
134SERVO_PORT = {}
135
136smdk = None
137src_root = os.path.join(constants.SOURCE_ROOT, 'src')
138in_chroot = cros_build_lib.IsInsideChroot()
139
140uboard = ''
141
142default_board = 'peach_pit'
143use_ccache = False
144vendor = None
145verbose = False
146
147# Special cases for the U-Boot board config, the SOCs and default device tree
148# since the naming is not always consistent.
149# x86 has a lot of boards, but to U-Boot they are all the same
150UBOARDS = {
151 'daisy': 'smdk5250',
152 'peach': 'smdk5420',
153}
154for b in ['alex', 'butterfly', 'emeraldlake2', 'link', 'lumpy', 'parrot',
155 'stout', 'stumpy']:
156 UBOARDS[b] = 'coreboot-x86'
157 UBOARDS['chromeos_%s' % b] = 'chromeos_coreboot'
158
159SOCS = {
160 'coreboot-x86': '',
161 'chromeos_coreboot': '',
162 'daisy': 'exynos5250-',
163 'peach': 'exynos5420-',
164}
165
166DEFAULT_DTS = {
167 'daisy': 'snow',
168 'daisy_spring': 'spring',
169 'peach_pit': 'peach-pit',
170}
171
Simon Glassb89ae892013-07-18 15:23:35 -0600172OUT_DIR = '/tmp/crosfw'
173
Simon Glass02741682013-05-26 07:07:58 -0700174rc_file = os.path.expanduser('~/.crosfwrc')
175if os.path.exists(rc_file):
Mike Frysinger5d535ac2019-07-03 03:29:47 -0400176 with open(rc_file) as fp:
177 # pylint: disable=exec-used
178 exec(compile(fp.read(), rc_file, 'exec'))
Simon Glass02741682013-05-26 07:07:58 -0700179
180
181def Log(msg):
182 """Print out a message if we are in verbose mode.
183
184 Args:
185 msg: Message to print
186 """
187 if verbose:
Ralph Nathan03047282015-03-23 11:09:32 -0700188 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700189
190
191def Dumper(flag, infile, outfile):
192 """Run objdump on an input file.
193
194 Args:
195 flag: Flag to pass objdump (e.g. '-d').
196 infile: Input file to process.
197 outfile: Output file to write to.
198 """
Mike Frysinger45602c72019-09-22 02:15:11 -0400199 result = cros_build_lib.run(
Simon Glass02741682013-05-26 07:07:58 -0700200 [CompilerTool('objdump'), flag, infile],
Mike Frysingerae3e2c72019-12-07 02:35:12 -0500201 stdout=outfile, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700202 if result.returncode:
203 sys.exit()
204
205
206def CompilerTool(tool):
207 """Returns the cross-compiler tool filename.
208
209 Args:
210 tool: Tool name to return, e.g. 'size'.
211
212 Returns:
213 Filename of requested tool.
214 """
215 return '%s%s' % (compiler, tool)
216
217
218def ParseCmdline(argv):
219 """Parse all command line options.
220
221 Args:
222 argv: Arguments to parse.
223
224 Returns:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400225 The parsed options object
Simon Glass02741682013-05-26 07:07:58 -0700226 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400227 parser = commandline.ArgumentParser(description=__doc__)
228 parser.add_argument('-a', '--cbfargs', action='append',
229 help='Pass extra arguments to cros_bundle_firmware')
230 parser.add_argument('-b', '--board', type=str, default=default_board,
231 help='Select board to build (daisy/peach_pit/link)')
232 parser.add_argument('-B', '--build', action='store_false', default=True,
233 help="Don't build U-Boot, just configure device tree")
234 parser.add_argument('-C', '--console', action='store_false', default=True,
235 help='Permit console output')
236 parser.add_argument('-d', '--dt', default='seaboard',
237 help='Select name of device tree file to use')
238 parser.add_argument('-D', '--nodefaults', dest='use_defaults',
239 action='store_false', default=True,
240 help="Don't select default filenames for those not given")
241 parser.add_argument('-F', '--flash', action='store_true', default=False,
242 help='Create magic flasher for SPI flash')
243 parser.add_argument('-M', '--mmc', action='store_true', default=False,
244 help='Create magic flasher for eMMC')
245 parser.add_argument('-i', '--incremental', action='store_true', default=False,
246 help="Don't reconfigure and clean")
247 parser.add_argument('-k', '--kernel', action='store_true', default=False,
248 help='Send kernel to board also')
249 parser.add_argument('-O', '--objdump', action='store_true', default=False,
250 help='Write disassembly output')
251 parser.add_argument('-r', '--run', action='store_false', default=True,
252 help='Run the boot command')
253 parser.add_argument('--ro', action='store_true', default=False,
254 help='Create Chrome OS read-only image')
255 parser.add_argument('--rw', action='store_true', default=False,
256 help='Create Chrome OS read-write image')
257 parser.add_argument('-s', '--separate', action='store_false', default=True,
258 help='Link device tree into U-Boot, instead of separate')
259 parser.add_argument('-S', '--secure', action='store_true', default=False,
260 help='Use vboot_twostop secure boot')
261 parser.add_argument('--small', action='store_true', default=False,
262 help='Create Chrome OS small image')
263 parser.add_argument('-t', '--trace', action='store_true', default=False,
264 help='Enable trace support')
265 parser.add_argument('-v', '--verbose', type=int, default=0,
266 help='Make cros_bundle_firmware verbose')
267 parser.add_argument('-V', '--verified', action='store_true', default=False,
268 help='Include Chrome OS verified boot components')
269 parser.add_argument('-w', '--write', action='store_false', default=True,
270 help="Don't write image to board using usb/em100")
271 parser.add_argument('-x', '--sdcard', action='store_true', default=False,
272 help='Write to SD card instead of USB/em100')
273 parser.add_argument('-z', '--size', action='store_true', default=False,
274 help='Display U-Boot image size')
Simon Glassf67f93e2016-08-04 20:29:51 -0600275 parser.add_argument('target', nargs='?', default='all',
Mike Frysinger4e91d822015-06-04 02:01:40 -0400276 help='The target to work on')
Simon Glass02741682013-05-26 07:07:58 -0700277 return parser.parse_args(argv)
278
279
Simon Glassc1a323a2016-08-04 20:29:51 -0600280def FindCompiler(gcc, cros_prefix):
281 """Look up the compiler for an architecture.
282
283 Args:
284 gcc: GCC architecture, either 'arm' or 'aarch64'
285 cros_prefix: Full Chromium OS toolchain prefix
286 """
287 if in_chroot:
288 # Use the Chromium OS toolchain.
289 prefix = cros_prefix
290 else:
291 prefix = glob.glob('/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc' % gcc)
292 if not prefix:
Simon Glassd0557f02016-11-15 08:51:34 -0700293 cros_build_lib.Die("""Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600294Install a Linaro toolchain from:
295https://launchpad.net/linaro-toolchain-binaries
Simon Glassd0557f02016-11-15 08:51:34 -0700296or see cros/commands/cros_chrome_sdk.py.""" % gcc)
Simon Glassc1a323a2016-08-04 20:29:51 -0600297 prefix = re.sub('gcc$', '', prefix[0])
298 return prefix
299
300
Simon Glass02741682013-05-26 07:07:58 -0700301def SetupBuild(options):
302 """Set up parameters needed for the build.
303
304 This checks the current environment and options and sets up various things
305 needed for the build, including 'base' which holds the base flags for
306 passing to the U-Boot Makefile.
307
308 Args:
309 options: Command line options
310
311 Returns:
312 Base flags to use for U-Boot, as a list.
313 """
Mike Frysinger27e21b72018-07-12 14:20:21 -0400314 # pylint: disable=global-statement
Simon Glass02741682013-05-26 07:07:58 -0700315 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
316
317 if not verbose:
318 verbose = options.verbose != 0
319
Ralph Nathan23a12212015-03-25 10:27:54 -0700320 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700321
322 Log('Building for %s' % options.board)
323
Simon Glass9d9bf942013-07-10 16:32:42 -0700324 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
325 # But don't mess up upstream boards which use _ in their name.
Simon Glass02741682013-05-26 07:07:58 -0700326 parts = options.board.split('_')
Simon Glass9d9bf942013-07-10 16:32:42 -0700327 if parts[0] in ['daisy', 'peach']:
328 board = parts[0]
329 else:
330 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700331
332 # To allow this to be run from 'cros_sdk'
333 if in_chroot:
334 os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))
335
336 base_board = board
337
338 if options.verified:
339 base_board = 'chromeos_%s' % base_board
340
341 uboard = UBOARDS.get(base_board, base_board)
342 Log('U-Boot board is %s' % uboard)
343
344 # Pull out some information from the U-Boot boards config file
345 family = None
Simon Glasseb0c5352016-07-20 09:29:34 -0600346 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
347 if os.path.exists('MAINTAINERS'):
348 board_format = PRE_KBUILD
349 else:
350 board_format = PRE_KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700351 with open('boards.cfg') as f:
352 for line in f:
Simon Glasseb0c5352016-07-20 09:29:34 -0600353 if 'genboardscfg' in line:
354 board_format = KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700355 if uboard in line:
356 if line[0] == '#':
357 continue
358 fields = line.split()
359 if not fields:
360 continue
361 arch = fields[1]
362 fields += [None, None, None]
Simon Glasseb0c5352016-07-20 09:29:34 -0600363 if board_format == PRE_KBUILD:
364 smdk = fields[3]
365 vendor = fields[4]
366 family = fields[5]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700367 target = fields[6]
Simon Glasseb0c5352016-07-20 09:29:34 -0600368 elif board_format in (PRE_KCONFIG, KCONFIG):
369 smdk = fields[5]
370 vendor = fields[4]
371 family = fields[3]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700372 target = fields[0]
373
374 # Make sure this is the right target.
375 if target == uboard:
376 break
Simon Glass02741682013-05-26 07:07:58 -0700377 if not arch:
378 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
379
380 vboot = os.path.join('build', board, 'usr')
381 if arch == 'x86':
382 family = 'em100'
383 if in_chroot:
384 compiler = 'i686-pc-linux-gnu-'
385 else:
386 compiler = '/opt/i686/bin/i686-unknown-elf-'
387 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600388 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
389 elif arch == 'aarch64':
390 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
391 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
392 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700393 elif arch == 'sandbox':
394 compiler = ''
395 else:
396 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
397
398 if not options.build:
399 options.incremental = True
400
401 cpus = multiprocessing.cpu_count()
402
Simon Glassb89ae892013-07-18 15:23:35 -0600403 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700404 base = [
405 'make',
406 '-j%d' % cpus,
407 'O=%s' % outdir,
408 'ARCH=%s' % arch,
409 'CROSS_COMPILE=%s' % compiler,
410 '--no-print-directory',
411 'HOSTSTRIP=true',
412 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
413 'QEMU_ARCH=']
414
415 if options.verbose < 2:
416 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600417 elif options.verbose > 2:
418 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700419
420 if options.ro and options.rw:
421 cros_build_lib.Die('Cannot specify both --ro and --rw options')
422 if options.ro:
423 base.append('CROS_RO=1')
424 options.small = True
425
426 if options.rw:
427 base.append('CROS_RW=1')
428 options.small = True
429
430 if options.small:
431 base.append('CROS_SMALL=1')
432 else:
433 base.append('CROS_FULL=1')
434
435 if options.verified:
436 base += [
437 'VBOOT=%s' % vboot,
438 'MAKEFLAGS_VBOOT=DEBUG=1',
439 'QUIET=1',
440 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
441 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700442 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700443
444 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
445 # to a recent change, the need for which I didn't fully understand. But
446 # U-Boot doesn't normally use this. We have added an option to U-Boot to
447 # enable use of <stdint.h> and without it vboot will fail to build. So we
448 # need to enable it where ww can. We can't just enable it always since
449 # that would prevent this script from building other non-Chrome OS boards
450 # with a different (older) toolchain, or Chrome OS boards without vboot.
451 # So use USE_STDINT if the toolchain supports it, and not if not. This
452 # file was originally part of glibc but has recently migrated to the
453 # compiler so it is reasonable to use it with a stand-alone program like
454 # U-Boot. At this point the comment has got long enough that we may as
455 # well include some poetry which seems to be sorely lacking the code base,
456 # so this is from Ogden Nash:
457 # To keep your marriage brimming
458 # With love in the loving cup,
459 # Whenever you're wrong, admit it;
460 # Whenever you're right, shut up.
461 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Mike Frysinger45602c72019-09-22 02:15:11 -0400462 result = cros_build_lib.run(cmd,
463 input='#include <stdint.h>',
464 capture_output=True,
465 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700466 if result.returncode == 0:
467 base.append('USE_STDINT=1')
468
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600469 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700470 if options.trace:
471 base.append('FTRACE=1')
472 if options.separate:
473 base.append('DEV_TREE_SEPARATE=1')
474
475 if options.incremental:
476 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600477 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700478 if not os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600479 logging.warning('No build found for %s - dropping -i', board)
Simon Glass02741682013-05-26 07:07:58 -0700480 options.incremental = False
481
Simon Glassef7e4372016-07-20 09:38:47 -0600482 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700483 if os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600484 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700485
486 # For when U-Boot supports ccache
487 # See http://patchwork.ozlabs.org/patch/245079/
488 if use_ccache:
489 os.environ['CCACHE'] = 'ccache'
490
491 return base
492
493
494def RunBuild(options, base, target, queue):
495 """Run the U-Boot build.
496
497 Args:
498 options: Command line options.
499 base: Base U-Boot flags.
500 target: Target to build.
501 queue: A parallel queue to add jobs to.
502 """
503 Log('U-Boot build flags: %s' % ' '.join(base))
504
505 # Reconfigure U-Boot.
506 if not options.incremental:
507 # Ignore any error from this, some older U-Boots fail on this.
Mike Frysinger45602c72019-09-22 02:15:11 -0400508 cros_build_lib.run(base + ['distclean'], **kwargs)
Simon Glass4e28d112016-11-16 13:52:48 -0700509 if os.path.exists('tools/genboardscfg.py'):
510 mtarget = 'defconfig'
511 else:
512 mtarget = 'config'
513 cmd = base + ['%s_%s' % (uboard, mtarget)]
Mike Frysinger45602c72019-09-22 02:15:11 -0400514 result = cros_build_lib.run(cmd, capture_output=True,
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500515 stderr=subprocess.STDOUT, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700516 if result.returncode:
Simon Glassc2fe94c2016-11-16 13:56:24 -0700517 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output))
518 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700519
520 # Do the actual build.
521 if options.build:
Mike Frysinger45602c72019-09-22 02:15:11 -0400522 result = cros_build_lib.run(base + [target], capture_output=True,
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500523 stderr=subprocess.STDOUT, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700524 if result.returncode:
Simon Glass08b33082017-01-23 12:16:40 -0700525 # The build failed, so output the results to stderr.
526 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.output),
527 file=sys.stderr)
Simon Glassc2fe94c2016-11-16 13:56:24 -0700528 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700529
530 files = ['%s/u-boot' % outdir]
531 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
532 if spl:
533 files += spl
534 if options.size:
Mike Frysinger45602c72019-09-22 02:15:11 -0400535 result = cros_build_lib.run([CompilerTool('size')] + files, **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))
Mike Frysinger45602c72019-09-22 02:15:11 -0400692 result = cros_build_lib.run(cbf, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700693 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')