1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2018 Google, Inc
3 # Written by Simon Glass <sjg@chromium.org>
5 # Support for flashrom's FMAP format. This supports a header followed by a
6 # number of 'areas', describing regions of a firmware storage device,
12 # constants imported from lib/fmap.h
13 FMAP_SIGNATURE = '__FMAP__'
18 FMAP_AREA_STATIC = 1 << 0
19 FMAP_AREA_COMPRESSED = 1 << 1
25 FMAP_HEADER_FORMAT = '<8sBBQI%dsH'% (FMAP_STRLEN)
26 FMAP_AREA_FORMAT = '<II%dsH' % (FMAP_STRLEN)
45 # These are the two data structures supported by flashrom, a header (which
46 # appears once at the start) and an area (which is repeated until the end of
48 FmapHeader = collections.namedtuple('FmapHeader', FMAP_HEADER_NAMES)
49 FmapArea = collections.namedtuple('FmapArea', FMAP_AREA_NAMES)
53 return name.replace('\0', '').replace('-', '_').upper()
55 def ConvertName(field_names, fields):
56 """Convert a name to something flashrom likes
58 Flashrom requires upper case, underscores instead of hyphens. We remove any
59 null characters as well. This updates the 'name' value in fields.
62 field_names: List of field names for this struct
65 value: value of that field (string for the ones we support)
67 name_index = field_names.index('name')
68 fields[name_index] = NameToFmap(fields[name_index])
71 """Decode a flashmap into a header and list of areas
74 data: Data block containing the FMAP
78 header: FmapHeader object
79 List of FmapArea objects
81 fields = list(struct.unpack(FMAP_HEADER_FORMAT, data[:FMAP_HEADER_LEN]))
82 ConvertName(FMAP_HEADER_NAMES, fields)
83 header = FmapHeader(*fields)
85 data = data[FMAP_HEADER_LEN:]
86 for area in range(header.nareas):
87 fields = list(struct.unpack(FMAP_AREA_FORMAT, data[:FMAP_AREA_LEN]))
88 ConvertName(FMAP_AREA_NAMES, fields)
89 areas.append(FmapArea(*fields))
90 data = data[FMAP_AREA_LEN:]
93 def EncodeFmap(image_size, name, areas):
94 """Create a new FMAP from a list of areas
97 image_size: Size of image, to put in the header
98 name: Name of image, to put in the header
99 areas: List of FmapArea objects
102 String containing the FMAP created
104 def _FormatBlob(fmt, names, obj):
105 params = [getattr(obj, name) for name in names]
106 ConvertName(names, params)
107 return struct.pack(fmt, *params)
109 values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size, name, len(areas))
110 blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, values)
112 blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, area)