]> Git Repo - u-boot.git/blame - tools/binman/fmap_util.py
Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
[u-boot.git] / tools / binman / fmap_util.py
CommitLineData
11e36cce
SG
1# SPDX-License-Identifier: GPL-2.0+
2# Copyright (c) 2018 Google, Inc
3# Written by Simon Glass <[email protected]>
4#
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,
7# generally SPI flash.
8
9import collections
10import struct
f3a58c8a
SG
11import sys
12
bf776679 13from patman import tools
11e36cce
SG
14
15# constants imported from lib/fmap.h
f3a58c8a 16FMAP_SIGNATURE = b'__FMAP__'
11e36cce
SG
17FMAP_VER_MAJOR = 1
18FMAP_VER_MINOR = 0
19FMAP_STRLEN = 32
20
21FMAP_AREA_STATIC = 1 << 0
22FMAP_AREA_COMPRESSED = 1 << 1
23FMAP_AREA_RO = 1 << 2
24
25FMAP_HEADER_LEN = 56
26FMAP_AREA_LEN = 42
27
28FMAP_HEADER_FORMAT = '<8sBBQI%dsH'% (FMAP_STRLEN)
29FMAP_AREA_FORMAT = '<II%dsH' % (FMAP_STRLEN)
30
31FMAP_HEADER_NAMES = (
32 'signature',
33 'ver_major',
34 'ver_minor',
35 'base',
36 'image_size',
37 'name',
38 'nareas',
39)
40
41FMAP_AREA_NAMES = (
42 'offset',
43 'size',
44 'name',
45 'flags',
46)
47
48# These are the two data structures supported by flashrom, a header (which
49# appears once at the start) and an area (which is repeated until the end of
50# the list of areas)
51FmapHeader = collections.namedtuple('FmapHeader', FMAP_HEADER_NAMES)
52FmapArea = collections.namedtuple('FmapArea', FMAP_AREA_NAMES)
53
54
f8f8df6e 55def NameToFmap(name):
f3a58c8a
SG
56 if type(name) == bytes and sys.version_info[0] >= 3:
57 name = name.decode('utf-8') # pragma: no cover (for Python 2)
f8f8df6e
SG
58 return name.replace('\0', '').replace('-', '_').upper()
59
11e36cce
SG
60def ConvertName(field_names, fields):
61 """Convert a name to something flashrom likes
62
63 Flashrom requires upper case, underscores instead of hyphens. We remove any
64 null characters as well. This updates the 'name' value in fields.
65
66 Args:
67 field_names: List of field names for this struct
68 fields: Dict:
69 key: Field name
70 value: value of that field (string for the ones we support)
71 """
72 name_index = field_names.index('name')
f3a58c8a 73 fields[name_index] = tools.ToBytes(NameToFmap(fields[name_index]))
11e36cce
SG
74
75def DecodeFmap(data):
76 """Decode a flashmap into a header and list of areas
77
78 Args:
79 data: Data block containing the FMAP
80
81 Returns:
82 Tuple:
83 header: FmapHeader object
84 List of FmapArea objects
85 """
86 fields = list(struct.unpack(FMAP_HEADER_FORMAT, data[:FMAP_HEADER_LEN]))
87 ConvertName(FMAP_HEADER_NAMES, fields)
88 header = FmapHeader(*fields)
89 areas = []
90 data = data[FMAP_HEADER_LEN:]
91 for area in range(header.nareas):
92 fields = list(struct.unpack(FMAP_AREA_FORMAT, data[:FMAP_AREA_LEN]))
93 ConvertName(FMAP_AREA_NAMES, fields)
94 areas.append(FmapArea(*fields))
95 data = data[FMAP_AREA_LEN:]
96 return header, areas
97
98def EncodeFmap(image_size, name, areas):
99 """Create a new FMAP from a list of areas
100
101 Args:
102 image_size: Size of image, to put in the header
103 name: Name of image, to put in the header
104 areas: List of FmapArea objects
105
106 Returns:
107 String containing the FMAP created
108 """
109 def _FormatBlob(fmt, names, obj):
110 params = [getattr(obj, name) for name in names]
f8f8df6e 111 ConvertName(names, params)
11e36cce
SG
112 return struct.pack(fmt, *params)
113
fc0056e8 114 values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size, name, len(areas))
11e36cce
SG
115 blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, values)
116 for area in areas:
117 blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, area)
118 return blob
This page took 0.080095 seconds and 4 git commands to generate.