blob: 8923d909371281ad12510175a825306554f79aa1 [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 """
Mike Frysinger45602c72019-09-22 02:15:11 -0400198 result = cros_build_lib.run(
Simon Glass02741682013-05-26 07:07:58 -0700199 [CompilerTool('objdump'), flag, infile],
Mike Frysingerae3e2c72019-12-07 02:35:12 -0500200 stdout=outfile, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700201 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', '-']
Mike Frysinger45602c72019-09-22 02:15:11 -0400461 result = cros_build_lib.run(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.
Mike Frysinger45602c72019-09-22 02:15:11 -0400507 cros_build_lib.run(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)]
Mike Frysinger45602c72019-09-22 02:15:11 -0400513 result = cros_build_lib.run(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:
Mike Frysinger45602c72019-09-22 02:15:11 -0400521 result = cros_build_lib.run(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:
Mike Frysinger45602c72019-09-22 02:15:11 -0400534 result = cros_build_lib.run([CompilerTool('size')] + files, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700535 if result.returncode:
536 sys.exit()
537
538 # Create disassembly files .dis and .Dis (full dump)
539 for f in files:
540 base = os.path.splitext(f)[0]
541 if options.objdump:
542 queue.put(('-d', f, base + '.dis'))
543 queue.put(('-D', f, base + '.Dis'))
544 else:
545 # Remove old files which otherwise might be confusing
546 osutils.SafeUnlink(base + '.dis')
547 osutils.SafeUnlink(base + '.Dis')
548
549 Log('Output directory %s' % outdir)
550
551
552def WriteFirmware(options):
553 """Write firmware to the board.
554
555 This uses cros_bundle_firmware to create a firmware image and write it to
556 the board.
557
558 Args:
559 options: Command line options
560 """
561 flash = []
562 kernel = []
563 run = []
564 secure = []
565 servo = []
566 silent = []
567 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600568 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700569
570 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
571
572 if options.use_defaults:
573 bl1 = []
574 bmpblk = []
575 ecro = []
576 ecrw = []
577 defaults = []
578 else:
579 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
580 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
581 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
582 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
583 defaults = ['-D']
584
585 if arch == 'x86':
586 seabios = ['--seabios',
587 '##/build/%s/firmware/seabios.cbfs' % options.board]
588 else:
589 seabios = []
590
591 if options.sdcard:
592 dest = 'sd:.'
593 elif arch == 'x86':
594 dest = 'em100'
595 elif arch == 'sandbox':
596 dest = ''
597 else:
598 dest = 'usb'
599
600 port = SERVO_PORT.get(options.board, '')
601 if port:
602 servo = ['--servo', '%d' % port]
603
604 if options.flash:
605 flash = ['-F', 'spi']
606
Simon Glass46411592013-07-22 22:35:01 -0600607 # The small builds don't have the command line interpreter so cannot
608 # run the magic flasher script. So use the standard U-Boot in this
609 # case.
610 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700611 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600612 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
613
Michael Prattc88035d2013-07-31 16:27:29 -0700614 if options.mmc:
615 flash = ['-F', 'sdmmc']
616
Simon Glass02741682013-05-26 07:07:58 -0700617 if options.verbose:
618 verbose_arg = ['-v', '%s' % options.verbose]
619
620 if options.secure:
621 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
622
623 if not options.verified:
624 # Make a small image, without GBB, etc.
625 secure.append('-s')
626
627 if options.kernel:
628 kernel = ['--kernel', '##/build/%s/boot/vmlinux.uimg' % options.board]
629
630 if not options.console:
631 silent = ['--add-config-int', 'silent-console', '1']
632
633 if not options.run:
634 run = ['--bootcmd', 'none']
635
636 if arch != 'sandbox' and not in_chroot and servo:
637 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700638 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700639 dest = ''
640 servo = []
641 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700642 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700643 servo = []
644
645 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700646 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700647
648 if dest:
649 dest = ['-w', dest]
650 else:
651 dest = []
652
653 soc = SOCS.get(board)
654 if not soc:
655 soc = SOCS.get(uboard, '')
656 dt_name = DEFAULT_DTS.get(options.board, options.board)
657 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
658 Log('Device tree: %s' % dts_file)
659
660 if arch == 'sandbox':
661 uboot_fname = '%s/u-boot' % outdir
662 else:
663 uboot_fname = '%s/u-boot.bin' % outdir
664
Simon Glass46411592013-07-22 22:35:01 -0600665 if options.ro:
666 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
667 # ebuild one as RW.
668 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
669 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700670 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600671 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
672 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700673 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
674 '-b', options.board,
675 '-d', dts_file,
676 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
677 '-u', uboot_fname,
678 '-O', '%s/out' % outdir,
679 '-M', family]
680
681 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600682 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700683 if other:
684 cbf += other
685 if options.cbfargs:
686 for item in options.cbfargs:
687 cbf += item.split(' ')
688 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
689 (src_root, src_root))
690 Log(' '.join(cbf))
Mike Frysinger45602c72019-09-22 02:15:11 -0400691 result = cros_build_lib.run(cbf, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700692 if result.returncode:
693 cros_build_lib.Die('cros_bundle_firmware failed')
694
695 if not dest or not result.returncode:
Lann Martinffb95162018-08-28 12:02:54 -0600696 logging.info('Image is available at %s/out/image.bin', outdir)
Simon Glass02741682013-05-26 07:07:58 -0700697 else:
698 if result.returncode:
699 cros_build_lib.Die('Failed to write image to board')
700 else:
Lann Martinffb95162018-08-28 12:02:54 -0600701 logging.info('Image written to board with %s', ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700702
703
704def main(argv):
705 """Main function for script to build/write firmware.
706
707 Args:
708 argv: Program arguments.
709 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400710 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700711 base = SetupBuild(options)
712
713 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400714 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700715
716 if options.write:
717 WriteFirmware(options)
718
719 if options.objdump:
720 Log('Writing diasssembly files')