blob: a024eef42ab2f4fa9249ebd9599f868635a8fb51 [file] [log] [blame]
Simon Glass89b86b82011-07-17 23:49:49 -07001# Copyright (c) 2011 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"""This module builds a firmware image for a tegra-based board.
6
7This modules uses a few rudimentary other libraries for its activity.
8
9Here are the names we give to the various files we deal with. It is important
10to keep these consistent!
11
12 uboot u-boot.bin (with no device tree)
13 fdt the fdt blob
14 bct the BCT file
15 bootstub uboot + fdt
16 signed (uboot + fdt + bct) signed blob
17"""
18
19import os
20import re
21
22import cros_output
23from fdt import Fdt
24from pack_firmware import PackFirmware
25import shutil
26import tempfile
27from tools import Tools
28from write_firmware import WriteFirmware
29
30# This data is required by bmpblk_utility. Does it ever change?
31# It was stored with the chromeos-bootimage ebuild, but we want
32# this utility to work outside the chroot.
33yaml_data = '''
34bmpblock: 1.0
35
36images:
37 devmode: DeveloperBmp/DeveloperBmp.bmp
38 recovery: RecoveryBmp/RecoveryBmp.bmp
39 rec_yuck: RecoveryNoOSBmp/RecoveryNoOSBmp.bmp
40 rec_insert: RecoveryMissingOSBmp/RecoveryMissingOSBmp.bmp
41
42screens:
43 dev_en:
44 - [0, 0, devmode]
45 rec_en:
46 - [0, 0, recovery]
47 yuck_en:
48 - [0, 0, rec_yuck]
49 ins_en:
50 - [0, 0, rec_insert]
51
52localizations:
53 - [ dev_en, rec_en, yuck_en, ins_en ]
54'''
55
56class Bundle:
Simon Glass290a1802011-07-17 13:54:32 -070057 """This class encapsulates the entire bundle firmware logic.
Simon Glass89b86b82011-07-17 23:49:49 -070058
Simon Glass290a1802011-07-17 13:54:32 -070059 Sequence of events:
60 bundle = Bundle(tools.Tools(), cros_output.Output())
61 bundle.SetDirs(...)
62 bundle.SetFiles(...)
63 bundle.SetOptions(...)
64 bundle.SelectFdt(fdt.Fdt('filename.dtb')
65 .. can call bundle.AddConfigList() if required
66 bundle.Start(...)
Simon Glass89b86b82011-07-17 23:49:49 -070067
Simon Glass290a1802011-07-17 13:54:32 -070068 Public properties:
69 fdt: The fdt object that we use for building our image. This wil be the
70 one specified by the user, except that we might add config options
71 to it. This is set up by SelectFdt() which must be called before
72 bundling starts.
73 uboot_fname: Full filename of the U-Boot binary we use.
74 bct_fname: Full filename of the BCT file we use.
75 """
Simon Glass89b86b82011-07-17 23:49:49 -070076
Simon Glass290a1802011-07-17 13:54:32 -070077 def __init__(self, tools, output):
78 """Set up a new Bundle object.
Simon Glass89b86b82011-07-17 23:49:49 -070079
Simon Glass290a1802011-07-17 13:54:32 -070080 Args:
81 tools: A tools.Tools object to use for external tools.
82 output: A cros_output.Output object to use for program output.
Simon Glass89b86b82011-07-17 23:49:49 -070083 """
Simon Glass290a1802011-07-17 13:54:32 -070084 self.text_base = None # Base of U-Boot image in memory
85
86 self._tools = tools
87 self._out = output
88
89 # Set up the things we need to know in order to operate.
90 self._board = None # Board name, e.g. tegra2_seaboard.
91 self._fdt_fname = None # Filename of our FDT.
92 self.uboot_fname = None # Filename of our U-Boot binary.
93 self.bct_fname = None # Filename of our BCT file.
94 self.fdt = None # Our Fdt object.
Hung-Te Lin5b649382011-08-03 15:01:16 +080095 self.bmpblk_fname = None # Filename of our Bitmap Block
Stefan Reinauer8d79d362011-08-16 14:20:43 -070096 self.coreboot_fname = None # Filename of our coreboot binary.
Vincent Palatinf7286772011-10-12 14:31:53 -070097 self.seabios_fname = None # Filename of our SeaBIOS payload.
Simon Glass290a1802011-07-17 13:54:32 -070098
99 def SetDirs(self, keydir):
100 """Set up directories required for Bundle.
101
102 Args:
103 keydir: Directory containing keys to use for signing firmware.
104 """
105 self._keydir = keydir
106
Simon Glass6dcc2f22011-07-28 15:26:49 +1200107 def SetFiles(self, board, bct, uboot=None, bmpblk=None, coreboot=None,
Vincent Palatinf7286772011-10-12 14:31:53 -0700108 postload=None, seabios=None):
Simon Glass290a1802011-07-17 13:54:32 -0700109 """Set up files required for Bundle.
110
111 Args:
112 board: The name of the board to target (e.g. tegra2_seaboard).
113 uboot: The filename of the u-boot.bin image to use.
114 bct: The filename of the binary BCT file to use.
Hung-Te Lin5b649382011-08-03 15:01:16 +0800115 bmpblk: The filename of bitmap block file to use.
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700116 coreboot: The filename of the coreboot image to use (on x86)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200117 postload: The filename of the u-boot-post.bin image to use.
Vincent Palatinf7286772011-10-12 14:31:53 -0700118 seabios: The filename of the SeaBIOS payload to use if any.
Simon Glass290a1802011-07-17 13:54:32 -0700119 """
120 self._board = board
121 self.uboot_fname = uboot
122 self.bct_fname = bct
Hung-Te Lin5b649382011-08-03 15:01:16 +0800123 self.bmpblk_fname = bmpblk
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700124 self.coreboot_fname = coreboot
Simon Glass6dcc2f22011-07-28 15:26:49 +1200125 self.postload_fname = postload
Vincent Palatinf7286772011-10-12 14:31:53 -0700126 self.seabios_fname = seabios
Simon Glass290a1802011-07-17 13:54:32 -0700127
128 def SetOptions(self, small):
129 """Set up options supported by Bundle.
130
131 Args:
132 small: Only create a signed U-Boot - don't produce the full packed
133 firmware image. This is useful for devs who want to replace just the
134 U-Boot part while keeping the keys, gbb, etc. the same.
135 """
136 self._small = small
137
138 def CheckOptions(self):
139 """Check provided options and select defaults."""
140 if not self._board:
141 raise ValueError('No board defined - please define a board to use')
Simon Glass493163b2011-09-14 11:19:57 -0700142 build_root = os.path.join('##', 'build', self._board, 'firmware')
Simon Glass290a1802011-07-17 13:54:32 -0700143 if not self._fdt_fname:
144 self._fdt_fname = os.path.join(build_root, 'dtb', '%s.dtb' %
145 re.sub('_', '-', self._board))
146 if not self.uboot_fname:
147 self.uboot_fname = os.path.join(build_root, 'u-boot.bin')
148 if not self.bct_fname:
149 self.bct_fname = os.path.join(build_root, 'bct', 'board.bct')
Simon Glass2a7f0b32011-08-26 11:25:17 -0700150 if not self.bmpblk_fname:
151 self.bmpblk_fname = os.path.join(build_root, 'default.bmpblk')
Simon Glass89b86b82011-07-17 23:49:49 -0700152
Simon Glass56577572011-07-19 11:08:06 +1200153 def _CreateGoogleBinaryBlock(self, hardware_id):
Simon Glass89b86b82011-07-17 23:49:49 -0700154 """Create a GBB for the image.
155
Simon Glass56577572011-07-19 11:08:06 +1200156 Args:
157 hardware_id: Hardware ID to use for this board. If None, then the
158 default from the Fdt will be used
159
Simon Glass89b86b82011-07-17 23:49:49 -0700160 Returns:
161 Path of the created GBB file.
162
163 Raises:
164 CmdError if a command fails.
165 """
Simon Glass56577572011-07-19 11:08:06 +1200166 if not hardware_id:
167 hardware_id = self.fdt.GetString('/config/hwid')
Simon Glass89b86b82011-07-17 23:49:49 -0700168 gbb_size = self.fdt.GetFlashPartSize('ro', 'gbb')
Simon Glass290a1802011-07-17 13:54:32 -0700169 odir = self._tools.outdir
Simon Glass89b86b82011-07-17 23:49:49 -0700170
Simon Glass89b86b82011-07-17 23:49:49 -0700171 self._out.Progress('Creating GBB')
172 sizes = [0x100, 0x1000, gbb_size - 0x2180, 0x1000]
173 sizes = ['%#x' % size for size in sizes]
174 gbb = 'gbb.bin'
Simon Glass290a1802011-07-17 13:54:32 -0700175 keydir = self._tools.Filename(self._keydir)
176 self._tools.Run('gbb_utility', ['-c', ','.join(sizes), gbb], cwd=odir)
Simon Glass89b86b82011-07-17 23:49:49 -0700177 self._tools.Run('gbb_utility', ['-s',
Simon Glass56577572011-07-19 11:08:06 +1200178 '--hwid=%s' % hardware_id,
Simon Glass89b86b82011-07-17 23:49:49 -0700179 '--rootkey=%s/root_key.vbpubk' % keydir,
180 '--recoverykey=%s/recovery_key.vbpubk' % keydir,
Simon Glass2a7f0b32011-08-26 11:25:17 -0700181 '--bmpfv=%s' % self._tools.Filename(self.bmpblk_fname),
Simon Glass89b86b82011-07-17 23:49:49 -0700182 gbb],
Simon Glass290a1802011-07-17 13:54:32 -0700183 cwd=odir)
184 return os.path.join(odir, gbb)
Simon Glass89b86b82011-07-17 23:49:49 -0700185
Simon Glasse13ee2c2011-07-28 08:12:28 +1200186 def _SignBootstub(self, bct, bootstub, text_base):
Simon Glass89b86b82011-07-17 23:49:49 -0700187 """Sign an image so that the Tegra SOC will boot it.
188
189 Args:
190 bct: BCT file to use.
191 bootstub: Boot stub (U-Boot + fdt) file to sign.
192 text_base: Address of text base for image.
Simon Glass89b86b82011-07-17 23:49:49 -0700193
194 Returns:
195 filename of signed image.
196
197 Raises:
198 CmdError if a command fails.
199 """
200 # First create a config file - this is how we instruct cbootimage
Simon Glasse13ee2c2011-07-28 08:12:28 +1200201 signed = os.path.join(self._tools.outdir, 'signed.bin')
Simon Glass89b86b82011-07-17 23:49:49 -0700202 self._out.Progress('Signing Bootstub')
Simon Glasse13ee2c2011-07-28 08:12:28 +1200203 config = os.path.join(self._tools.outdir, 'boot.cfg')
Simon Glass89b86b82011-07-17 23:49:49 -0700204 fd = open(config, 'w')
205 fd.write('Version = 1;\n')
206 fd.write('Redundancy = 1;\n')
207 fd.write('Bctfile = %s;\n' % bct)
Doug Anderson0eeb0742011-09-15 18:11:40 -0700208
209 # TODO(dianders): Right now, we don't have enough space in our flash map
210 # for two copies of the BCT when we're using NAND, so hack it to 1. Not
211 # sure what this does for reliability, but at least things will fit...
212 is_nand = "NvBootDevType_Nand" in self._tools.Run('bct_dump', [bct])
213 if is_nand:
214 fd.write('Bctcopy = 1;\n')
215
Simon Glass89b86b82011-07-17 23:49:49 -0700216 fd.write('BootLoader = %s,%#x,%#x,Complete;\n' % (bootstub, text_base,
217 text_base))
Doug Anderson0eeb0742011-09-15 18:11:40 -0700218
Simon Glass89b86b82011-07-17 23:49:49 -0700219 fd.close()
220
221 self._tools.Run('cbootimage', [config, signed])
222 self._tools.OutputSize('BCT', bct)
223 self._tools.OutputSize('Signed image', signed)
224 return signed
225
Doug Anderson86ce5f42011-07-27 10:40:18 -0700226 def SetBootcmd(self, bootcmd, bootsecure):
Simon Glass290a1802011-07-17 13:54:32 -0700227 """Set the boot command for U-Boot.
Simon Glass89b86b82011-07-17 23:49:49 -0700228
229 Args:
Simon Glass290a1802011-07-17 13:54:32 -0700230 bootcmd: Boot command to use, as a string (if None this this is a nop).
Doug Anderson86ce5f42011-07-27 10:40:18 -0700231 bootsecure: We'll set '/config/bootsecure' to 1 if True and 0 if False.
Simon Glass89b86b82011-07-17 23:49:49 -0700232 """
Simon Glass290a1802011-07-17 13:54:32 -0700233 if bootcmd:
Simon Glassb4447fd2011-07-26 11:18:25 +1200234 self.fdt.PutString('/config/bootcmd', bootcmd)
Doug Anderson86ce5f42011-07-27 10:40:18 -0700235 self.fdt.PutInteger('/config/bootsecure', int(bootsecure))
Simon Glass290a1802011-07-17 13:54:32 -0700236 self._out.Info('Boot command: %s' % bootcmd)
Simon Glass89b86b82011-07-17 23:49:49 -0700237
Simon Glass290a1802011-07-17 13:54:32 -0700238 def AddConfigList(self, config_list, use_int=False):
239 """Add a list of config items to the fdt.
240
241 Normally these values are written to the fdt as strings, but integers
242 are also supported, in which case the values will be converted to integers
243 (if necessary) before being stored.
244
245 Args:
246 config_list: List of (config, value) tuples to add to the fdt. For each
247 tuple:
248 config: The fdt node to write to will be /config/<config>.
249 value: An integer or string value to write.
250 use_int: True to only write integer values.
251
252 Raises:
253 CmdError: if a value is required to be converted to integer but can't be.
254 """
255 if config_list:
256 for config in config_list:
257 value = config[1]
258 if use_int:
259 try:
260 value = int(value)
261 except ValueError as str:
262 raise CmdError("Cannot convert config option '%s' to integer" %
263 value)
264 if type(value) == type(1):
265 self.fdt.PutInteger('/config/%s' % config[0], value)
266 else:
267 self.fdt.PutString('/config/%s' % config[0], value)
268
Simon Glass6dcc2f22011-07-28 15:26:49 +1200269 def _CreateBootStub(self, uboot, base_fdt, postload):
Simon Glass89b86b82011-07-17 23:49:49 -0700270 """Create a boot stub and a signed boot stub.
271
Simon Glass6dcc2f22011-07-28 15:26:49 +1200272 For postload:
273 We add a /config/postload-text-offset entry to the signed bootstub's
274 fdt so that U-Boot can find the postload code.
275
276 The raw (unsigned) bootstub will have a value of -1 for this since we will
277 simply append the postload code to the bootstub and it can find it there.
278 This will be used for RW A/B firmware.
279
280 For the signed case this value will specify where in the flash to find
281 the postload code. This will be used for RO firmware.
282
Simon Glass89b86b82011-07-17 23:49:49 -0700283 Args:
284 uboot: Path to u-boot.bin (may be chroot-relative)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200285 fdt: Fdt object containing the flat device tree.
286 postload: Path to u-boot-post.bin, or None if none.
Simon Glass89b86b82011-07-17 23:49:49 -0700287
288 Returns:
289 Tuple containing:
Simon Glass6dcc2f22011-07-28 15:26:49 +1200290 Full path to bootstub (uboot + fdt(-1) + postload).
291 Full path to signed (uboot + fdt(flash pos) + bct) + postload.
Simon Glass89b86b82011-07-17 23:49:49 -0700292
293 Raises:
294 CmdError if a command fails.
295 """
Simon Glasse13ee2c2011-07-28 08:12:28 +1200296 bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt.bin')
Simon Glass290a1802011-07-17 13:54:32 -0700297 text_base = self.fdt.GetInt('/chromeos-config/textbase');
Simon Glass89b86b82011-07-17 23:49:49 -0700298 uboot_data = self._tools.ReadFile(uboot)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200299
300 # Make a copy of the fdt for the bootstub
301 fdt = base_fdt.Copy(os.path.join(self._tools.outdir, 'bootstub.dtb'))
302 fdt.PutInteger('/config/postload-text-offset', 0xffffffff);
Simon Glass290a1802011-07-17 13:54:32 -0700303 fdt_data = self._tools.ReadFile(fdt.fname)
Simon Glasse13ee2c2011-07-28 08:12:28 +1200304
Simon Glass89b86b82011-07-17 23:49:49 -0700305 self._tools.WriteFile(bootstub, uboot_data + fdt_data)
Simon Glass290a1802011-07-17 13:54:32 -0700306 self._tools.OutputSize('U-Boot binary', self.uboot_fname)
307 self._tools.OutputSize('U-Boot fdt', self._fdt_fname)
Simon Glass89b86b82011-07-17 23:49:49 -0700308 self._tools.OutputSize('Combined binary', bootstub)
309
Simon Glasse13ee2c2011-07-28 08:12:28 +1200310 # Sign the bootstub; this is a combination of the board specific
Simon Glass89b86b82011-07-17 23:49:49 -0700311 # bct and the stub u-boot image.
Simon Glass290a1802011-07-17 13:54:32 -0700312 signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
Simon Glasse13ee2c2011-07-28 08:12:28 +1200313 bootstub, text_base)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200314
315 signed_postload = os.path.join(self._tools.outdir, 'signed-postload.bin')
316 data = self._tools.ReadFile(signed)
317
318 if postload:
319 # We must add postload to the bootstub since A and B will need to
320 # be able to find it without the /config/postload-text-offset mechanism.
321 bs_data = self._tools.ReadFile(bootstub)
322 bs_data += self._tools.ReadFile(postload)
323 bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt-postload.bin')
324 self._tools.WriteFile(bootstub, bs_data)
325 self._tools.OutputSize('Combined binary with postload', bootstub)
326
327 # Now that we know the file size, adjust the fdt and re-sign
328 postload_bootstub = os.path.join(self._tools.outdir, 'postload.bin')
329 fdt.PutInteger('/config/postload-text-offset', len(data))
330 fdt_data = self._tools.ReadFile(fdt.fname)
331 self._tools.WriteFile(postload_bootstub, uboot_data + fdt_data)
332 signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
333 postload_bootstub, text_base)
334 if len(data) != os.path.getsize(signed):
335 raise CmdError('Signed file size changed from %d to %d after updating '
336 'fdt' % (len(data), os.path.getsize(signed)))
337
338 # Re-read the signed image, and add the post-load binary.
339 data = self._tools.ReadFile(signed)
340 data += self._tools.ReadFile(postload)
341 self._tools.OutputSize('Post-load binary', postload)
342
343 self._tools.WriteFile(signed_postload, data)
344 self._tools.OutputSize('Final bootstub with postload', signed_postload)
345
346 return bootstub, signed_postload
Simon Glass89b86b82011-07-17 23:49:49 -0700347
Vincent Palatinf7286772011-10-12 14:31:53 -0700348 def _CreateCorebootStub(self, uboot, coreboot, fdt, seabios):
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700349 """Create a coreboot boot stub.
350
351 Args:
352 uboot: Path to u-boot.bin (may be chroot-relative)
353 coreboot: Path to coreboot.rom
354 fdt: Device Tree
Vincent Palatinf7286772011-10-12 14:31:53 -0700355 seabios: Path to SeaBIOS payload binary or None
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700356
357 Returns:
358 Full path to bootstub (coreboot + uboot + fdt).
359
360 Raises:
361 CmdError if a command fails.
362 """
363 bootstub = os.path.join(self._tools.outdir, 'coreboot-full.rom')
Stefan Reinauer17c19622011-09-16 12:47:41 -0700364 cbfstool = "/usr/bin/cbfstool"
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700365 uboot_elf = uboot.replace(".bin", ".elf")
366 shutil.copyfile(coreboot, bootstub)
Vincent Palatinf7286772011-10-12 14:31:53 -0700367 if seabios:
368 self._tools.Run(cbfstool, [bootstub, 'add-payload', seabios,
369 'fallback/payload', 'lzma'])
370 self._tools.Run(cbfstool, [bootstub, 'add-payload', uboot_elf,
371 'img/U-Boot', 'lzma'])
372 else:
373 self._tools.Run(cbfstool, [bootstub, 'add-payload', uboot_elf,
374 'fallback/payload', 'lzma'])
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700375 self._tools.Run(cbfstool, [bootstub, 'add', fdt.fname, 'u-boot.dtb',
376 '0xac'])
377 return bootstub
378
Simon Glass89b86b82011-07-17 23:49:49 -0700379 def _PackOutput(self, msg):
380 """Helper function to write output from PackFirmware (verbose level 2).
381
382 This is passed to PackFirmware for it to use to write output.
383
384 Args:
385 msg: Message to display.
386 """
387 self._out.Notice(msg)
388
Simon Glass290a1802011-07-17 13:54:32 -0700389 def _CreateImage(self, gbb, fdt):
Simon Glass89b86b82011-07-17 23:49:49 -0700390 """Create a full firmware image, along with various by-products.
391
392 This uses the provided u-boot.bin, fdt and bct to create a firmware
393 image containing all the required parts. If the GBB is not supplied
394 then this will just return a signed U-Boot as the image.
395
396 Args:
Simon Glasse13ee2c2011-07-28 08:12:28 +1200397 gbb: Full path to the GBB file, or empty if a GBB is not required.
398 fdt: Fdt object containing required information.
399
400 Returns:
401 Path to image file
Simon Glass89b86b82011-07-17 23:49:49 -0700402
403 Raises:
404 CmdError if a command fails.
405 """
Simon Glass290a1802011-07-17 13:54:32 -0700406 self._out.Notice("Model: %s" % fdt.GetString('/model'))
Simon Glass89b86b82011-07-17 23:49:49 -0700407
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700408 if self.coreboot_fname:
409 # FIXME(reinauer) the names are not too great choices.
410 # signed gets packed into the bootstub, and bootstub gets
411 # packed into the RW sections.
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700412 signed = self._CreateCorebootStub(self.uboot_fname,
Vincent Palatinf7286772011-10-12 14:31:53 -0700413 self.coreboot_fname, fdt, self.seabios_fname)
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700414 bootstub = self.uboot_fname
415 else:
416 # Create the boot stub, which is U-Boot plus an fdt and bct
Simon Glass6dcc2f22011-07-28 15:26:49 +1200417 bootstub, signed = self._CreateBootStub(self.uboot_fname, fdt,
418 self.postload_fname)
Simon Glass89b86b82011-07-17 23:49:49 -0700419
420 if gbb:
421 pack = PackFirmware(self._tools, self._out)
422 image = os.path.join(self._tools.outdir, 'image.bin')
Hung-Te Lina7462e72011-07-27 19:17:10 +0800423 fwid = '.'.join([
424 re.sub('[ ,]+', '_', fdt.GetString('/model')),
425 self._tools.GetChromeosVersion()])
Simon Glass89b86b82011-07-17 23:49:49 -0700426 self._out.Notice('Firmware ID: %s' % fwid)
427 pack.SetupFiles(boot=bootstub, signed=signed, gbb=gbb,
Simon Glass290a1802011-07-17 13:54:32 -0700428 fwid=fwid, keydir=self._keydir)
429 pack.SelectFdt(fdt)
Simon Glass89b86b82011-07-17 23:49:49 -0700430 pack.PackImage(self._tools.outdir, image)
431 else:
432 image = signed
433
434 self._tools.OutputSize('Final image', image)
Simon Glasse13ee2c2011-07-28 08:12:28 +1200435 return image
Simon Glass89b86b82011-07-17 23:49:49 -0700436
Simon Glass290a1802011-07-17 13:54:32 -0700437 def SelectFdt(self, fdt_fname):
438 """Select an FDT to control the firmware bundling
439
440 Args:
441 fdt_fname: The filename of the fdt to use.
442
Simon Glassc0f3dc62011-08-09 14:19:05 -0700443 Returns:
444 The Fdt object of the original fdt file, which we will not modify.
445
Simon Glass290a1802011-07-17 13:54:32 -0700446 We make a copy of this which will include any on-the-fly changes we want
447 to make.
448 """
449 self._fdt_fname = fdt_fname
450 self.CheckOptions()
451 fdt = Fdt(self._tools, self._fdt_fname)
452 self.fdt = fdt.Copy(os.path.join(self._tools.outdir, 'updated.dtb'))
Simon Glassc0f3dc62011-08-09 14:19:05 -0700453 return fdt
Simon Glass290a1802011-07-17 13:54:32 -0700454
Simon Glass56577572011-07-19 11:08:06 +1200455 def Start(self, hardware_id, output_fname):
Simon Glass290a1802011-07-17 13:54:32 -0700456 """This creates a firmware bundle according to settings provided.
Simon Glass89b86b82011-07-17 23:49:49 -0700457
458 - Checks options, tools, output directory, fdt.
459 - Creates GBB and image.
Simon Glass290a1802011-07-17 13:54:32 -0700460
461 Args:
Simon Glass56577572011-07-19 11:08:06 +1200462 hardware_id: Hardware ID to use for this board. If None, then the
463 default from the Fdt will be used
Simon Glass290a1802011-07-17 13:54:32 -0700464 output_fname: Output filename for the image. If this is not None, then
465 the final image will be copied here.
466
467 Returns:
468 Filename of the resulting image (not the output_fname copy).
Simon Glass89b86b82011-07-17 23:49:49 -0700469 """
Simon Glass89b86b82011-07-17 23:49:49 -0700470 gbb = ''
Simon Glass290a1802011-07-17 13:54:32 -0700471 if not self._small:
Simon Glass56577572011-07-19 11:08:06 +1200472 gbb = self._CreateGoogleBinaryBlock(hardware_id)
Simon Glass89b86b82011-07-17 23:49:49 -0700473
474 # This creates the actual image.
Simon Glasse13ee2c2011-07-28 08:12:28 +1200475 image = self._CreateImage(gbb, self.fdt)
Simon Glass290a1802011-07-17 13:54:32 -0700476 if output_fname:
477 shutil.copyfile(image, output_fname)
478 self._out.Notice("Output image '%s'" % output_fname)
479 return image