blob: 9b2af29312bbd7c08d8f7f31b894f73b21d0cad2 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2013 The ChromiumOS Authors
Simon Glass02741682013-05-26 07:07:58 -07002# 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
Alex Klein1699fab2022-09-08 08:46:06 -0600123logging.basicConfig(format="%(message)s")
124kwargs = {
125 "print_cmd": False,
126 "check": False,
127 "debug_level": logging.getLogger().getEffectiveLevel(),
128}
Simon Glass02741682013-05-26 07:07:58 -0700129
Alex Klein1699fab2022-09-08 08:46:06 -0600130outdir = ""
Simon Glass02741682013-05-26 07:07:58 -0700131
Alex Klein1699fab2022-09-08 08:46:06 -0600132# If you have multiple boards connected on different servo ports, put lines
Simon Glass02741682013-05-26 07:07:58 -0700133# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
134SERVO_PORT = {}
135
136smdk = None
Alex Klein1699fab2022-09-08 08:46:06 -0600137src_root = os.path.join(constants.SOURCE_ROOT, "src")
Simon Glass02741682013-05-26 07:07:58 -0700138in_chroot = cros_build_lib.IsInsideChroot()
139
Alex Klein1699fab2022-09-08 08:46:06 -0600140uboard = ""
Simon Glass02741682013-05-26 07:07:58 -0700141
Alex Klein1699fab2022-09-08 08:46:06 -0600142default_board = "peach_pit"
Simon Glass02741682013-05-26 07:07:58 -0700143use_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 = {
Alex Klein1699fab2022-09-08 08:46:06 -0600151 "daisy": "smdk5250",
152 "peach": "smdk5420",
Simon Glass02741682013-05-26 07:07:58 -0700153}
Alex Klein1699fab2022-09-08 08:46:06 -0600154for b in [
155 "alex",
156 "butterfly",
157 "emeraldlake2",
158 "link",
159 "lumpy",
160 "parrot",
161 "stout",
162 "stumpy",
163]:
164 UBOARDS[b] = "coreboot-x86"
165 UBOARDS["chromeos_%s" % b] = "chromeos_coreboot"
Simon Glass02741682013-05-26 07:07:58 -0700166
167SOCS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600168 "coreboot-x86": "",
169 "chromeos_coreboot": "",
170 "daisy": "exynos5250-",
171 "peach": "exynos5420-",
Simon Glass02741682013-05-26 07:07:58 -0700172}
173
174DEFAULT_DTS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600175 "daisy": "snow",
176 "daisy_spring": "spring",
177 "peach_pit": "peach-pit",
Simon Glass02741682013-05-26 07:07:58 -0700178}
179
Alex Klein1699fab2022-09-08 08:46:06 -0600180OUT_DIR = "/tmp/crosfw"
Simon Glassb89ae892013-07-18 15:23:35 -0600181
Alex Klein1699fab2022-09-08 08:46:06 -0600182rc_file = os.path.expanduser("~/.crosfwrc")
Simon Glass02741682013-05-26 07:07:58 -0700183if os.path.exists(rc_file):
Alex Klein1699fab2022-09-08 08:46:06 -0600184 with open(rc_file) as fp:
185 # pylint: disable=exec-used
186 exec(compile(fp.read(), rc_file, "exec"))
Simon Glass02741682013-05-26 07:07:58 -0700187
188
189def Log(msg):
Alex Klein1699fab2022-09-08 08:46:06 -0600190 """Print out a message if we are in verbose mode.
Simon Glass02741682013-05-26 07:07:58 -0700191
Alex Klein1699fab2022-09-08 08:46:06 -0600192 Args:
193 msg: Message to print
194 """
195 if verbose:
196 logging.info(msg)
Simon Glass02741682013-05-26 07:07:58 -0700197
198
199def Dumper(flag, infile, outfile):
Alex Klein1699fab2022-09-08 08:46:06 -0600200 """Run objdump on an input file.
Simon Glass02741682013-05-26 07:07:58 -0700201
Alex Klein1699fab2022-09-08 08:46:06 -0600202 Args:
203 flag: Flag to pass objdump (e.g. '-d').
204 infile: Input file to process.
205 outfile: Output file to write to.
206 """
207 result = cros_build_lib.run(
208 [CompilerTool("objdump"), flag, infile], stdout=outfile, **kwargs
209 )
210 if result.returncode:
211 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700212
213
214def CompilerTool(tool):
Alex Klein1699fab2022-09-08 08:46:06 -0600215 """Returns the cross-compiler tool filename.
Simon Glass02741682013-05-26 07:07:58 -0700216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 Args:
218 tool: Tool name to return, e.g. 'size'.
Simon Glass02741682013-05-26 07:07:58 -0700219
Alex Klein1699fab2022-09-08 08:46:06 -0600220 Returns:
221 Filename of requested tool.
222 """
223 return "%s%s" % (compiler, tool)
Simon Glass02741682013-05-26 07:07:58 -0700224
225
226def ParseCmdline(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600227 """Parse all command line options.
Simon Glass02741682013-05-26 07:07:58 -0700228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 Args:
230 argv: Arguments to parse.
Simon Glass02741682013-05-26 07:07:58 -0700231
Alex Klein1699fab2022-09-08 08:46:06 -0600232 Returns:
233 The parsed options object
234 """
235 parser = commandline.ArgumentParser(description=__doc__)
236 parser.add_argument(
237 "-a",
238 "--cbfargs",
239 action="append",
240 help="Pass extra arguments to cros_bundle_firmware",
241 )
242 parser.add_argument(
243 "-b",
244 "--board",
245 type=str,
246 default=default_board,
247 help="Select board to build (daisy/peach_pit/link)",
248 )
249 parser.add_argument(
250 "-B",
251 "--build",
252 action="store_false",
253 default=True,
254 help="Don't build U-Boot, just configure device tree",
255 )
256 parser.add_argument(
257 "-C",
258 "--console",
259 action="store_false",
260 default=True,
261 help="Permit console output",
262 )
263 parser.add_argument(
264 "-d",
265 "--dt",
266 default="seaboard",
267 help="Select name of device tree file to use",
268 )
269 parser.add_argument(
270 "-D",
271 "--nodefaults",
272 dest="use_defaults",
273 action="store_false",
274 default=True,
275 help="Don't select default filenames for those not given",
276 )
277 parser.add_argument(
278 "-F",
279 "--flash",
280 action="store_true",
281 default=False,
282 help="Create magic flasher for SPI flash",
283 )
284 parser.add_argument(
285 "-M",
286 "--mmc",
287 action="store_true",
288 default=False,
289 help="Create magic flasher for eMMC",
290 )
291 parser.add_argument(
292 "-i",
293 "--incremental",
294 action="store_true",
295 default=False,
296 help="Don't reconfigure and clean",
297 )
298 parser.add_argument(
299 "-k",
300 "--kernel",
301 action="store_true",
302 default=False,
303 help="Send kernel to board also",
304 )
305 parser.add_argument(
306 "-O",
307 "--objdump",
308 action="store_true",
309 default=False,
310 help="Write disassembly output",
311 )
312 parser.add_argument(
313 "-r",
314 "--run",
315 action="store_false",
316 default=True,
317 help="Run the boot command",
318 )
319 parser.add_argument(
320 "--ro",
321 action="store_true",
322 default=False,
323 help="Create Chrome OS read-only image",
324 )
325 parser.add_argument(
326 "--rw",
327 action="store_true",
328 default=False,
329 help="Create Chrome OS read-write image",
330 )
331 parser.add_argument(
332 "-s",
333 "--separate",
334 action="store_false",
335 default=True,
336 help="Link device tree into U-Boot, instead of separate",
337 )
338 parser.add_argument(
339 "-S",
340 "--secure",
341 action="store_true",
342 default=False,
343 help="Use vboot_twostop secure boot",
344 )
345 parser.add_argument(
346 "--small",
347 action="store_true",
348 default=False,
349 help="Create Chrome OS small image",
350 )
351 parser.add_argument(
352 "-t",
353 "--trace",
354 action="store_true",
355 default=False,
356 help="Enable trace support",
357 )
358 parser.add_argument(
359 "-V",
360 "--verified",
361 action="store_true",
362 default=False,
363 help="Include Chrome OS verified boot components",
364 )
365 parser.add_argument(
366 "-w",
367 "--write",
368 action="store_false",
369 default=True,
370 help="Don't write image to board using usb/em100",
371 )
372 parser.add_argument(
373 "-x",
374 "--sdcard",
375 action="store_true",
376 default=False,
377 help="Write to SD card instead of USB/em100",
378 )
379 parser.add_argument(
380 "-z",
381 "--size",
382 action="store_true",
383 default=False,
384 help="Display U-Boot image size",
385 )
386 parser.add_argument(
387 "target", nargs="?", default="all", help="The target to work on"
388 )
389 return parser.parse_args(argv)
Simon Glass02741682013-05-26 07:07:58 -0700390
391
Simon Glassc1a323a2016-08-04 20:29:51 -0600392def FindCompiler(gcc, cros_prefix):
Alex Klein1699fab2022-09-08 08:46:06 -0600393 """Look up the compiler for an architecture.
Simon Glassc1a323a2016-08-04 20:29:51 -0600394
Alex Klein1699fab2022-09-08 08:46:06 -0600395 Args:
396 gcc: GCC architecture, either 'arm' or 'aarch64'
397 cros_prefix: Full Chromium OS toolchain prefix
398 """
399 if in_chroot:
400 # Use the Chromium OS toolchain.
401 prefix = cros_prefix
402 else:
403 prefix = glob.glob("/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc" % gcc)
404 if not prefix:
405 cros_build_lib.Die(
406 """Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600407Install a Linaro toolchain from:
408https://launchpad.net/linaro-toolchain-binaries
Alex Klein1699fab2022-09-08 08:46:06 -0600409or see cros/commands/cros_chrome_sdk.py."""
410 % gcc
411 )
412 prefix = re.sub("gcc$", "", prefix[0])
413 return prefix
Simon Glassc1a323a2016-08-04 20:29:51 -0600414
415
Simon Glass02741682013-05-26 07:07:58 -0700416def SetupBuild(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600417 """Set up parameters needed for the build.
Simon Glass02741682013-05-26 07:07:58 -0700418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 This checks the current environment and options and sets up various things
420 needed for the build, including 'base' which holds the base flags for
421 passing to the U-Boot Makefile.
Simon Glass02741682013-05-26 07:07:58 -0700422
Alex Klein1699fab2022-09-08 08:46:06 -0600423 Args:
424 options: Command line options
Simon Glass02741682013-05-26 07:07:58 -0700425
Alex Klein1699fab2022-09-08 08:46:06 -0600426 Returns:
427 Base flags to use for U-Boot, as a list.
428 """
429 # pylint: disable=global-statement
430 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
Simon Glass02741682013-05-26 07:07:58 -0700431
Alex Klein1699fab2022-09-08 08:46:06 -0600432 if not verbose:
433 verbose = options.verbose != 0
Simon Glass02741682013-05-26 07:07:58 -0700434
Alex Klein1699fab2022-09-08 08:46:06 -0600435 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700436
Alex Klein1699fab2022-09-08 08:46:06 -0600437 Log("Building for %s" % options.board)
Simon Glass02741682013-05-26 07:07:58 -0700438
Alex Klein1699fab2022-09-08 08:46:06 -0600439 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
440 # But don't mess up upstream boards which use _ in their name.
441 parts = options.board.split("_")
442 if parts[0] in ["daisy", "peach"]:
443 board = parts[0]
Simon Glass02741682013-05-26 07:07:58 -0700444 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600445 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700446
Alex Klein1699fab2022-09-08 08:46:06 -0600447 # To allow this to be run from 'cros_sdk'
448 if in_chroot:
449 os.chdir(os.path.join(src_root, "third_party", "u-boot", "files"))
Simon Glass02741682013-05-26 07:07:58 -0700450
Alex Klein1699fab2022-09-08 08:46:06 -0600451 base_board = board
Simon Glass02741682013-05-26 07:07:58 -0700452
Alex Klein1699fab2022-09-08 08:46:06 -0600453 if options.verified:
454 base_board = "chromeos_%s" % base_board
Simon Glass02741682013-05-26 07:07:58 -0700455
Alex Klein1699fab2022-09-08 08:46:06 -0600456 uboard = UBOARDS.get(base_board, base_board)
457 Log("U-Boot board is %s" % uboard)
Simon Glass02741682013-05-26 07:07:58 -0700458
Alex Klein1699fab2022-09-08 08:46:06 -0600459 # Pull out some information from the U-Boot boards config file
460 family = None
461 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
462 if os.path.exists("MAINTAINERS"):
463 board_format = PRE_KBUILD
464 else:
465 board_format = PRE_KCONFIG
466 with open("boards.cfg") as f:
467 for line in f:
468 if "genboardscfg" in line:
469 board_format = KCONFIG
470 if uboard in line:
471 if line[0] == "#":
472 continue
473 fields = line.split()
474 if not fields:
475 continue
476 arch = fields[1]
477 fields += [None, None, None]
478 if board_format == PRE_KBUILD:
479 smdk = fields[3]
480 vendor = fields[4]
481 family = fields[5]
482 target = fields[6]
483 elif board_format in (PRE_KCONFIG, KCONFIG):
484 smdk = fields[5]
485 vendor = fields[4]
486 family = fields[3]
487 target = fields[0]
Simon Glass02741682013-05-26 07:07:58 -0700488
Alex Klein1699fab2022-09-08 08:46:06 -0600489 # Make sure this is the right target.
490 if target == uboard:
491 break
492 if not arch:
493 cros_build_lib.Die(
494 "Selected board '%s' not found in boards.cfg." % board
495 )
Simon Glass02741682013-05-26 07:07:58 -0700496
Alex Klein1699fab2022-09-08 08:46:06 -0600497 vboot = os.path.join("build", board, "usr")
498 if arch == "x86":
499 family = "em100"
500 if in_chroot:
501 compiler = "i686-pc-linux-gnu-"
502 else:
503 compiler = "/opt/i686/bin/i686-unknown-elf-"
504 elif arch == "arm":
505 compiler = FindCompiler(arch, "armv7a-cros-linux-gnueabi-")
506 elif arch == "aarch64":
507 compiler = FindCompiler(arch, "aarch64-cros-linux-gnu-")
508 # U-Boot builds both arm and aarch64 with the 'arm' architecture.
509 arch = "arm"
510 elif arch == "sandbox":
511 compiler = ""
512 else:
Alex Kleindf8ee502022-10-18 09:48:15 -0600513 cros_build_lib.Die("Selected arch '%s' not supported.", arch)
Simon Glass02741682013-05-26 07:07:58 -0700514
Alex Klein1699fab2022-09-08 08:46:06 -0600515 if not options.build:
516 options.incremental = True
Simon Glass02741682013-05-26 07:07:58 -0700517
Alex Klein1699fab2022-09-08 08:46:06 -0600518 cpus = multiprocessing.cpu_count()
Simon Glass02741682013-05-26 07:07:58 -0700519
Alex Klein1699fab2022-09-08 08:46:06 -0600520 outdir = os.path.join(OUT_DIR, uboard)
521 base = [
522 "make",
523 "-j%d" % cpus,
524 "O=%s" % outdir,
525 "ARCH=%s" % arch,
526 "CROSS_COMPILE=%s" % compiler,
527 "--no-print-directory",
528 "HOSTSTRIP=true",
529 "DEV_TREE_SRC=%s-%s" % (family, options.dt),
530 "QEMU_ARCH=",
531 ]
Simon Glass02741682013-05-26 07:07:58 -0700532
Alex Klein1699fab2022-09-08 08:46:06 -0600533 if options.verbose < 2:
534 base.append("-s")
535 elif options.verbose > 2:
536 base.append("V=1")
Simon Glass02741682013-05-26 07:07:58 -0700537
Alex Klein1699fab2022-09-08 08:46:06 -0600538 if options.ro and options.rw:
539 cros_build_lib.Die("Cannot specify both --ro and --rw options")
540 if options.ro:
541 base.append("CROS_RO=1")
542 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700543
Alex Klein1699fab2022-09-08 08:46:06 -0600544 if options.rw:
545 base.append("CROS_RW=1")
546 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700547
Alex Klein1699fab2022-09-08 08:46:06 -0600548 if options.small:
549 base.append("CROS_SMALL=1")
550 else:
551 base.append("CROS_FULL=1")
552
553 if options.verified:
554 base += [
555 "VBOOT=%s" % vboot,
556 "MAKEFLAGS_VBOOT=DEBUG=1",
557 "QUIET=1",
558 "CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS",
559 "VBOOT_SOURCE=%s/platform/vboot_reference" % src_root,
560 ]
561 base.append("VBOOT_DEBUG=1")
562
563 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
564 # to a recent change, the need for which I didn't fully understand. But
565 # U-Boot doesn't normally use this. We have added an option to U-Boot to
566 # enable use of <stdint.h> and without it vboot will fail to build. So we
567 # need to enable it where ww can. We can't just enable it always since
568 # that would prevent this script from building other non-Chrome OS boards
569 # with a different (older) toolchain, or Chrome OS boards without vboot.
570 # So use USE_STDINT if the toolchain supports it, and not if not. This
571 # file was originally part of glibc but has recently migrated to the
572 # compiler so it is reasonable to use it with a stand-alone program like
573 # U-Boot. At this point the comment has got long enough that we may as
574 # well include some poetry which seems to be sorely lacking the code base,
575 # so this is from Ogden Nash:
576 # To keep your marriage brimming
577 # With love in the loving cup,
578 # Whenever you're wrong, admit it;
579 # Whenever you're right, shut up.
580 cmd = [CompilerTool("gcc"), "-ffreestanding", "-x", "c", "-c", "-"]
581 result = cros_build_lib.run(
582 cmd, input="#include <stdint.h>", capture_output=True, **kwargs
583 )
584 if result.returncode == 0:
585 base.append("USE_STDINT=1")
586
587 base.append("BUILD_ROM=1")
588 if options.trace:
589 base.append("FTRACE=1")
590 if options.separate:
591 base.append("DEV_TREE_SEPARATE=1")
592
593 if options.incremental:
594 # Get the correct board for cros_write_firmware
595 config_mk = "%s/include/autoconf.mk" % outdir
596 if not os.path.exists(config_mk):
597 logging.warning("No build found for %s - dropping -i", board)
598 options.incremental = False
599
600 config_mk = "include/autoconf.mk"
601 if os.path.exists(config_mk):
602 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
603
604 # For when U-Boot supports ccache
605 # See http://patchwork.ozlabs.org/patch/245079/
606 if use_ccache:
607 os.environ["CCACHE"] = "ccache"
608
609 return base
Simon Glass02741682013-05-26 07:07:58 -0700610
611
612def RunBuild(options, base, target, queue):
Alex Klein1699fab2022-09-08 08:46:06 -0600613 """Run the U-Boot build.
Simon Glass02741682013-05-26 07:07:58 -0700614
Alex Klein1699fab2022-09-08 08:46:06 -0600615 Args:
616 options: Command line options.
617 base: Base U-Boot flags.
618 target: Target to build.
619 queue: A parallel queue to add jobs to.
620 """
621 Log("U-Boot build flags: %s" % " ".join(base))
Simon Glass02741682013-05-26 07:07:58 -0700622
Alex Klein1699fab2022-09-08 08:46:06 -0600623 # Reconfigure U-Boot.
624 if not options.incremental:
625 # Ignore any error from this, some older U-Boots fail on this.
626 cros_build_lib.run(base + ["distclean"], **kwargs)
627 if os.path.exists("tools/genboardscfg.py"):
628 mtarget = "defconfig"
629 else:
630 mtarget = "config"
631 cmd = base + ["%s_%s" % (uboard, mtarget)]
632 result = cros_build_lib.run(
633 cmd, stdout=True, stderr=subprocess.STDOUT, **kwargs
634 )
635 if result.returncode:
636 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout))
637 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700638
Alex Klein1699fab2022-09-08 08:46:06 -0600639 # Do the actual build.
640 if options.build:
641 result = cros_build_lib.run(
642 base + [target], stdout=True, stderr=subprocess.STDOUT, **kwargs
643 )
644 if result.returncode:
645 # The build failed, so output the results to stderr.
646 print(
647 "cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout),
648 file=sys.stderr,
649 )
650 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700651
Alex Klein1699fab2022-09-08 08:46:06 -0600652 files = ["%s/u-boot" % outdir]
653 spl = glob.glob("%s/spl/u-boot-spl" % outdir)
654 if spl:
655 files += spl
656 if options.size:
657 result = cros_build_lib.run([CompilerTool("size")] + files, **kwargs)
658 if result.returncode:
659 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700660
Alex Klein1699fab2022-09-08 08:46:06 -0600661 # Create disassembly files .dis and .Dis (full dump)
662 for f in files:
663 base = os.path.splitext(f)[0]
664 if options.objdump:
665 queue.put(("-d", f, base + ".dis"))
666 queue.put(("-D", f, base + ".Dis"))
667 else:
668 # Remove old files which otherwise might be confusing
669 osutils.SafeUnlink(base + ".dis")
670 osutils.SafeUnlink(base + ".Dis")
Simon Glass02741682013-05-26 07:07:58 -0700671
Alex Klein1699fab2022-09-08 08:46:06 -0600672 Log("Output directory %s" % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700673
674
675def WriteFirmware(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600676 """Write firmware to the board.
Simon Glass02741682013-05-26 07:07:58 -0700677
Alex Klein1699fab2022-09-08 08:46:06 -0600678 This uses cros_bundle_firmware to create a firmware image and write it to
679 the board.
Simon Glass02741682013-05-26 07:07:58 -0700680
Alex Klein1699fab2022-09-08 08:46:06 -0600681 Args:
682 options: Command line options
683 """
684 flash = []
685 kernel = []
686 run = []
687 secure = []
688 servo = []
689 silent = []
690 verbose_arg = []
691 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700692
Alex Klein1699fab2022-09-08 08:46:06 -0600693 bl2 = ["--bl2", "%s/spl/%s-spl.bin" % (outdir, smdk)]
Simon Glass02741682013-05-26 07:07:58 -0700694
Alex Klein1699fab2022-09-08 08:46:06 -0600695 if options.use_defaults:
696 bl1 = []
697 bmpblk = []
698 ecro = []
699 ecrw = []
700 defaults = []
Simon Glass02741682013-05-26 07:07:58 -0700701 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600702 bl1 = ["--bl1", "##/build/%s/firmware/u-boot.bl1.bin" % options.board]
703 bmpblk = ["--bmpblk", "##/build/%s/firmware/bmpblk.bin" % options.board]
704 ecro = ["--ecro", "##/build/%s/firmware/ec.RO.bin" % options.board]
705 ecrw = ["--ec", "##/build/%s/firmware/ec.RW.bin" % options.board]
706 defaults = ["-D"]
707
708 if arch == "x86":
709 seabios = [
710 "--seabios",
711 "##/build/%s/firmware/seabios.cbfs" % options.board,
712 ]
713 else:
714 seabios = []
715
716 if options.sdcard:
717 dest = "sd:."
718 elif arch == "x86":
719 dest = "em100"
720 elif arch == "sandbox":
721 dest = ""
722 else:
723 dest = "usb"
724
725 port = SERVO_PORT.get(options.board, "")
726 if port:
727 servo = ["--servo", "%d" % port]
728
729 if options.flash:
730 flash = ["-F", "spi"]
731
732 # The small builds don't have the command line interpreter so cannot
733 # run the magic flasher script. So use the standard U-Boot in this
734 # case.
735 if options.small:
736 logging.warning("Using standard U-Boot as flasher")
737 flash += ["-U", "##/build/%s/firmware/u-boot.bin" % options.board]
738
739 if options.mmc:
740 flash = ["-F", "sdmmc"]
741
742 if options.verbose:
743 verbose_arg = ["-v", "%s" % options.verbose]
744
745 if options.secure:
746 secure += ["--bootsecure", "--bootcmd", "vboot_twostop"]
747
748 if not options.verified:
749 # Make a small image, without GBB, etc.
750 secure.append("-s")
751
752 if options.kernel:
753 kernel = ["--kernel", "##/build/%s/boot/vmlinuz" % options.board]
754
755 if not options.console:
756 silent = ["--add-config-int", "silent-console", "1"]
757
758 if not options.run:
759 run = ["--bootcmd", "none"]
760
761 if arch != "sandbox" and not in_chroot and servo:
762 if dest == "usb":
763 logging.warning("Image cannot be written to board")
764 dest = ""
765 servo = []
766 elif dest == "em100":
767 logging.warning("Please reset the board manually to boot firmware")
768 servo = []
769
770 if not servo:
771 logging.warning("(sadly dut-control does not work outside chroot)")
772
773 if dest:
774 dest = ["-w", dest]
775 else:
776 dest = []
777
778 soc = SOCS.get(board)
779 if not soc:
780 soc = SOCS.get(uboard, "")
781 dt_name = DEFAULT_DTS.get(options.board, options.board)
782 dts_file = "board/%s/dts/%s%s.dts" % (vendor, soc, dt_name)
783 Log("Device tree: %s" % dts_file)
784
785 if arch == "sandbox":
786 uboot_fname = "%s/u-boot" % outdir
787 else:
788 uboot_fname = "%s/u-boot.bin" % outdir
789
790 if options.ro:
791 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
792 # ebuild one as RW.
793 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
794 # a fresh RW U-Boot.
795 logging.warning("Using standard U-Boot for RW")
796 ro_uboot = ["--add-blob", "ro-boot", uboot_fname]
797 uboot_fname = "##/build/%s/firmware/u-boot.bin" % options.board
798 cbf = [
799 "%s/platform/dev/host/cros_bundle_firmware" % src_root,
800 "-b",
801 options.board,
802 "-d",
803 dts_file,
804 "-I",
805 "arch/%s/dts" % arch,
806 "-I",
807 "cros/dts",
808 "-u",
809 uboot_fname,
810 "-O",
811 "%s/out" % outdir,
812 "-M",
813 family,
814 ]
815
816 for other in [
817 bl1,
818 bl2,
819 bmpblk,
820 defaults,
821 dest,
822 ecro,
823 ecrw,
824 flash,
825 kernel,
826 run,
827 seabios,
828 secure,
829 servo,
830 silent,
831 verbose_arg,
832 ro_uboot,
833 ]:
834 if other:
835 cbf += other
836 if options.cbfargs:
837 for item in options.cbfargs:
838 cbf += item.split(" ")
839 os.environ["PYTHONPATH"] = "%s/platform/dev/host/lib:%s/.." % (
840 src_root,
841 src_root,
842 )
843 Log(" ".join(cbf))
844 result = cros_build_lib.run(cbf, **kwargs)
845 if result.returncode:
846 cros_build_lib.Die("cros_bundle_firmware failed")
847
848 if not dest or not result.returncode:
849 logging.info("Image is available at %s/out/image.bin", outdir)
850 else:
851 if result.returncode:
852 cros_build_lib.Die("Failed to write image to board")
853 else:
854 logging.info(
855 "Image written to board with %s", " ".join(dest + servo)
856 )
Simon Glass02741682013-05-26 07:07:58 -0700857
858
859def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600860 """Main function for script to build/write firmware.
Simon Glass02741682013-05-26 07:07:58 -0700861
Alex Klein1699fab2022-09-08 08:46:06 -0600862 Args:
863 argv: Program arguments.
864 """
865 options = ParseCmdline(argv)
866 base = SetupBuild(options)
Simon Glass02741682013-05-26 07:07:58 -0700867
Alex Klein1699fab2022-09-08 08:46:06 -0600868 with parallel.BackgroundTaskRunner(Dumper) as queue:
869 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700870
Alex Klein1699fab2022-09-08 08:46:06 -0600871 if options.write:
872 WriteFirmware(options)
Simon Glass02741682013-05-26 07:07:58 -0700873
Alex Klein1699fab2022-09-08 08:46:06 -0600874 if options.objdump:
875 Log("Writing diasssembly files")