blob: 7638d4271769eb8aeb46d2471488d85d650fcf5e [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(
Alex Klein1699fab2022-09-08 08:46:06 -0600237 "-b",
238 "--board",
239 type=str,
240 default=default_board,
241 help="Select board to build (daisy/peach_pit/link)",
242 )
243 parser.add_argument(
244 "-B",
245 "--build",
246 action="store_false",
247 default=True,
248 help="Don't build U-Boot, just configure device tree",
249 )
250 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600251 "-d",
252 "--dt",
253 default="seaboard",
254 help="Select name of device tree file to use",
255 )
256 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600257 "-i",
258 "--incremental",
259 action="store_true",
260 default=False,
261 help="Don't reconfigure and clean",
262 )
263 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600264 "-O",
265 "--objdump",
266 action="store_true",
267 default=False,
268 help="Write disassembly output",
269 )
270 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600271 "--ro",
272 action="store_true",
273 default=False,
274 help="Create Chrome OS read-only image",
275 )
276 parser.add_argument(
277 "--rw",
278 action="store_true",
279 default=False,
280 help="Create Chrome OS read-write image",
281 )
282 parser.add_argument(
283 "-s",
284 "--separate",
285 action="store_false",
286 default=True,
287 help="Link device tree into U-Boot, instead of separate",
288 )
289 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600290 "--small",
291 action="store_true",
292 default=False,
293 help="Create Chrome OS small image",
294 )
295 parser.add_argument(
296 "-t",
297 "--trace",
298 action="store_true",
299 default=False,
300 help="Enable trace support",
301 )
302 parser.add_argument(
303 "-V",
304 "--verified",
305 action="store_true",
306 default=False,
307 help="Include Chrome OS verified boot components",
308 )
309 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600310 "-z",
311 "--size",
312 action="store_true",
313 default=False,
314 help="Display U-Boot image size",
315 )
316 parser.add_argument(
317 "target", nargs="?", default="all", help="The target to work on"
318 )
319 return parser.parse_args(argv)
Simon Glass02741682013-05-26 07:07:58 -0700320
321
Simon Glassc1a323a2016-08-04 20:29:51 -0600322def FindCompiler(gcc, cros_prefix):
Alex Klein1699fab2022-09-08 08:46:06 -0600323 """Look up the compiler for an architecture.
Simon Glassc1a323a2016-08-04 20:29:51 -0600324
Alex Klein1699fab2022-09-08 08:46:06 -0600325 Args:
326 gcc: GCC architecture, either 'arm' or 'aarch64'
327 cros_prefix: Full Chromium OS toolchain prefix
328 """
329 if in_chroot:
330 # Use the Chromium OS toolchain.
331 prefix = cros_prefix
332 else:
333 prefix = glob.glob("/opt/linaro/gcc-linaro-%s-linux-*/bin/*gcc" % gcc)
334 if not prefix:
335 cros_build_lib.Die(
336 """Please install an %s toolchain for your machine.
Simon Glassc1a323a2016-08-04 20:29:51 -0600337Install a Linaro toolchain from:
338https://launchpad.net/linaro-toolchain-binaries
Alex Klein1699fab2022-09-08 08:46:06 -0600339or see cros/commands/cros_chrome_sdk.py."""
340 % gcc
341 )
342 prefix = re.sub("gcc$", "", prefix[0])
343 return prefix
Simon Glassc1a323a2016-08-04 20:29:51 -0600344
345
Simon Glass02741682013-05-26 07:07:58 -0700346def SetupBuild(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600347 """Set up parameters needed for the build.
Simon Glass02741682013-05-26 07:07:58 -0700348
Alex Klein1699fab2022-09-08 08:46:06 -0600349 This checks the current environment and options and sets up various things
350 needed for the build, including 'base' which holds the base flags for
351 passing to the U-Boot Makefile.
Simon Glass02741682013-05-26 07:07:58 -0700352
Alex Klein1699fab2022-09-08 08:46:06 -0600353 Args:
354 options: Command line options
Simon Glass02741682013-05-26 07:07:58 -0700355
Alex Klein1699fab2022-09-08 08:46:06 -0600356 Returns:
357 Base flags to use for U-Boot, as a list.
358 """
359 # pylint: disable=global-statement
360 global arch, board, compiler, family, outdir, smdk, uboard, vendor, verbose
Simon Glass02741682013-05-26 07:07:58 -0700361
Alex Klein1699fab2022-09-08 08:46:06 -0600362 if not verbose:
363 verbose = options.verbose != 0
Simon Glass02741682013-05-26 07:07:58 -0700364
Alex Klein1699fab2022-09-08 08:46:06 -0600365 logging.getLogger().setLevel(options.verbose)
Simon Glass02741682013-05-26 07:07:58 -0700366
Alex Klein1699fab2022-09-08 08:46:06 -0600367 Log("Building for %s" % options.board)
Simon Glass02741682013-05-26 07:07:58 -0700368
Alex Klein1699fab2022-09-08 08:46:06 -0600369 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
370 # But don't mess up upstream boards which use _ in their name.
371 parts = options.board.split("_")
372 if parts[0] in ["daisy", "peach"]:
373 board = parts[0]
Simon Glass02741682013-05-26 07:07:58 -0700374 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600375 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700376
Alex Klein1699fab2022-09-08 08:46:06 -0600377 # To allow this to be run from 'cros_sdk'
378 if in_chroot:
379 os.chdir(os.path.join(src_root, "third_party", "u-boot", "files"))
Simon Glass02741682013-05-26 07:07:58 -0700380
Alex Klein1699fab2022-09-08 08:46:06 -0600381 base_board = board
Simon Glass02741682013-05-26 07:07:58 -0700382
Alex Klein1699fab2022-09-08 08:46:06 -0600383 if options.verified:
384 base_board = "chromeos_%s" % base_board
Simon Glass02741682013-05-26 07:07:58 -0700385
Alex Klein1699fab2022-09-08 08:46:06 -0600386 uboard = UBOARDS.get(base_board, base_board)
387 Log("U-Boot board is %s" % uboard)
Simon Glass02741682013-05-26 07:07:58 -0700388
Alex Klein1699fab2022-09-08 08:46:06 -0600389 # Pull out some information from the U-Boot boards config file
390 family = None
391 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
392 if os.path.exists("MAINTAINERS"):
393 board_format = PRE_KBUILD
394 else:
395 board_format = PRE_KCONFIG
396 with open("boards.cfg") as f:
397 for line in f:
398 if "genboardscfg" in line:
399 board_format = KCONFIG
400 if uboard in line:
401 if line[0] == "#":
402 continue
403 fields = line.split()
404 if not fields:
405 continue
Simon Glassa44a1f92023-02-09 16:31:34 -0700406 target = fields[6]
407 # Make sure this is the right target.
408 if target != uboard:
409 continue
Alex Klein1699fab2022-09-08 08:46:06 -0600410 arch = fields[1]
411 fields += [None, None, None]
412 if board_format == PRE_KBUILD:
413 smdk = fields[3]
414 vendor = fields[4]
415 family = fields[5]
Alex Klein1699fab2022-09-08 08:46:06 -0600416 elif board_format in (PRE_KCONFIG, KCONFIG):
417 smdk = fields[5]
418 vendor = fields[4]
419 family = fields[3]
420 target = fields[0]
Alex Klein1699fab2022-09-08 08:46:06 -0600421 if not arch:
422 cros_build_lib.Die(
423 "Selected board '%s' not found in boards.cfg." % board
424 )
Simon Glass02741682013-05-26 07:07:58 -0700425
Alex Klein1699fab2022-09-08 08:46:06 -0600426 vboot = os.path.join("build", board, "usr")
Simon Glassa44a1f92023-02-09 16:31:34 -0700427 if in_chroot:
428 if arch == "x86":
429 compiler = "i686-cros-linux-gnu-"
430 elif arch == "arm":
431 compiler = FindCompiler(arch, "armv7a-cros-linux-gnueabihf-")
432 elif arch == "aarch64":
433 compiler = FindCompiler(arch, "aarch64-cros-linux-gnu-")
Alex Klein1699fab2022-09-08 08:46:06 -0600434 elif arch == "sandbox":
435 compiler = ""
436 else:
Simon Glassa44a1f92023-02-09 16:31:34 -0700437 result = cros_build_lib.run(
438 ["buildman", "-A", "--boards", options.board],
439 capture_output=True,
440 encoding="utf-8",
441 **kwargs,
442 )
443 compiler = result.stdout.strip()
444 if not compiler:
445 cros_build_lib.Die("Selected arch '%s' not supported.", arch)
Simon Glass02741682013-05-26 07:07:58 -0700446
Alex Klein1699fab2022-09-08 08:46:06 -0600447 if not options.build:
448 options.incremental = True
Simon Glass02741682013-05-26 07:07:58 -0700449
Alex Klein1699fab2022-09-08 08:46:06 -0600450 cpus = multiprocessing.cpu_count()
Simon Glass02741682013-05-26 07:07:58 -0700451
Alex Klein1699fab2022-09-08 08:46:06 -0600452 outdir = os.path.join(OUT_DIR, uboard)
453 base = [
454 "make",
455 "-j%d" % cpus,
456 "O=%s" % outdir,
457 "ARCH=%s" % arch,
458 "CROSS_COMPILE=%s" % compiler,
459 "--no-print-directory",
460 "HOSTSTRIP=true",
461 "DEV_TREE_SRC=%s-%s" % (family, options.dt),
462 "QEMU_ARCH=",
463 ]
Simon Glass02741682013-05-26 07:07:58 -0700464
Alex Klein1699fab2022-09-08 08:46:06 -0600465 if options.verbose < 2:
466 base.append("-s")
467 elif options.verbose > 2:
468 base.append("V=1")
Simon Glass02741682013-05-26 07:07:58 -0700469
Alex Klein1699fab2022-09-08 08:46:06 -0600470 if options.ro and options.rw:
471 cros_build_lib.Die("Cannot specify both --ro and --rw options")
472 if options.ro:
473 base.append("CROS_RO=1")
474 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700475
Alex Klein1699fab2022-09-08 08:46:06 -0600476 if options.rw:
477 base.append("CROS_RW=1")
478 options.small = True
Simon Glass02741682013-05-26 07:07:58 -0700479
Alex Klein1699fab2022-09-08 08:46:06 -0600480 if options.small:
481 base.append("CROS_SMALL=1")
482 else:
483 base.append("CROS_FULL=1")
484
485 if options.verified:
486 base += [
487 "VBOOT=%s" % vboot,
488 "MAKEFLAGS_VBOOT=DEBUG=1",
489 "QUIET=1",
490 "CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS",
491 "VBOOT_SOURCE=%s/platform/vboot_reference" % src_root,
492 ]
493 base.append("VBOOT_DEBUG=1")
494
495 # Handle the Chrome OS USE_STDINT workaround. Vboot needs <stdint.h> due
496 # to a recent change, the need for which I didn't fully understand. But
497 # U-Boot doesn't normally use this. We have added an option to U-Boot to
498 # enable use of <stdint.h> and without it vboot will fail to build. So we
499 # need to enable it where ww can. We can't just enable it always since
500 # that would prevent this script from building other non-Chrome OS boards
501 # with a different (older) toolchain, or Chrome OS boards without vboot.
502 # So use USE_STDINT if the toolchain supports it, and not if not. This
503 # file was originally part of glibc but has recently migrated to the
504 # compiler so it is reasonable to use it with a stand-alone program like
505 # U-Boot. At this point the comment has got long enough that we may as
506 # well include some poetry which seems to be sorely lacking the code base,
507 # so this is from Ogden Nash:
508 # To keep your marriage brimming
509 # With love in the loving cup,
510 # Whenever you're wrong, admit it;
511 # Whenever you're right, shut up.
512 cmd = [CompilerTool("gcc"), "-ffreestanding", "-x", "c", "-c", "-"]
513 result = cros_build_lib.run(
514 cmd, input="#include <stdint.h>", capture_output=True, **kwargs
515 )
516 if result.returncode == 0:
517 base.append("USE_STDINT=1")
518
519 base.append("BUILD_ROM=1")
520 if options.trace:
521 base.append("FTRACE=1")
522 if options.separate:
523 base.append("DEV_TREE_SEPARATE=1")
524
525 if options.incremental:
Alex Klein1699fab2022-09-08 08:46:06 -0600526 config_mk = "%s/include/autoconf.mk" % outdir
527 if not os.path.exists(config_mk):
528 logging.warning("No build found for %s - dropping -i", board)
529 options.incremental = False
530
531 config_mk = "include/autoconf.mk"
532 if os.path.exists(config_mk):
533 logging.warning("Warning: '%s' exists, try 'make distclean'", config_mk)
534
535 # For when U-Boot supports ccache
536 # See http://patchwork.ozlabs.org/patch/245079/
537 if use_ccache:
538 os.environ["CCACHE"] = "ccache"
539
540 return base
Simon Glass02741682013-05-26 07:07:58 -0700541
542
543def RunBuild(options, base, target, queue):
Alex Klein1699fab2022-09-08 08:46:06 -0600544 """Run the U-Boot build.
Simon Glass02741682013-05-26 07:07:58 -0700545
Alex Klein1699fab2022-09-08 08:46:06 -0600546 Args:
547 options: Command line options.
548 base: Base U-Boot flags.
549 target: Target to build.
550 queue: A parallel queue to add jobs to.
551 """
552 Log("U-Boot build flags: %s" % " ".join(base))
Simon Glass02741682013-05-26 07:07:58 -0700553
Alex Klein1699fab2022-09-08 08:46:06 -0600554 # Reconfigure U-Boot.
555 if not options.incremental:
556 # Ignore any error from this, some older U-Boots fail on this.
557 cros_build_lib.run(base + ["distclean"], **kwargs)
558 if os.path.exists("tools/genboardscfg.py"):
559 mtarget = "defconfig"
560 else:
561 mtarget = "config"
562 cmd = base + ["%s_%s" % (uboard, mtarget)]
563 result = cros_build_lib.run(
564 cmd, stdout=True, stderr=subprocess.STDOUT, **kwargs
565 )
566 if result.returncode:
567 print("cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout))
568 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700569
Alex Klein1699fab2022-09-08 08:46:06 -0600570 # Do the actual build.
571 if options.build:
572 result = cros_build_lib.run(
573 base + [target], stdout=True, stderr=subprocess.STDOUT, **kwargs
574 )
575 if result.returncode:
576 # The build failed, so output the results to stderr.
577 print(
578 "cmd: '%s', output: '%s'" % (result.cmdstr, result.stdout),
579 file=sys.stderr,
580 )
581 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700582
Alex Klein1699fab2022-09-08 08:46:06 -0600583 files = ["%s/u-boot" % outdir]
584 spl = glob.glob("%s/spl/u-boot-spl" % outdir)
585 if spl:
586 files += spl
587 if options.size:
588 result = cros_build_lib.run([CompilerTool("size")] + files, **kwargs)
589 if result.returncode:
590 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700591
Alex Klein1699fab2022-09-08 08:46:06 -0600592 # Create disassembly files .dis and .Dis (full dump)
593 for f in files:
594 base = os.path.splitext(f)[0]
595 if options.objdump:
596 queue.put(("-d", f, base + ".dis"))
597 queue.put(("-D", f, base + ".Dis"))
598 else:
599 # Remove old files which otherwise might be confusing
600 osutils.SafeUnlink(base + ".dis")
601 osutils.SafeUnlink(base + ".Dis")
Simon Glass02741682013-05-26 07:07:58 -0700602
Alex Klein1699fab2022-09-08 08:46:06 -0600603 Log("Output directory %s" % outdir)
Simon Glass02741682013-05-26 07:07:58 -0700604
605
Simon Glass02741682013-05-26 07:07:58 -0700606def main(argv):
Simon Glasse6201d72023-02-09 16:42:22 -0700607 """Main function for script to build firmware.
Simon Glass02741682013-05-26 07:07:58 -0700608
Alex Klein1699fab2022-09-08 08:46:06 -0600609 Args:
610 argv: Program arguments.
611 """
612 options = ParseCmdline(argv)
613 base = SetupBuild(options)
Simon Glass02741682013-05-26 07:07:58 -0700614
Alex Klein1699fab2022-09-08 08:46:06 -0600615 with parallel.BackgroundTaskRunner(Dumper) as queue:
616 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700617
Alex Klein1699fab2022-09-08 08:46:06 -0600618 if options.objdump:
619 Log("Writing diasssembly files")