blob: 5b52e7c1d5c0a97aee397b8e1fb0871fb6c0a8f4 [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
Simon Glassa44a1f92023-02-09 16:31:34 -0700476 target = fields[6]
477 # Make sure this is the right target.
478 if target != uboard:
479 continue
Alex Klein1699fab2022-09-08 08:46:06 -0600480 arch = fields[1]
481 fields += [None, None, None]
482 if board_format == PRE_KBUILD:
483 smdk = fields[3]
484 vendor = fields[4]
485 family = fields[5]
Alex Klein1699fab2022-09-08 08:46:06 -0600486 elif board_format in (PRE_KCONFIG, KCONFIG):
487 smdk = fields[5]
488 vendor = fields[4]
489 family = fields[3]
490 target = fields[0]
Alex Klein1699fab2022-09-08 08:46:06 -0600491 if not arch:
492 cros_build_lib.Die(
493 "Selected board '%s' not found in boards.cfg." % board
494 )
Simon Glass02741682013-05-26 07:07:58 -0700495
Alex Klein1699fab2022-09-08 08:46:06 -0600496 vboot = os.path.join("build", board, "usr")
Simon Glassa44a1f92023-02-09 16:31:34 -0700497 if in_chroot:
498 if arch == "x86":
499 compiler = "i686-cros-linux-gnu-"
500 elif arch == "arm":
501 compiler = FindCompiler(arch, "armv7a-cros-linux-gnueabihf-")
502 elif arch == "aarch64":
503 compiler = FindCompiler(arch, "aarch64-cros-linux-gnu-")
Alex Klein1699fab2022-09-08 08:46:06 -0600504 elif arch == "sandbox":
505 compiler = ""
506 else:
Simon Glassa44a1f92023-02-09 16:31:34 -0700507 result = cros_build_lib.run(
508 ["buildman", "-A", "--boards", options.board],
509 capture_output=True,
510 encoding="utf-8",
511 **kwargs,
512 )
513 compiler = result.stdout.strip()
514 if not compiler:
515 cros_build_lib.Die("Selected arch '%s' not supported.", arch)
Simon Glass02741682013-05-26 07:07:58 -0700516
Alex Klein1699fab2022-09-08 08:46:06 -0600517 if not options.build:
518 options.incremental = True
Simon Glass02741682013-05-26 07:07:58 -0700519
Alex Klein1699fab2022-09-08 08:46:06 -0600520 cpus = multiprocessing.cpu_count()
Simon Glass02741682013-05-26 07:07:58 -0700521
Alex Klein1699fab2022-09-08 08:46:06 -0600522 outdir = os.path.join(OUT_DIR, uboard)
523 base = [
524 "make",
525 "-j%d" % cpus,
526 "O=%s" % outdir,
527 "ARCH=%s" % arch,
528 "CROSS_COMPILE=%s" % compiler,
529 "--no-print-directory",
530 "HOSTSTRIP=true",
531 "DEV_TREE_SRC=%s-%s" % (family, options.dt),
532 "QEMU_ARCH=",
533 ]
Simon Glass02741682013-05-26 07:07:58 -0700534
Alex Klein1699fab2022-09-08 08:46:06 -0600535 if options.verbose < 2:
536 base.append("-s")
537 elif options.verbose > 2:
538 base.append("V=1")
Simon Glass02741682013-05-26 07:07:58 -0700539
Alex Klein1699fab2022-09-08 08:46:06 -0600540 if options.ro and options.rw:
541 cros_build_lib.Die("Cannot specify both --ro and --rw options")
542 if options.ro:
543 base.append("CROS_RO=1")
544 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700545
Alex Klein1699fab2022-09-08 08:46:06 -0600546 if options.rw:
547 base.append("CROS_RW=1")
548 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700549
Alex Klein1699fab2022-09-08 08:46:06 -0600550 if options.small:
551 base.append("CROS_SMALL=1")
552 else:
553 base.append("CROS_FULL=1")
554
555 if options.verified:
556 base += [
557 "VBOOT=%s" % vboot,
558 "MAKEFLAGS_VBOOT=DEBUG=1",
559 "QUIET=1",
560 "CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS",
561 "VBOOT_SOURCE=%s/platform/vboot_reference" % src_root,
562 ]
563 base.append("VBOOT_DEBUG=1")
564
565 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
566 # to a recent change, the need for which I didn't fully understand. But
567 # U-Boot doesn't normally use this. We have added an option to U-Boot to
568 # enable use of <stdint.h> and without it vboot will fail to build. So we
569 # need to enable it where ww can. We can't just enable it always since
570 # that would prevent this script from building other non-Chrome OS boards
571 # with a different (older) toolchain, or Chrome OS boards without vboot.
572 # So use USE_STDINT if the toolchain supports it, and not if not. This
573 # file was originally part of glibc but has recently migrated to the
574 # compiler so it is reasonable to use it with a stand-alone program like
575 # U-Boot. At this point the comment has got long enough that we may as
576 # well include some poetry which seems to be sorely lacking the code base,
577 # so this is from Ogden Nash:
578 # To keep your marriage brimming
579 # With love in the loving cup,
580 # Whenever you're wrong, admit it;
581 # Whenever you're right, shut up.
582 cmd = [CompilerTool("gcc"), "-ffreestanding", "-x", "c", "-c", "-"]
583 result = cros_build_lib.run(
584 cmd, input="#include <stdint.h>", capture_output=True, **kwargs
585 )
586 if result.returncode == 0:
587 base.append("USE_STDINT=1")
588
589 base.append("BUILD_ROM=1")
590 if options.trace:
591 base.append("FTRACE=1")
592 if options.separate:
593 base.append("DEV_TREE_SEPARATE=1")
594
595 if options.incremental:
596 # Get the correct board for cros_write_firmware
597 config_mk = "%s/include/autoconf.mk" % outdir
598 if not os.path.exists(config_mk):
599 logging.warning("No build found for %s - dropping -i", board)
600 options.incremental = False
601
602 config_mk = "include/autoconf.mk"
603 if os.path.exists(config_mk):
604 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
605
606 # For when U-Boot supports ccache
607 # See http://patchwork.ozlabs.org/patch/245079/
608 if use_ccache:
609 os.environ["CCACHE"] = "ccache"
610
611 return base
Simon Glass02741682013-05-26 07:07:58 -0700612
613
614def RunBuild(options, base, target, queue):
Alex Klein1699fab2022-09-08 08:46:06 -0600615 """Run the U-Boot build.
Simon Glass02741682013-05-26 07:07:58 -0700616
Alex Klein1699fab2022-09-08 08:46:06 -0600617 Args:
618 options: Command line options.
619 base: Base U-Boot flags.
620 target: Target to build.
621 queue: A parallel queue to add jobs to.
622 """
623 Log("U-Boot build flags: %s" % " ".join(base))
Simon Glass02741682013-05-26 07:07:58 -0700624
Alex Klein1699fab2022-09-08 08:46:06 -0600625 # Reconfigure U-Boot.
626 if not options.incremental:
627 # Ignore any error from this, some older U-Boots fail on this.
628 cros_build_lib.run(base + ["distclean"], **kwargs)
629 if os.path.exists("tools/genboardscfg.py"):
630 mtarget = "defconfig"
631 else:
632 mtarget = "config"
633 cmd = base + ["%s_%s" % (uboard, mtarget)]
634 result = cros_build_lib.run(
635 cmd, stdout=True, stderr=subprocess.STDOUT, **kwargs
636 )
637 if result.returncode:
638 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout))
639 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700640
Alex Klein1699fab2022-09-08 08:46:06 -0600641 # Do the actual build.
642 if options.build:
643 result = cros_build_lib.run(
644 base + [target], stdout=True, stderr=subprocess.STDOUT, **kwargs
645 )
646 if result.returncode:
647 # The build failed, so output the results to stderr.
648 print(
649 "cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout),
650 file=sys.stderr,
651 )
652 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700653
Alex Klein1699fab2022-09-08 08:46:06 -0600654 files = ["%s/u-boot" % outdir]
655 spl = glob.glob("%s/spl/u-boot-spl" % outdir)
656 if spl:
657 files += spl
658 if options.size:
659 result = cros_build_lib.run([CompilerTool("size")] + files, **kwargs)
660 if result.returncode:
661 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700662
Alex Klein1699fab2022-09-08 08:46:06 -0600663 # Create disassembly files .dis and .Dis (full dump)
664 for f in files:
665 base = os.path.splitext(f)[0]
666 if options.objdump:
667 queue.put(("-d", f, base + ".dis"))
668 queue.put(("-D", f, base + ".Dis"))
669 else:
670 # Remove old files which otherwise might be confusing
671 osutils.SafeUnlink(base + ".dis")
672 osutils.SafeUnlink(base + ".Dis")
Simon Glass02741682013-05-26 07:07:58 -0700673
Alex Klein1699fab2022-09-08 08:46:06 -0600674 Log("Output directory %s" % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700675
676
677def WriteFirmware(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600678 """Write firmware to the board.
Simon Glass02741682013-05-26 07:07:58 -0700679
Alex Klein1699fab2022-09-08 08:46:06 -0600680 This uses cros_bundle_firmware to create a firmware image and write it to
681 the board.
Simon Glass02741682013-05-26 07:07:58 -0700682
Alex Klein1699fab2022-09-08 08:46:06 -0600683 Args:
684 options: Command line options
685 """
686 flash = []
687 kernel = []
688 run = []
689 secure = []
690 servo = []
691 silent = []
692 verbose_arg = []
693 ro_uboot = []
Simon Glass02741682013-05-26 07:07:58 -0700694
Alex Klein1699fab2022-09-08 08:46:06 -0600695 bl2 = ["--bl2", "%s/spl/%s-spl.bin" % (outdir, smdk)]
Simon Glass02741682013-05-26 07:07:58 -0700696
Alex Klein1699fab2022-09-08 08:46:06 -0600697 if options.use_defaults:
698 bl1 = []
699 bmpblk = []
700 ecro = []
701 ecrw = []
702 defaults = []
Simon Glass02741682013-05-26 07:07:58 -0700703 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600704 bl1 = ["--bl1", "##/build/%s/firmware/u-boot.bl1.bin" % options.board]
705 bmpblk = ["--bmpblk", "##/build/%s/firmware/bmpblk.bin" % options.board]
706 ecro = ["--ecro", "##/build/%s/firmware/ec.RO.bin" % options.board]
707 ecrw = ["--ec", "##/build/%s/firmware/ec.RW.bin" % options.board]
708 defaults = ["-D"]
709
710 if arch == "x86":
711 seabios = [
712 "--seabios",
713 "##/build/%s/firmware/seabios.cbfs" % options.board,
714 ]
715 else:
716 seabios = []
717
718 if options.sdcard:
719 dest = "sd:."
720 elif arch == "x86":
721 dest = "em100"
722 elif arch == "sandbox":
723 dest = ""
724 else:
725 dest = "usb"
726
727 port = SERVO_PORT.get(options.board, "")
728 if port:
729 servo = ["--servo", "%d" % port]
730
731 if options.flash:
732 flash = ["-F", "spi"]
733
734 # The small builds don't have the command line interpreter so cannot
735 # run the magic flasher script. So use the standard U-Boot in this
736 # case.
737 if options.small:
738 logging.warning("Using standard U-Boot as flasher")
739 flash += ["-U", "##/build/%s/firmware/u-boot.bin" % options.board]
740
741 if options.mmc:
742 flash = ["-F", "sdmmc"]
743
744 if options.verbose:
745 verbose_arg = ["-v", "%s" % options.verbose]
746
747 if options.secure:
748 secure += ["--bootsecure", "--bootcmd", "vboot_twostop"]
749
750 if not options.verified:
751 # Make a small image, without GBB, etc.
752 secure.append("-s")
753
754 if options.kernel:
755 kernel = ["--kernel", "##/build/%s/boot/vmlinuz" % options.board]
756
757 if not options.console:
758 silent = ["--add-config-int", "silent-console", "1"]
759
760 if not options.run:
761 run = ["--bootcmd", "none"]
762
763 if arch != "sandbox" and not in_chroot and servo:
764 if dest == "usb":
765 logging.warning("Image cannot be written to board")
766 dest = ""
767 servo = []
768 elif dest == "em100":
769 logging.warning("Please reset the board manually to boot firmware")
770 servo = []
771
772 if not servo:
773 logging.warning("(sadly dut-control does not work outside chroot)")
774
775 if dest:
776 dest = ["-w", dest]
777 else:
778 dest = []
779
780 soc = SOCS.get(board)
781 if not soc:
782 soc = SOCS.get(uboard, "")
783 dt_name = DEFAULT_DTS.get(options.board, options.board)
784 dts_file = "board/%s/dts/%s%s.dts" % (vendor, soc, dt_name)
785 Log("Device tree: %s" % dts_file)
786
787 if arch == "sandbox":
788 uboot_fname = "%s/u-boot" % outdir
789 else:
790 uboot_fname = "%s/u-boot.bin" % outdir
791
792 if options.ro:
793 # RO U-Boot is passed through as blob 'ro-boot'. We use the standard
794 # ebuild one as RW.
795 # TODO(sjg@chromium.org): Option to build U-Boot a second time to get
796 # a fresh RW U-Boot.
797 logging.warning("Using standard U-Boot for RW")
798 ro_uboot = ["--add-blob", "ro-boot", uboot_fname]
799 uboot_fname = "##/build/%s/firmware/u-boot.bin" % options.board
800 cbf = [
801 "%s/platform/dev/host/cros_bundle_firmware" % src_root,
802 "-b",
803 options.board,
804 "-d",
805 dts_file,
806 "-I",
807 "arch/%s/dts" % arch,
808 "-I",
809 "cros/dts",
810 "-u",
811 uboot_fname,
812 "-O",
813 "%s/out" % outdir,
814 "-M",
815 family,
816 ]
817
818 for other in [
819 bl1,
820 bl2,
821 bmpblk,
822 defaults,
823 dest,
824 ecro,
825 ecrw,
826 flash,
827 kernel,
828 run,
829 seabios,
830 secure,
831 servo,
832 silent,
833 verbose_arg,
834 ro_uboot,
835 ]:
836 if other:
837 cbf += other
838 if options.cbfargs:
839 for item in options.cbfargs:
840 cbf += item.split(" ")
841 os.environ["PYTHONPATH"] = "%s/platform/dev/host/lib:%s/.." % (
842 src_root,
843 src_root,
844 )
845 Log(" ".join(cbf))
846 result = cros_build_lib.run(cbf, **kwargs)
847 if result.returncode:
848 cros_build_lib.Die("cros_bundle_firmware failed")
849
850 if not dest or not result.returncode:
851 logging.info("Image is available at %s/out/image.bin", outdir)
852 else:
853 if result.returncode:
854 cros_build_lib.Die("Failed to write image to board")
855 else:
856 logging.info(
857 "Image written to board with %s", " ".join(dest + servo)
858 )
Simon Glass02741682013-05-26 07:07:58 -0700859
860
861def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600862 """Main function for script to build/write firmware.
Simon Glass02741682013-05-26 07:07:58 -0700863
Alex Klein1699fab2022-09-08 08:46:06 -0600864 Args:
865 argv: Program arguments.
866 """
867 options = ParseCmdline(argv)
868 base = SetupBuild(options)
Simon Glass02741682013-05-26 07:07:58 -0700869
Alex Klein1699fab2022-09-08 08:46:06 -0600870 with parallel.BackgroundTaskRunner(Dumper) as queue:
871 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700872
Alex Klein1699fab2022-09-08 08:46:06 -0600873 if options.write:
874 WriteFirmware(options)
Simon Glass02741682013-05-26 07:07:58 -0700875
Alex Klein1699fab2022-09-08 08:46:06 -0600876 if options.objdump:
877 Log("Writing diasssembly files")