blob: be512573ea7c775c5799a10f721e82f150b8db0e [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
Mike Frysinger0246c1f2021-12-14 01:17:17 -050092--bmpblk ~/chromiumos/src/third_party/u-boot/bmp.bin
Simon Glass02741682013-05-26 07:07:58 -070093
94For example: -a "--gbb-flags -force-dev-switch-on"
95
96Note the standard bmpblk is at:
Mike Frysinger0246c1f2021-12-14 01:17:17 -050097 ~/chromiumos/src/third_party/chromiumos-overlay/sys-boot/
98 chromeos-bootimage/files/bmpblk.bin
Simon Glass02741682013-05-26 07:07:58 -070099"""
100
101import glob
Chris McDonald59650c32021-07-20 15:29:28 -0600102import logging
Simon Glass02741682013-05-26 07:07:58 -0700103import multiprocessing
104import os
105import re
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500106import subprocess
Simon Glass02741682013-05-26 07:07:58 -0700107import sys
108
Simon Glass02741682013-05-26 07:07:58 -0700109from chromite.lib import commandline
Chris McDonald59650c32021-07-20 15:29:28 -0600110from chromite.lib import constants
Simon Glass02741682013-05-26 07:07:58 -0700111from chromite.lib import cros_build_lib
112from chromite.lib import osutils
113from chromite.lib import parallel
114
115
116arch = None
117board = None
118compiler = None
119default_board = None
120family = None
121in_chroot = True
122
Simon Glass02741682013-05-26 07:07:58 -0700123logging.basicConfig(format='%(message)s')
Mike Frysingerf5a3b2d2019-12-12 14:36:17 -0500124kwargs = {'print_cmd': False, 'check': False,
Ralph Nathan23a12212015-03-25 10:27:54 -0700125 'debug_level': logging.getLogger().getEffectiveLevel()}
Simon Glass02741682013-05-26 07:07:58 -0700126
127outdir = ''
128
129 # If you have multiple boards connected on different servo ports, put lines
130# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
131SERVO_PORT = {}
132
133smdk = None
134src_root = os.path.join(constants.SOURCE_ROOT, 'src')
135in_chroot = cros_build_lib.IsInsideChroot()
136
137uboard = ''
138
139default_board = 'peach_pit'
140use_ccache = False
141vendor = None
142verbose = False
143
144# Special cases for the U-Boot board config, the SOCs and default device tree
145# since the naming is not always consistent.
146# x86 has a lot of boards, but to U-Boot they are all the same
147UBOARDS = {
148 'daisy': 'smdk5250',
149 'peach': 'smdk5420',
150}
151for b in ['alex', 'butterfly', 'emeraldlake2', 'link', 'lumpy', 'parrot',
152 'stout', 'stumpy']:
153 UBOARDS[b] = 'coreboot-x86'
154 UBOARDS['chromeos_%s' % b] = 'chromeos_coreboot'
155
156SOCS = {
157 'coreboot-x86': '',
158 'chromeos_coreboot': '',
159 'daisy': 'exynos5250-',
160 'peach': 'exynos5420-',
161}
162
163DEFAULT_DTS = {
164 'daisy': 'snow',
165 'daisy_spring': 'spring',
166 'peach_pit': 'peach-pit',
167}
168
Simon Glassb89ae892013-07-18 15:23:35 -0600169OUT_DIR = '/tmp/crosfw'
170
Simon Glass02741682013-05-26 07:07:58 -0700171rc_file = os.path.expanduser('~/.crosfwrc')
172if os.path.exists(rc_file):
Mike Frysinger5d535ac2019-07-03 03:29:47 -0400173 with open(rc_file) as fp:
174 # pylint: disable=exec-used
175 exec(compile(fp.read(), rc_file, 'exec'))
Simon Glass02741682013-05-26 07:07:58 -0700176
177
178def Log(msg):
179 """Print out a message if we are in verbose mode.
180
181 Args:
182 msg: Message to print
183 """
184 if verbose:
Ralph Nathan03047282015-03-23 11:09:32 -0700185 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700186
187
188def Dumper(flag, infile, outfile):
189 """Run objdump on an input file.
190
191 Args:
192 flag: Flag to pass objdump (e.g. '-d').
193 infile: Input file to process.
194 outfile: Output file to write to.
195 """
Mike Frysinger45602c72019-09-22 02:15:11 -0400196 result = cros_build_lib.run(
Simon Glass02741682013-05-26 07:07:58 -0700197 [CompilerTool('objdump'), flag, infile],
Mike Frysingerae3e2c72019-12-07 02:35:12 -0500198 stdout=outfile, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700199 if result.returncode:
200 sys.exit()
201
202
203def CompilerTool(tool):
204 """Returns the cross-compiler tool filename.
205
206 Args:
207 tool: Tool name to return, e.g. 'size'.
208
209 Returns:
210 Filename of requested tool.
211 """
212 return '%s%s' % (compiler, tool)
213
214
215def ParseCmdline(argv):
216 """Parse all command line options.
217
218 Args:
219 argv: Arguments to parse.
220
221 Returns:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400222 The parsed options object
Simon Glass02741682013-05-26 07:07:58 -0700223 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400224 parser = commandline.ArgumentParser(description=__doc__)
225 parser.add_argument('-a', '--cbfargs', action='append',
226 help='Pass extra arguments to cros_bundle_firmware')
227 parser.add_argument('-b', '--board', type=str, default=default_board,
228 help='Select board to build (daisy/peach_pit/link)')
229 parser.add_argument('-B', '--build', action='store_false', default=True,
230 help="Don't build U-Boot, just configure device tree")
231 parser.add_argument('-C', '--console', action='store_false', default=True,
232 help='Permit console output')
233 parser.add_argument('-d', '--dt', default='seaboard',
234 help='Select name of device tree file to use')
235 parser.add_argument('-D', '--nodefaults', dest='use_defaults',
236 action='store_false', default=True,
237 help="Don't select default filenames for those not given")
238 parser.add_argument('-F', '--flash', action='store_true', default=False,
239 help='Create magic flasher for SPI flash')
240 parser.add_argument('-M', '--mmc', action='store_true', default=False,
241 help='Create magic flasher for eMMC')
242 parser.add_argument('-i', '--incremental', action='store_true', default=False,
243 help="Don't reconfigure and clean")
244 parser.add_argument('-k', '--kernel', action='store_true', default=False,
245 help='Send kernel to board also')
246 parser.add_argument('-O', '--objdump', action='store_true', default=False,
247 help='Write disassembly output')
248 parser.add_argument('-r', '--run', action='store_false', default=True,
249 help='Run the boot command')
250 parser.add_argument('--ro', action='store_true', default=False,
251 help='Create Chrome OS read-only image')
252 parser.add_argument('--rw', action='store_true', default=False,
253 help='Create Chrome OS read-write image')
254 parser.add_argument('-s', '--separate', action='store_false', default=True,
255 help='Link device tree into U-Boot, instead of separate')
256 parser.add_argument('-S', '--secure', action='store_true', default=False,
257 help='Use vboot_twostop secure boot')
258 parser.add_argument('--small', action='store_true', default=False,
259 help='Create Chrome OS small image')
260 parser.add_argument('-t', '--trace', action='store_true', default=False,
261 help='Enable trace support')
Mike Frysinger4e91d822015-06-04 02:01:40 -0400262 parser.add_argument('-V', '--verified', action='store_true', default=False,
263 help='Include Chrome OS verified boot components')
264 parser.add_argument('-w', '--write', action='store_false', default=True,
265 help="Don't write image to board using usb/em100")
266 parser.add_argument('-x', '--sdcard', action='store_true', default=False,
267 help='Write to SD card instead of USB/em100')
268 parser.add_argument('-z', '--size', action='store_true', default=False,
269 help='Display U-Boot image size')
Simon Glassf67f93e2016-08-04 20:29:51 -0600270 parser.add_argument('target', nargs='?', default='all',
Mike Frysinger4e91d822015-06-04 02:01:40 -0400271 help='The target to work on')
Simon Glass02741682013-05-26 07:07:58 -0700272 return parser.parse_args(argv)
273
274
Simon Glassc1a323a2016-08-04 20:29:51 -0600275def FindCompiler(gcc, cros_prefix):
276 """Look up the compiler for an architecture.
277
278 Args:
279 gcc: GCC architecture, either 'arm' or 'aarch64'
280 cros_prefix: Full Chromium OS toolchain prefix
281 """
282 if in_chroot:
283 # Use the Chromium OS toolchain.
284 prefix = cros_prefix
285 else:
286 prefix = glob.glob('/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc' % gcc)
287 if not prefix:
Simon Glassd0557f02016-11-15 08:51:34 -0700288 cros_build_lib.Die("""Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600289Install a Linaro toolchain from:
290https://launchpad.net/linaro-toolchain-binaries
Simon Glassd0557f02016-11-15 08:51:34 -0700291or see cros/commands/cros_chrome_sdk.py.""" % gcc)
Simon Glassc1a323a2016-08-04 20:29:51 -0600292 prefix = re.sub('gcc$', '', prefix[0])
293 return prefix
294
295
Simon Glass02741682013-05-26 07:07:58 -0700296def SetupBuild(options):
297 """Set up parameters needed for the build.
298
299 This checks the current environment and options and sets up various things
300 needed for the build, including 'base' which holds the base flags for
301 passing to the U-Boot Makefile.
302
303 Args:
304 options: Command line options
305
306 Returns:
307 Base flags to use for U-Boot, as a list.
308 """
Mike Frysinger27e21b72018-07-12 14:20:21 -0400309 # pylint: disable=global-statement
Simon Glass02741682013-05-26 07:07:58 -0700310 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
311
312 if not verbose:
313 verbose = options.verbose != 0
314
Ralph Nathan23a12212015-03-25 10:27:54 -0700315 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700316
317 Log('Building for %s' % options.board)
318
Simon Glass9d9bf942013-07-10 16:32:42 -0700319 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
320 # But don't mess up upstream boards which use _ in their name.
Simon Glass02741682013-05-26 07:07:58 -0700321 parts = options.board.split('_')
Simon Glass9d9bf942013-07-10 16:32:42 -0700322 if parts[0] in ['daisy', 'peach']:
323 board = parts[0]
324 else:
325 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700326
327 # To allow this to be run from 'cros_sdk'
328 if in_chroot:
329 os.chdir(os.path.join(src_root, 'third_party', 'u-boot', 'files'))
330
331 base_board = board
332
333 if options.verified:
334 base_board = 'chromeos_%s' % base_board
335
336 uboard = UBOARDS.get(base_board, base_board)
337 Log('U-Boot board is %s' % uboard)
338
339 # Pull out some information from the U-Boot boards config file
340 family = None
Simon Glasseb0c5352016-07-20 09:29:34 -0600341 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
342 if os.path.exists('MAINTAINERS'):
343 board_format = PRE_KBUILD
344 else:
345 board_format = PRE_KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700346 with open('boards.cfg') as f:
347 for line in f:
Simon Glasseb0c5352016-07-20 09:29:34 -0600348 if 'genboardscfg' in line:
349 board_format = KCONFIG
Simon Glass02741682013-05-26 07:07:58 -0700350 if uboard in line:
351 if line[0] == '#':
352 continue
353 fields = line.split()
354 if not fields:
355 continue
356 arch = fields[1]
357 fields += [None, None, None]
Simon Glasseb0c5352016-07-20 09:29:34 -0600358 if board_format == PRE_KBUILD:
359 smdk = fields[3]
360 vendor = fields[4]
361 family = fields[5]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700362 target = fields[6]
Simon Glasseb0c5352016-07-20 09:29:34 -0600363 elif board_format in (PRE_KCONFIG, KCONFIG):
364 smdk = fields[5]
365 vendor = fields[4]
366 family = fields[3]
Simon Glass5a5a36e2016-11-15 08:51:34 -0700367 target = fields[0]
368
369 # Make sure this is the right target.
370 if target == uboard:
371 break
Simon Glass02741682013-05-26 07:07:58 -0700372 if not arch:
373 cros_build_lib.Die("Selected board '%s' not found in boards.cfg." % board)
374
375 vboot = os.path.join('build', board, 'usr')
376 if arch == 'x86':
377 family = 'em100'
378 if in_chroot:
379 compiler = 'i686-pc-linux-gnu-'
380 else:
381 compiler = '/opt/i686/bin/i686-unknown-elf-'
382 elif arch == 'arm':
Simon Glassc1a323a2016-08-04 20:29:51 -0600383 compiler = FindCompiler(arch, 'armv7a-cros-linux-gnueabi-')
384 elif arch == 'aarch64':
385 compiler = FindCompiler(arch, 'aarch64-cros-linux-gnu-')
386 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
387 arch = 'arm'
Simon Glass02741682013-05-26 07:07:58 -0700388 elif arch == 'sandbox':
389 compiler = ''
390 else:
391 cros_build_lib.Die("Selected arch '%s' not supported." % arch)
392
393 if not options.build:
394 options.incremental = True
395
396 cpus = multiprocessing.cpu_count()
397
Simon Glassb89ae892013-07-18 15:23:35 -0600398 outdir = os.path.join(OUT_DIR, uboard)
Simon Glass02741682013-05-26 07:07:58 -0700399 base = [
400 'make',
401 '-j%d' % cpus,
402 'O=%s' % outdir,
403 'ARCH=%s' % arch,
404 'CROSS_COMPILE=%s' % compiler,
405 '--no-print-directory',
406 'HOSTSTRIP=true',
407 'DEV_TREE_SRC=%s-%s' % (family, options.dt),
408 'QEMU_ARCH=']
409
410 if options.verbose < 2:
411 base.append('-s')
Simon Glass234e5f32016-07-20 09:11:59 -0600412 elif options.verbose > 2:
413 base.append('V=1')
Simon Glass02741682013-05-26 07:07:58 -0700414
415 if options.ro and options.rw:
416 cros_build_lib.Die('Cannot specify both --ro and --rw options')
417 if options.ro:
418 base.append('CROS_RO=1')
419 options.small = True
420
421 if options.rw:
422 base.append('CROS_RW=1')
423 options.small = True
424
425 if options.small:
426 base.append('CROS_SMALL=1')
427 else:
428 base.append('CROS_FULL=1')
429
430 if options.verified:
431 base += [
432 'VBOOT=%s' % vboot,
433 'MAKEFLAGS_VBOOT=DEBUG=1',
434 'QUIET=1',
435 'CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS',
436 'VBOOT_SOURCE=%s/platform/vboot_reference' % src_root]
Simon Glass9d9bf942013-07-10 16:32:42 -0700437 base.append('VBOOT_DEBUG=1')
Simon Glass02741682013-05-26 07:07:58 -0700438
439 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
440 # to a recent change, the need for which I didn't fully understand. But
441 # U-Boot doesn't normally use this. We have added an option to U-Boot to
442 # enable use of <stdint.h> and without it vboot will fail to build. So we
443 # need to enable it where ww can. We can't just enable it always since
444 # that would prevent this script from building other non-Chrome OS boards
445 # with a different (older) toolchain, or Chrome OS boards without vboot.
446 # So use USE_STDINT if the toolchain supports it, and not if not. This
447 # file was originally part of glibc but has recently migrated to the
448 # compiler so it is reasonable to use it with a stand-alone program like
449 # U-Boot. At this point the comment has got long enough that we may as
450 # well include some poetry which seems to be sorely lacking the code base,
451 # so this is from Ogden Nash:
452 # To keep your marriage brimming
453 # With love in the loving cup,
454 # Whenever you're wrong, admit it;
455 # Whenever you're right, shut up.
456 cmd = [CompilerTool('gcc'), '-ffreestanding', '-x', 'c', '-c', '-']
Mike Frysinger45602c72019-09-22 02:15:11 -0400457 result = cros_build_lib.run(cmd,
458 input='#include <stdint.h>',
459 capture_output=True,
460 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700461 if result.returncode == 0:
462 base.append('USE_STDINT=1')
463
Simon Glassc0a4d0e2016-08-10 08:18:27 -0600464 base.append('BUILD_ROM=1')
Simon Glass02741682013-05-26 07:07:58 -0700465 if options.trace:
466 base.append('FTRACE=1')
467 if options.separate:
468 base.append('DEV_TREE_SEPARATE=1')
469
470 if options.incremental:
471 # Get the correct board for cros_write_firmware
Simon Glassef7e4372016-07-20 09:38:47 -0600472 config_mk = '%s/include/autoconf.mk' % outdir
Simon Glass02741682013-05-26 07:07:58 -0700473 if not os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600474 logging.warning('No build found for %s - dropping -i', board)
Simon Glass02741682013-05-26 07:07:58 -0700475 options.incremental = False
476
Simon Glassef7e4372016-07-20 09:38:47 -0600477 config_mk = 'include/autoconf.mk'
Simon Glass02741682013-05-26 07:07:58 -0700478 if os.path.exists(config_mk):
Lann Martinffb95162018-08-28 12:02:54 -0600479 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
Simon Glass02741682013-05-26 07:07:58 -0700480
481 # For when U-Boot supports ccache
482 # See http://patchwork.ozlabs.org/patch/245079/
483 if use_ccache:
484 os.environ['CCACHE'] = 'ccache'
485
486 return base
487
488
489def RunBuild(options, base, target, queue):
490 """Run the U-Boot build.
491
492 Args:
493 options: Command line options.
494 base: Base U-Boot flags.
495 target: Target to build.
496 queue: A parallel queue to add jobs to.
497 """
498 Log('U-Boot build flags: %s' % ' '.join(base))
499
500 # Reconfigure U-Boot.
501 if not options.incremental:
502 # Ignore any error from this, some older U-Boots fail on this.
Mike Frysinger45602c72019-09-22 02:15:11 -0400503 cros_build_lib.run(base + ['distclean'], **kwargs)
Simon Glass4e28d112016-11-16 13:52:48 -0700504 if os.path.exists('tools/genboardscfg.py'):
505 mtarget = 'defconfig'
506 else:
507 mtarget = 'config'
508 cmd = base + ['%s_%s' % (uboard, mtarget)]
Mike Frysingerc9885932020-02-26 01:02:49 -0500509 result = cros_build_lib.run(cmd, stdout=True, stderr=subprocess.STDOUT,
510 **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700511 if result.returncode:
Mike Frysinger7a580c12022-08-01 21:45:41 -0400512 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout))
Simon Glassc2fe94c2016-11-16 13:56:24 -0700513 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700514
515 # Do the actual build.
516 if options.build:
Mike Frysingerc9885932020-02-26 01:02:49 -0500517 result = cros_build_lib.run(base + [target], stdout=True,
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500518 stderr=subprocess.STDOUT, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700519 if result.returncode:
Simon Glass08b33082017-01-23 12:16:40 -0700520 # The build failed, so output the results to stderr.
Mike Frysinger7a580c12022-08-01 21:45:41 -0400521 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout),
Simon Glass08b33082017-01-23 12:16:40 -0700522 file=sys.stderr)
Simon Glassc2fe94c2016-11-16 13:56:24 -0700523 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700524
525 files = ['%s/u-boot' % outdir]
526 spl = glob.glob('%s/spl/u-boot-spl' % outdir)
527 if spl:
528 files += spl
529 if options.size:
Mike Frysinger45602c72019-09-22 02:15:11 -0400530 result = cros_build_lib.run([CompilerTool('size')] + files, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700531 if result.returncode:
532 sys.exit()
533
534 # Create disassembly files .dis and .Dis (full dump)
535 for f in files:
536 base = os.path.splitext(f)[0]
537 if options.objdump:
538 queue.put(('-d', f, base + '.dis'))
539 queue.put(('-D', f, base + '.Dis'))
540 else:
541 # Remove old files which otherwise might be confusing
542 osutils.SafeUnlink(base + '.dis')
543 osutils.SafeUnlink(base + '.Dis')
544
545 Log('Output directory %s' % outdir)
546
547
548def WriteFirmware(options):
549 """Write firmware to the board.
550
551 This uses cros_bundle_firmware to create a firmware image and write it to
552 the board.
553
554 Args:
555 options: Command line options
556 """
557 flash = []
558 kernel = []
559 run = []
560 secure = []
561 servo = []
562 silent = []
563 verbose_arg = []
Simon Glass46411592013-07-22 22:35:01 -0600564 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700565
566 bl2 = ['--bl2', '%s/spl/%s-spl.bin' % (outdir, smdk)]
567
568 if options.use_defaults:
569 bl1 = []
570 bmpblk = []
571 ecro = []
572 ecrw = []
573 defaults = []
574 else:
575 bl1 = ['--bl1', '##/build/%s/firmware/u-boot.bl1.bin' % options.board]
576 bmpblk = ['--bmpblk', '##/build/%s/firmware/bmpblk.bin' % options.board]
577 ecro = ['--ecro', '##/build/%s/firmware/ec.RO.bin' % options.board]
578 ecrw = ['--ec', '##/build/%s/firmware/ec.RW.bin' % options.board]
579 defaults = ['-D']
580
581 if arch == 'x86':
582 seabios = ['--seabios',
583 '##/build/%s/firmware/seabios.cbfs' % options.board]
584 else:
585 seabios = []
586
587 if options.sdcard:
588 dest = 'sd:.'
589 elif arch == 'x86':
590 dest = 'em100'
591 elif arch == 'sandbox':
592 dest = ''
593 else:
594 dest = 'usb'
595
596 port = SERVO_PORT.get(options.board, '')
597 if port:
598 servo = ['--servo', '%d' % port]
599
600 if options.flash:
601 flash = ['-F', 'spi']
602
Simon Glass46411592013-07-22 22:35:01 -0600603 # The small builds don't have the command line interpreter so cannot
604 # run the magic flasher script. So use the standard U-Boot in this
605 # case.
606 if options.small:
Ralph Nathan446aee92015-03-23 14:44:56 -0700607 logging.warning('Using standard U-Boot as flasher')
Simon Glass46411592013-07-22 22:35:01 -0600608 flash += ['-U', '##/build/%s/firmware/u-boot.bin' % options.board]
609
Michael Prattc88035d2013-07-31 16:27:29 -0700610 if options.mmc:
611 flash = ['-F', 'sdmmc']
612
Simon Glass02741682013-05-26 07:07:58 -0700613 if options.verbose:
614 verbose_arg = ['-v', '%s' % options.verbose]
615
616 if options.secure:
617 secure += ['--bootsecure', '--bootcmd', 'vboot_twostop']
618
619 if not options.verified:
620 # Make a small image, without GBB, etc.
621 secure.append('-s')
622
623 if options.kernel:
Brian Norris8016b992021-09-13 15:00:15 -0700624 kernel = ['--kernel', '##/build/%s/boot/vmlinuz' % options.board]
Simon Glass02741682013-05-26 07:07:58 -0700625
626 if not options.console:
627 silent = ['--add-config-int', 'silent-console', '1']
628
629 if not options.run:
630 run = ['--bootcmd', 'none']
631
632 if arch != 'sandbox' and not in_chroot and servo:
633 if dest == 'usb':
Ralph Nathan446aee92015-03-23 14:44:56 -0700634 logging.warning('Image cannot be written to board')
Simon Glass02741682013-05-26 07:07:58 -0700635 dest = ''
636 servo = []
637 elif dest == 'em100':
Ralph Nathan446aee92015-03-23 14:44:56 -0700638 logging.warning('Please reset the board manually to boot firmware')
Simon Glass02741682013-05-26 07:07:58 -0700639 servo = []
640
641 if not servo:
Ralph Nathan446aee92015-03-23 14:44:56 -0700642 logging.warning('(sadly dut-control does not work outside chroot)')
Simon Glass02741682013-05-26 07:07:58 -0700643
644 if dest:
645 dest = ['-w', dest]
646 else:
647 dest = []
648
649 soc = SOCS.get(board)
650 if not soc:
651 soc = SOCS.get(uboard, '')
652 dt_name = DEFAULT_DTS.get(options.board, options.board)
653 dts_file = 'board/%s/dts/%s%s.dts' % (vendor, soc, dt_name)
654 Log('Device tree: %s' % dts_file)
655
656 if arch == 'sandbox':
657 uboot_fname = '%s/u-boot' % outdir
658 else:
659 uboot_fname = '%s/u-boot.bin' % outdir
660
Simon Glass46411592013-07-22 22:35:01 -0600661 if options.ro:
662 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
663 # ebuild one as RW.
664 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
665 # a fresh RW U-Boot.
Ralph Nathan446aee92015-03-23 14:44:56 -0700666 logging.warning('Using standard U-Boot for RW')
Simon Glass46411592013-07-22 22:35:01 -0600667 ro_uboot = ['--add-blob', 'ro-boot', uboot_fname]
668 uboot_fname = '##/build/%s/firmware/u-boot.bin' % options.board
Simon Glass02741682013-05-26 07:07:58 -0700669 cbf = ['%s/platform/dev/host/cros_bundle_firmware' % src_root,
670 '-b', options.board,
671 '-d', dts_file,
672 '-I', 'arch/%s/dts' % arch, '-I', 'cros/dts',
673 '-u', uboot_fname,
674 '-O', '%s/out' % outdir,
675 '-M', family]
676
677 for other in [bl1, bl2, bmpblk, defaults, dest, ecro, ecrw, flash, kernel,
Simon Glass46411592013-07-22 22:35:01 -0600678 run, seabios, secure, servo, silent, verbose_arg, ro_uboot]:
Simon Glass02741682013-05-26 07:07:58 -0700679 if other:
680 cbf += other
681 if options.cbfargs:
682 for item in options.cbfargs:
683 cbf += item.split(' ')
684 os.environ['PYTHONPATH'] = ('%s/platform/dev/host/lib:%s/..' %
685 (src_root, src_root))
686 Log(' '.join(cbf))
Mike Frysinger45602c72019-09-22 02:15:11 -0400687 result = cros_build_lib.run(cbf, **kwargs)
Simon Glass02741682013-05-26 07:07:58 -0700688 if result.returncode:
689 cros_build_lib.Die('cros_bundle_firmware failed')
690
691 if not dest or not result.returncode:
Lann Martinffb95162018-08-28 12:02:54 -0600692 logging.info('Image is available at %s/out/image.bin', outdir)
Simon Glass02741682013-05-26 07:07:58 -0700693 else:
694 if result.returncode:
695 cros_build_lib.Die('Failed to write image to board')
696 else:
Lann Martinffb95162018-08-28 12:02:54 -0600697 logging.info('Image written to board with %s', ' '.join(dest + servo))
Simon Glass02741682013-05-26 07:07:58 -0700698
699
700def main(argv):
701 """Main function for script to build/write firmware.
702
703 Args:
704 argv: Program arguments.
705 """
Mike Frysinger4e91d822015-06-04 02:01:40 -0400706 options = ParseCmdline(argv)
Simon Glass02741682013-05-26 07:07:58 -0700707 base = SetupBuild(options)
708
709 with parallel.BackgroundTaskRunner(Dumper) as queue:
Mike Frysinger4e91d822015-06-04 02:01:40 -0400710 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700711
712 if options.write:
713 WriteFirmware(options)
714
715 if options.objdump:
716 Log('Writing diasssembly files')