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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
Index: client/common_lib/site_fmap.py
diff --git a/client/common_lib/site_fmap.py b/client/common_lib/site_fmap.py
new file mode 100644
index 0000000000000000000000000000000000000000..87e87ffdffc250d808535e93a9039004c5b03fd7
--- /dev/null
+++ b/client/common_lib/site_fmap.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""
+This module provides basic encode and decode functionality to the flashrom
+memory map (FMAP) structure.
+
+Usage:
+ (decode)
+ obj = fmap_decode(blob)
+ print obj
+
+ (encode)
+ blob = fmap_encode(obj)
+ open('output.bin', 'w').write(blob)
+
+ The object returned by fmap_decode is a dictionary with names defined in
+ fmap.h. A special property 'FLAGS' is provided as a readable and read-only
+ tuple of decoded area flags.
+"""
+
+import struct
+import sys
+
+# constants imported from lib/fmap.h
+FMAP_SIGNATURE = "__FMAP__"
+FMAP_VER_MAJOR = 1
+FMAP_VER_MINOR = 0
+FMAP_STRLEN = 32
+
+FMAP_FLAGS = {
+ 'FMAP_AREA_STATIC': 1 << 0,
+ 'FMAP_AREA_COMPRESSED': 1 << 1,
+}
+
+FMAP_HEADER_NAMES = (
+ 'signature',
+ 'ver_major',
+ 'ver_minor',
+ 'base',
+ 'size',
+ 'name',
+ 'nareas',
+)
+
+FMAP_AREA_NAMES = (
+ 'offset',
+ 'size',
+ 'name',
+ 'flags',
+)
+
+# format string
+FMAP_HEADER_FORMAT = "<8sBBQI%dsH" % (FMAP_STRLEN)
+FMAP_AREA_FORMAT = "<II%dsH" % (FMAP_STRLEN)
+
+
+def _fmap_decode_header(blob, offset):
+ """ (internal) Decodes a FMAP header from blob by offset"""
+ header = {}
+ for (name, value) in zip(FMAP_HEADER_NAMES,
+ struct.unpack_from(FMAP_HEADER_FORMAT,
+ blob,
+ offset)):
+ header[name] = value
+
+ if header['signature'] != FMAP_SIGNATURE:
+ raise struct.error('Invalid signature')
+ if header['ver_major'] != FMAP_VER_MAJOR or \
+ header['ver_minor'] != FMAP_VER_MINOR:
+ raise struct.error('Incompatible version')
+
+ # convert null-terminated names
+ header['name'] = header['name'].strip(chr(0))
+ return (header, struct.calcsize(FMAP_HEADER_FORMAT))
+
+
+def _fmap_decode_area(blob, offset):
+ """ (internal) Decodes a FMAP area record from blob by offset """
+ area = {}
+ for (name, value) in zip(FMAP_AREA_NAMES,
+ struct.unpack_from(FMAP_AREA_FORMAT, blob, offset)):
+ area[name] = value
+ # convert null-terminated names
+ area['name'] = area['name'].strip(chr(0))
+ # add a (readonly) readable FLAGS
+ area['FLAGS'] = _fmap_decode_area_flags(area['flags'])
+ return (area, struct.calcsize(FMAP_AREA_FORMAT))
+
+
+def _fmap_decode_area_flags(area_flags):
+ """ (internal) Decodes a FMAP flags property """
+ return tuple([name for name in FMAP_FLAGS if area_flags & FMAP_FLAGS[name]])
+
+
+def fmap_decode(blob, offset=None):
+ """ Decodes a blob to FMAP dictionary object.
+
+ Arguments:
+ blob: a binary data containing FMAP structure.
+ offset: starting offset of FMAP. When omitted, fmap_decode will search in
+ the blob.
+ """
+ fmap = {}
+ if offset == None:
+ # try search magic in fmap
+ offset = blob.find(FMAP_SIGNATURE)
+ (fmap, size) = _fmap_decode_header(blob, offset)
+ fmap['areas'] = []
+ offset = offset + size
+ for i in range(fmap['nareas']):
+ (area, size) = _fmap_decode_area(blob, offset)
+ offset = offset + size
+ fmap['areas'].append(area)
+ return fmap
+
+
+def _fmap_encode_header(obj):
+ """ (internal) Encodes a FMAP header """
+ values = [obj[name] for name in FMAP_HEADER_NAMES]
+ return struct.pack(FMAP_HEADER_FORMAT, *values)
+
+
+def _fmap_encode_area(obj):
+ """ (internal) Encodes a FMAP area entry """
+ values = [obj[name] for name in FMAP_AREA_NAMES]
+ return struct.pack(FMAP_AREA_FORMAT, *values)
+
+
+def fmap_encode(obj):
+ """ Encodes a FMAP dictionary object to blob.
+
+ Arguments
+ obj: a FMAP dictionary object.
+ """
+ # fix up values
+ obj['nareas'] = len(obj['areas'])
+ # TODO(hungte) re-assign signature / version?
+ blob = _fmap_encode_header(obj)
+ for area in obj['areas']:
+ blob = blob + _fmap_encode_area(area)
+ return blob
+
+
+if __name__ == '__main__':
+ # main entry, do a unit test
+ blob = open('bin/example.bin').read()
+ obj = fmap_decode(blob)
+ print obj
+ blob2 = fmap_encode(obj)
+ obj2 = fmap_decode(blob2)
+ print obj2
+ assert obj == obj2
« 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