Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: client/common_lib/site_fmap.py

Issue 3246002: Add flashrom memory layout detection by FMAP (using fmap_decode) (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git
Patch Set: change site_fmap license header Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5 """
6 This module provides basic encode and decode functionality to the flashrom
7 memory map (FMAP) structure.
8
9 Usage:
10 (decode)
11 obj = fmap_decode(blob)
12 print obj
13
14 (encode)
15 blob = fmap_encode(obj)
16 open('output.bin', 'w').write(blob)
17
18 The object returned by fmap_decode is a dictionary with names defined in
19 fmap.h. A special property 'FLAGS' is provided as a readable and read-only
20 tuple of decoded area flags.
21 """
22
23 import struct
24 import sys
25
26 # constants imported from lib/fmap.h
27 FMAP_SIGNATURE = "__FMAP__"
28 FMAP_VER_MAJOR = 1
29 FMAP_VER_MINOR = 0
30 FMAP_STRLEN = 32
31
32 FMAP_FLAGS = {
33 'FMAP_AREA_STATIC': 1 << 0,
34 'FMAP_AREA_COMPRESSED': 1 << 1,
35 }
36
37 FMAP_HEADER_NAMES = (
38 'signature',
39 'ver_major',
40 'ver_minor',
41 'base',
42 'size',
43 'name',
44 'nareas',
45 )
46
47 FMAP_AREA_NAMES = (
48 'offset',
49 'size',
50 'name',
51 'flags',
52 )
53
54 # format string
55 FMAP_HEADER_FORMAT = "<8sBBQI%dsH" % (FMAP_STRLEN)
56 FMAP_AREA_FORMAT = "<II%dsH" % (FMAP_STRLEN)
57
58
59 def _fmap_decode_header(blob, offset):
60 """ (internal) Decodes a FMAP header from blob by offset"""
61 header = {}
62 for (name, value) in zip(FMAP_HEADER_NAMES,
63 struct.unpack_from(FMAP_HEADER_FORMAT,
64 blob,
65 offset)):
66 header[name] = value
67
68 if header['signature'] != FMAP_SIGNATURE:
69 raise struct.error('Invalid signature')
70 if header['ver_major'] != FMAP_VER_MAJOR or \
71 header['ver_minor'] != FMAP_VER_MINOR:
72 raise struct.error('Incompatible version')
73
74 # convert null-terminated names
75 header['name'] = header['name'].strip(chr(0))
76 return (header, struct.calcsize(FMAP_HEADER_FORMAT))
77
78
79 def _fmap_decode_area(blob, offset):
80 """ (internal) Decodes a FMAP area record from blob by offset """
81 area = {}
82 for (name, value) in zip(FMAP_AREA_NAMES,
83 struct.unpack_from(FMAP_AREA_FORMAT, blob, offset)):
84 area[name] = value
85 # convert null-terminated names
86 area['name'] = area['name'].strip(chr(0))
87 # add a (readonly) readable FLAGS
88 area['FLAGS'] = _fmap_decode_area_flags(area['flags'])
89 return (area, struct.calcsize(FMAP_AREA_FORMAT))
90
91
92 def _fmap_decode_area_flags(area_flags):
93 """ (internal) Decodes a FMAP flags property """
94 return tuple([name for name in FMAP_FLAGS if area_flags & FMAP_FLAGS[name]])
95
96
97 def fmap_decode(blob, offset=None):
98 """ Decodes a blob to FMAP dictionary object.
99
100 Arguments:
101 blob: a binary data containing FMAP structure.
102 offset: starting offset of FMAP. When omitted, fmap_decode will search in
103 the blob.
104 """
105 fmap = {}
106 if offset == None:
107 # try search magic in fmap
108 offset = blob.find(FMAP_SIGNATURE)
109 (fmap, size) = _fmap_decode_header(blob, offset)
110 fmap['areas'] = []
111 offset = offset + size
112 for i in range(fmap['nareas']):
113 (area, size) = _fmap_decode_area(blob, offset)
114 offset = offset + size
115 fmap['areas'].append(area)
116 return fmap
117
118
119 def _fmap_encode_header(obj):
120 """ (internal) Encodes a FMAP header """
121 values = [obj[name] for name in FMAP_HEADER_NAMES]
122 return struct.pack(FMAP_HEADER_FORMAT, *values)
123
124
125 def _fmap_encode_area(obj):
126 """ (internal) Encodes a FMAP area entry """
127 values = [obj[name] for name in FMAP_AREA_NAMES]
128 return struct.pack(FMAP_AREA_FORMAT, *values)
129
130
131 def fmap_encode(obj):
132 """ Encodes a FMAP dictionary object to blob.
133
134 Arguments
135 obj: a FMAP dictionary object.
136 """
137 # fix up values
138 obj['nareas'] = len(obj['areas'])
139 # TODO(hungte) re-assign signature / version?
140 blob = _fmap_encode_header(obj)
141 for area in obj['areas']:
142 blob = blob + _fmap_encode_area(area)
143 return blob
144
145
146 if __name__ == '__main__':
147 # main entry, do a unit test
148 blob = open('bin/example.bin').read()
149 obj = fmap_decode(blob)
150 print obj
151 blob2 = fmap_encode(obj)
152 obj2 = fmap_decode(blob2)
153 print obj2
154 assert obj == obj2
OLDNEW
« no previous file with comments | « client/common_lib/flashrom_util.py ('k') | client/site_tests/factory_EnableWriteProtect/factory_EnableWriteProtect.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698