cros_write_firmware: Extract FDT from image automatically
It is a pain to have to specify the board and FDT when writing an image.
Extract the FDT from the image instead, while still allowing an override
if required.
BUG=chromium:245311
BRANCH=none
TEST=manual
Using any image build from ToT, this command should flash it over USB:
$ cros_write_firmware /path/to/image.bin -F spi
For x86, this command should write it to em100:
$ cros_write_firmware /path/to/image.bin
Tested on pit and link.
Change-Id: I6fedec0ee6a6f877f72abe963b4b92bff82345eb
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/66922
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
diff --git a/host/cros_write_firmware b/host/cros_write_firmware
index ab832b8..48e65f7 100755
--- a/host/cros_write_firmware
+++ b/host/cros_write_firmware
@@ -55,6 +55,19 @@
bundle = Bundle(tools, output)
bundle.SetFiles(board=options.board, bct=options.bct,
exynos_bl1=options.exynos_bl1, exynos_bl2=options.exynos_bl2)
+
+ # Get the FDT from the image if possible.
+ if not options.fdt:
+ fdt_fname = tools.GetOutputFilename('fdt-from-image.dtb')
+ fdt = Fdt(tools, fdt_fname)
+ fdt.ExtractFromImage(options.image)
+ options.fdt = fdt_fname
+ if not options.board:
+ bundle._board = fdt.GetString('/chromeos-config', 'board', 'none')
+ if bundle._board == 'none':
+ raise ValueError('Cannot obtain board type from FDTMAP')
+ output.Notice("Using board from fdtmap: '%s'" % bundle._board)
+
if options.use_defaults:
bundle.CheckOptions()
bundle.spl_source = options.spl_source
@@ -125,8 +138,6 @@
del args[1]
if not options.image:
parser.error('Please use --image to specify a firmware image to flash');
- if not options.board:
- parser.error('Please use --board to specify the board type to flash');
if len(args) > 1:
parser.error("Unrecognized arguments '%s'" % ' '.join(args[1:]))
diff --git a/host/lib/bundle_firmware.py b/host/lib/bundle_firmware.py
index a8c697f..eb4a314 100644
--- a/host/lib/bundle_firmware.py
+++ b/host/lib/bundle_firmware.py
@@ -1096,6 +1096,9 @@
self._out.Warning('Missing properties in /config, using defaults')
fdt.InsertNodes([i for i in default_flashmap if i['path'] == '/config'])
+ # Remember our board type.
+ fdt.PutString('/chromeos-config', 'board', self._board)
+
self.fdt = fdt
return fdt
diff --git a/host/lib/fdt.py b/host/lib/fdt.py
index c59487d..e2964a2 100644
--- a/host/lib/fdt.py
+++ b/host/lib/fdt.py
@@ -6,11 +6,13 @@
"""This library provides basic access to an fdt blob."""
+import binascii
import doctest
import optparse
import os
import re
import shutil
+import struct
import sys
import cros_output
@@ -32,6 +34,26 @@
_, ext = os.path.splitext(fname)
self._is_compiled = ext == '.dtb'
+ def ExtractFromImage(self, fname):
+ """Extract an FDT from a Chrome OS firmware image (FDTMAP).
+
+ Args:
+ fname: Filename of image
+
+ Raises:
+ ValueError if no fdtmap is found in the image, or its crc32 is incorrect.
+ """
+ data = self.tools.ReadFile(fname)
+ pos = data.find('__FDTM__')
+ if pos == -1:
+ raise ValueError("No fdtmap found in image '%s'" % fname)
+ size, crc32 = struct.unpack('<LL', data[pos + 8:pos + 16])
+ fdt_data = data[pos + 16:pos + 16 + size]
+ check_crc32 = binascii.crc32(fdt_data) & 0xffffffff
+ if check_crc32 != crc32:
+ raise ValueError('Invalid CRC for FDTMAP')
+ self.tools.WriteFile(self.fname, fdt_data)
+
def GetProp(self, node, prop, default=None, typespec=None):
"""Get a property from a device tree.