blob: 9a967367a93c2250338124f3d5b396e61c0efe87 [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._tools = tools
85 self._out = output
86
87 # Set up the things we need to know in order to operate.
88 self._board = None # Board name, e.g. tegra2_seaboard.
89 self._fdt_fname = None # Filename of our FDT.
90 self.uboot_fname = None # Filename of our U-Boot binary.
91 self.bct_fname = None # Filename of our BCT file.
92 self.fdt = None # Our Fdt object.
Hung-Te Lin5b649382011-08-03 15:01:16 +080093 self.bmpblk_fname = None # Filename of our Bitmap Block
Stefan Reinauer8d79d362011-08-16 14:20:43 -070094 self.coreboot_fname = None # Filename of our coreboot binary.
Vincent Palatinf7286772011-10-12 14:31:53 -070095 self.seabios_fname = None # Filename of our SeaBIOS payload.
Simon Glass290a1802011-07-17 13:54:32 -070096
97 def SetDirs(self, keydir):
98 """Set up directories required for Bundle.
99
100 Args:
101 keydir: Directory containing keys to use for signing firmware.
102 """
103 self._keydir = keydir
104
Simon Glass6dcc2f22011-07-28 15:26:49 +1200105 def SetFiles(self, board, bct, uboot=None, bmpblk=None, coreboot=None,
Vincent Palatinf7286772011-10-12 14:31:53 -0700106 postload=None, seabios=None):
Simon Glass290a1802011-07-17 13:54:32 -0700107 """Set up files required for Bundle.
108
109 Args:
110 board: The name of the board to target (e.g. tegra2_seaboard).
111 uboot: The filename of the u-boot.bin image to use.
112 bct: The filename of the binary BCT file to use.
Hung-Te Lin5b649382011-08-03 15:01:16 +0800113 bmpblk: The filename of bitmap block file to use.
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700114 coreboot: The filename of the coreboot image to use (on x86)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200115 postload: The filename of the u-boot-post.bin image to use.
Vincent Palatinf7286772011-10-12 14:31:53 -0700116 seabios: The filename of the SeaBIOS payload to use if any.
Simon Glass290a1802011-07-17 13:54:32 -0700117 """
118 self._board = board
119 self.uboot_fname = uboot
120 self.bct_fname = bct
Hung-Te Lin5b649382011-08-03 15:01:16 +0800121 self.bmpblk_fname = bmpblk
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700122 self.coreboot_fname = coreboot
Simon Glass6dcc2f22011-07-28 15:26:49 +1200123 self.postload_fname = postload
Vincent Palatinf7286772011-10-12 14:31:53 -0700124 self.seabios_fname = seabios
Simon Glass290a1802011-07-17 13:54:32 -0700125
126 def SetOptions(self, small):
127 """Set up options supported by Bundle.
128
129 Args:
130 small: Only create a signed U-Boot - don't produce the full packed
131 firmware image. This is useful for devs who want to replace just the
132 U-Boot part while keeping the keys, gbb, etc. the same.
133 """
134 self._small = small
135
136 def CheckOptions(self):
137 """Check provided options and select defaults."""
138 if not self._board:
139 raise ValueError('No board defined - please define a board to use')
Simon Glass493163b2011-09-14 11:19:57 -0700140 build_root = os.path.join('##', 'build', self._board, 'firmware')
Simon Glass290a1802011-07-17 13:54:32 -0700141 if not self._fdt_fname:
142 self._fdt_fname = os.path.join(build_root, 'dtb', '%s.dtb' %
143 re.sub('_', '-', self._board))
144 if not self.uboot_fname:
145 self.uboot_fname = os.path.join(build_root, 'u-boot.bin')
146 if not self.bct_fname:
147 self.bct_fname = os.path.join(build_root, 'bct', 'board.bct')
Simon Glass2a7f0b32011-08-26 11:25:17 -0700148 if not self.bmpblk_fname:
149 self.bmpblk_fname = os.path.join(build_root, 'default.bmpblk')
Simon Glass89b86b82011-07-17 23:49:49 -0700150
Simon Glass56577572011-07-19 11:08:06 +1200151 def _CreateGoogleBinaryBlock(self, hardware_id):
Simon Glass89b86b82011-07-17 23:49:49 -0700152 """Create a GBB for the image.
153
Simon Glass56577572011-07-19 11:08:06 +1200154 Args:
155 hardware_id: Hardware ID to use for this board. If None, then the
156 default from the Fdt will be used
157
Simon Glass89b86b82011-07-17 23:49:49 -0700158 Returns:
159 Path of the created GBB file.
160
161 Raises:
162 CmdError if a command fails.
163 """
Simon Glass56577572011-07-19 11:08:06 +1200164 if not hardware_id:
165 hardware_id = self.fdt.GetString('/config/hwid')
Simon Glass89b86b82011-07-17 23:49:49 -0700166 gbb_size = self.fdt.GetFlashPartSize('ro', 'gbb')
Simon Glass290a1802011-07-17 13:54:32 -0700167 odir = self._tools.outdir
Simon Glass89b86b82011-07-17 23:49:49 -0700168
Simon Glass89b86b82011-07-17 23:49:49 -0700169 self._out.Progress('Creating GBB')
170 sizes = [0x100, 0x1000, gbb_size - 0x2180, 0x1000]
171 sizes = ['%#x' % size for size in sizes]
172 gbb = 'gbb.bin'
Simon Glass290a1802011-07-17 13:54:32 -0700173 keydir = self._tools.Filename(self._keydir)
174 self._tools.Run('gbb_utility', ['-c', ','.join(sizes), gbb], cwd=odir)
Simon Glass89b86b82011-07-17 23:49:49 -0700175 self._tools.Run('gbb_utility', ['-s',
Simon Glass56577572011-07-19 11:08:06 +1200176 '--hwid=%s' % hardware_id,
Simon Glass89b86b82011-07-17 23:49:49 -0700177 '--rootkey=%s/root_key.vbpubk' % keydir,
178 '--recoverykey=%s/recovery_key.vbpubk' % keydir,
Simon Glass2a7f0b32011-08-26 11:25:17 -0700179 '--bmpfv=%s' % self._tools.Filename(self.bmpblk_fname),
Simon Glass89b86b82011-07-17 23:49:49 -0700180 gbb],
Simon Glass290a1802011-07-17 13:54:32 -0700181 cwd=odir)
182 return os.path.join(odir, gbb)
Simon Glass89b86b82011-07-17 23:49:49 -0700183
Simon Glasse13ee2c2011-07-28 08:12:28 +1200184 def _SignBootstub(self, bct, bootstub, text_base):
Simon Glass89b86b82011-07-17 23:49:49 -0700185 """Sign an image so that the Tegra SOC will boot it.
186
187 Args:
188 bct: BCT file to use.
189 bootstub: Boot stub (U-Boot + fdt) file to sign.
190 text_base: Address of text base for image.
Simon Glass89b86b82011-07-17 23:49:49 -0700191
192 Returns:
193 filename of signed image.
194
195 Raises:
196 CmdError if a command fails.
197 """
198 # First create a config file - this is how we instruct cbootimage
Simon Glasse13ee2c2011-07-28 08:12:28 +1200199 signed = os.path.join(self._tools.outdir, 'signed.bin')
Simon Glass89b86b82011-07-17 23:49:49 -0700200 self._out.Progress('Signing Bootstub')
Simon Glasse13ee2c2011-07-28 08:12:28 +1200201 config = os.path.join(self._tools.outdir, 'boot.cfg')
Simon Glass89b86b82011-07-17 23:49:49 -0700202 fd = open(config, 'w')
203 fd.write('Version = 1;\n')
204 fd.write('Redundancy = 1;\n')
205 fd.write('Bctfile = %s;\n' % bct)
Doug Anderson0eeb0742011-09-15 18:11:40 -0700206
207 # TODO(dianders): Right now, we don't have enough space in our flash map
208 # for two copies of the BCT when we're using NAND, so hack it to 1. Not
209 # sure what this does for reliability, but at least things will fit...
210 is_nand = "NvBootDevType_Nand" in self._tools.Run('bct_dump', [bct])
211 if is_nand:
212 fd.write('Bctcopy = 1;\n')
213
Simon Glass89b86b82011-07-17 23:49:49 -0700214 fd.write('BootLoader = %s,%#x,%#x,Complete;\n' % (bootstub, text_base,
215 text_base))
Doug Anderson0eeb0742011-09-15 18:11:40 -0700216
Simon Glass89b86b82011-07-17 23:49:49 -0700217 fd.close()
218
219 self._tools.Run('cbootimage', [config, signed])
220 self._tools.OutputSize('BCT', bct)
221 self._tools.OutputSize('Signed image', signed)
222 return signed
223
Doug Anderson86ce5f42011-07-27 10:40:18 -0700224 def SetBootcmd(self, bootcmd, bootsecure):
Simon Glass290a1802011-07-17 13:54:32 -0700225 """Set the boot command for U-Boot.
Simon Glass89b86b82011-07-17 23:49:49 -0700226
227 Args:
Simon Glass290a1802011-07-17 13:54:32 -0700228 bootcmd: Boot command to use, as a string (if None this this is a nop).
Doug Anderson86ce5f42011-07-27 10:40:18 -0700229 bootsecure: We'll set '/config/bootsecure' to 1 if True and 0 if False.
Simon Glass89b86b82011-07-17 23:49:49 -0700230 """
Simon Glass290a1802011-07-17 13:54:32 -0700231 if bootcmd:
Simon Glassb4447fd2011-07-26 11:18:25 +1200232 self.fdt.PutString('/config/bootcmd', bootcmd)
Doug Anderson86ce5f42011-07-27 10:40:18 -0700233 self.fdt.PutInteger('/config/bootsecure', int(bootsecure))
Simon Glass290a1802011-07-17 13:54:32 -0700234 self._out.Info('Boot command: %s' % bootcmd)
Simon Glass89b86b82011-07-17 23:49:49 -0700235
Simon Glass290a1802011-07-17 13:54:32 -0700236 def AddConfigList(self, config_list, use_int=False):
237 """Add a list of config items to the fdt.
238
239 Normally these values are written to the fdt as strings, but integers
240 are also supported, in which case the values will be converted to integers
241 (if necessary) before being stored.
242
243 Args:
244 config_list: List of (config, value) tuples to add to the fdt. For each
245 tuple:
246 config: The fdt node to write to will be /config/<config>.
247 value: An integer or string value to write.
248 use_int: True to only write integer values.
249
250 Raises:
251 CmdError: if a value is required to be converted to integer but can't be.
252 """
253 if config_list:
254 for config in config_list:
255 value = config[1]
256 if use_int:
257 try:
258 value = int(value)
259 except ValueError as str:
260 raise CmdError("Cannot convert config option '%s' to integer" %
261 value)
262 if type(value) == type(1):
263 self.fdt.PutInteger('/config/%s' % config[0], value)
264 else:
265 self.fdt.PutString('/config/%s' % config[0], value)
266
Simon Glass6dcc2f22011-07-28 15:26:49 +1200267 def _CreateBootStub(self, uboot, base_fdt, postload):
Simon Glass89b86b82011-07-17 23:49:49 -0700268 """Create a boot stub and a signed boot stub.
269
Simon Glass6dcc2f22011-07-28 15:26:49 +1200270 For postload:
271 We add a /config/postload-text-offset entry to the signed bootstub's
272 fdt so that U-Boot can find the postload code.
273
274 The raw (unsigned) bootstub will have a value of -1 for this since we will
275 simply append the postload code to the bootstub and it can find it there.
276 This will be used for RW A/B firmware.
277
278 For the signed case this value will specify where in the flash to find
279 the postload code. This will be used for RO firmware.
280
Simon Glass89b86b82011-07-17 23:49:49 -0700281 Args:
282 uboot: Path to u-boot.bin (may be chroot-relative)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200283 fdt: Fdt object containing the flat device tree.
284 postload: Path to u-boot-post.bin, or None if none.
Simon Glass89b86b82011-07-17 23:49:49 -0700285
286 Returns:
287 Tuple containing:
Simon Glass6dcc2f22011-07-28 15:26:49 +1200288 Full path to bootstub (uboot + fdt(-1) + postload).
289 Full path to signed (uboot + fdt(flash pos) + bct) + postload.
Simon Glass89b86b82011-07-17 23:49:49 -0700290
291 Raises:
292 CmdError if a command fails.
293 """
Simon Glasse13ee2c2011-07-28 08:12:28 +1200294 bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt.bin')
Simon Glass290a1802011-07-17 13:54:32 -0700295 text_base = self.fdt.GetInt('/chromeos-config/textbase');
Simon Glass89b86b82011-07-17 23:49:49 -0700296 uboot_data = self._tools.ReadFile(uboot)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200297
298 # Make a copy of the fdt for the bootstub
299 fdt = base_fdt.Copy(os.path.join(self._tools.outdir, 'bootstub.dtb'))
300 fdt.PutInteger('/config/postload-text-offset', 0xffffffff);
Simon Glass290a1802011-07-17 13:54:32 -0700301 fdt_data = self._tools.ReadFile(fdt.fname)
Simon Glasse13ee2c2011-07-28 08:12:28 +1200302
Simon Glass89b86b82011-07-17 23:49:49 -0700303 self._tools.WriteFile(bootstub, uboot_data + fdt_data)
Simon Glass290a1802011-07-17 13:54:32 -0700304 self._tools.OutputSize('U-Boot binary', self.uboot_fname)
305 self._tools.OutputSize('U-Boot fdt', self._fdt_fname)
Simon Glass89b86b82011-07-17 23:49:49 -0700306 self._tools.OutputSize('Combined binary', bootstub)
307
Simon Glasse13ee2c2011-07-28 08:12:28 +1200308 # Sign the bootstub; this is a combination of the board specific
Simon Glass89b86b82011-07-17 23:49:49 -0700309 # bct and the stub u-boot image.
Simon Glass290a1802011-07-17 13:54:32 -0700310 signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
Simon Glasse13ee2c2011-07-28 08:12:28 +1200311 bootstub, text_base)
Simon Glass6dcc2f22011-07-28 15:26:49 +1200312
313 signed_postload = os.path.join(self._tools.outdir, 'signed-postload.bin')
314 data = self._tools.ReadFile(signed)
315
316 if postload:
317 # We must add postload to the bootstub since A and B will need to
318 # be able to find it without the /config/postload-text-offset mechanism.
319 bs_data = self._tools.ReadFile(bootstub)
320 bs_data += self._tools.ReadFile(postload)
321 bootstub = os.path.join(self._tools.outdir, 'u-boot-fdt-postload.bin')
322 self._tools.WriteFile(bootstub, bs_data)
323 self._tools.OutputSize('Combined binary with postload', bootstub)
324
325 # Now that we know the file size, adjust the fdt and re-sign
326 postload_bootstub = os.path.join(self._tools.outdir, 'postload.bin')
327 fdt.PutInteger('/config/postload-text-offset', len(data))
328 fdt_data = self._tools.ReadFile(fdt.fname)
329 self._tools.WriteFile(postload_bootstub, uboot_data + fdt_data)
330 signed = self._SignBootstub(self._tools.Filename(self.bct_fname),
331 postload_bootstub, text_base)
332 if len(data) != os.path.getsize(signed):
333 raise CmdError('Signed file size changed from %d to %d after updating '
334 'fdt' % (len(data), os.path.getsize(signed)))
335
336 # Re-read the signed image, and add the post-load binary.
337 data = self._tools.ReadFile(signed)
338 data += self._tools.ReadFile(postload)
339 self._tools.OutputSize('Post-load binary', postload)
340
341 self._tools.WriteFile(signed_postload, data)
342 self._tools.OutputSize('Final bootstub with postload', signed_postload)
343
344 return bootstub, signed_postload
Simon Glass89b86b82011-07-17 23:49:49 -0700345
Vincent Palatinf7286772011-10-12 14:31:53 -0700346 def _CreateCorebootStub(self, uboot, coreboot, fdt, seabios):
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700347 """Create a coreboot boot stub.
348
349 Args:
350 uboot: Path to u-boot.bin (may be chroot-relative)
351 coreboot: Path to coreboot.rom
352 fdt: Device Tree
Vincent Palatinf7286772011-10-12 14:31:53 -0700353 seabios: Path to SeaBIOS payload binary or None
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700354
355 Returns:
356 Full path to bootstub (coreboot + uboot + fdt).
357
358 Raises:
359 CmdError if a command fails.
360 """
361 bootstub = os.path.join(self._tools.outdir, 'coreboot-full.rom')
Stefan Reinauer17c19622011-09-16 12:47:41 -0700362 cbfstool = "/usr/bin/cbfstool"
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700363 uboot_elf = uboot.replace(".bin", ".elf")
364 shutil.copyfile(coreboot, bootstub)
Vincent Palatinf7286772011-10-12 14:31:53 -0700365 if seabios:
366 self._tools.Run(cbfstool, [bootstub, 'add-payload', seabios,
367 'fallback/payload', 'lzma'])
368 self._tools.Run(cbfstool, [bootstub, 'add-payload', uboot_elf,
369 'img/U-Boot', 'lzma'])
370 else:
371 self._tools.Run(cbfstool, [bootstub, 'add-payload', uboot_elf,
372 'fallback/payload', 'lzma'])
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700373 self._tools.Run(cbfstool, [bootstub, 'add', fdt.fname, 'u-boot.dtb',
374 '0xac'])
375 return bootstub
376
Simon Glass89b86b82011-07-17 23:49:49 -0700377 def _PackOutput(self, msg):
378 """Helper function to write output from PackFirmware (verbose level 2).
379
380 This is passed to PackFirmware for it to use to write output.
381
382 Args:
383 msg: Message to display.
384 """
385 self._out.Notice(msg)
386
Simon Glass290a1802011-07-17 13:54:32 -0700387 def _CreateImage(self, gbb, fdt):
Simon Glass89b86b82011-07-17 23:49:49 -0700388 """Create a full firmware image, along with various by-products.
389
390 This uses the provided u-boot.bin, fdt and bct to create a firmware
391 image containing all the required parts. If the GBB is not supplied
392 then this will just return a signed U-Boot as the image.
393
394 Args:
Simon Glasse13ee2c2011-07-28 08:12:28 +1200395 gbb: Full path to the GBB file, or empty if a GBB is not required.
396 fdt: Fdt object containing required information.
397
398 Returns:
399 Path to image file
Simon Glass89b86b82011-07-17 23:49:49 -0700400
401 Raises:
402 CmdError if a command fails.
403 """
Simon Glass290a1802011-07-17 13:54:32 -0700404 self._out.Notice("Model: %s" % fdt.GetString('/model'))
Simon Glass89b86b82011-07-17 23:49:49 -0700405
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700406 if self.coreboot_fname:
407 # FIXME(reinauer) the names are not too great choices.
408 # signed gets packed into the bootstub, and bootstub gets
409 # packed into the RW sections.
Stefan Reinauerc2e1e4d2011-08-23 14:50:59 -0700410 signed = self._CreateCorebootStub(self.uboot_fname,
Vincent Palatinf7286772011-10-12 14:31:53 -0700411 self.coreboot_fname, fdt, self.seabios_fname)
Stefan Reinauer8d79d362011-08-16 14:20:43 -0700412 bootstub = self.uboot_fname
413 else:
414 # Create the boot stub, which is U-Boot plus an fdt and bct
Simon Glass6dcc2f22011-07-28 15:26:49 +1200415 bootstub, signed = self._CreateBootStub(self.uboot_fname, fdt,
416 self.postload_fname)
Simon Glass89b86b82011-07-17 23:49:49 -0700417
418 if gbb:
419 pack = PackFirmware(self._tools, self._out)
420 image = os.path.join(self._tools.outdir, 'image.bin')
Hung-Te Lina7462e72011-07-27 19:17:10 +0800421 fwid = '.'.join([
422 re.sub('[ ,]+', '_', fdt.GetString('/model')),
423 self._tools.GetChromeosVersion()])
Simon Glass89b86b82011-07-17 23:49:49 -0700424 self._out.Notice('Firmware ID: %s' % fwid)
425 pack.SetupFiles(boot=bootstub, signed=signed, gbb=gbb,
Simon Glass290a1802011-07-17 13:54:32 -0700426 fwid=fwid, keydir=self._keydir)
427 pack.SelectFdt(fdt)
Simon Glass89b86b82011-07-17 23:49:49 -0700428 pack.PackImage(self._tools.outdir, image)
429 else:
430 image = signed
431
432 self._tools.OutputSize('Final image', image)
Simon Glasse13ee2c2011-07-28 08:12:28 +1200433 return image
Simon Glass89b86b82011-07-17 23:49:49 -0700434
Simon Glass290a1802011-07-17 13:54:32 -0700435 def SelectFdt(self, fdt_fname):
436 """Select an FDT to control the firmware bundling
437
438 Args:
439 fdt_fname: The filename of the fdt to use.
440
Simon Glassc0f3dc62011-08-09 14:19:05 -0700441 Returns:
442 The Fdt object of the original fdt file, which we will not modify.
443
Simon Glass290a1802011-07-17 13:54:32 -0700444 We make a copy of this which will include any on-the-fly changes we want
445 to make.
446 """
447 self._fdt_fname = fdt_fname
448 self.CheckOptions()
449 fdt = Fdt(self._tools, self._fdt_fname)
450 self.fdt = fdt.Copy(os.path.join(self._tools.outdir, 'updated.dtb'))
Simon Glassc0f3dc62011-08-09 14:19:05 -0700451 return fdt
Simon Glass290a1802011-07-17 13:54:32 -0700452
Simon Glass56577572011-07-19 11:08:06 +1200453 def Start(self, hardware_id, output_fname):
Simon Glass290a1802011-07-17 13:54:32 -0700454 """This creates a firmware bundle according to settings provided.
Simon Glass89b86b82011-07-17 23:49:49 -0700455
456 - Checks options, tools, output directory, fdt.
457 - Creates GBB and image.
Simon Glass290a1802011-07-17 13:54:32 -0700458
459 Args:
Simon Glass56577572011-07-19 11:08:06 +1200460 hardware_id: Hardware ID to use for this board. If None, then the
461 default from the Fdt will be used
Simon Glass290a1802011-07-17 13:54:32 -0700462 output_fname: Output filename for the image. If this is not None, then
463 the final image will be copied here.
464
465 Returns:
466 Filename of the resulting image (not the output_fname copy).
Simon Glass89b86b82011-07-17 23:49:49 -0700467 """
Simon Glass89b86b82011-07-17 23:49:49 -0700468 gbb = ''
Simon Glass290a1802011-07-17 13:54:32 -0700469 if not self._small:
Simon Glass56577572011-07-19 11:08:06 +1200470 gbb = self._CreateGoogleBinaryBlock(hardware_id)
Simon Glass89b86b82011-07-17 23:49:49 -0700471
472 # This creates the actual image.
Simon Glasse13ee2c2011-07-28 08:12:28 +1200473 image = self._CreateImage(gbb, self.fdt)
Simon Glass290a1802011-07-17 13:54:32 -0700474 if output_fname:
475 shutil.copyfile(image, output_fname)
476 self._out.Notice("Output image '%s'" % output_fname)
477 return image