mirror of https://github.com/ARMmbed/mbed-os.git
Fill header in application
parent
b2c71c0fce
commit
4c47f21cac
|
@ -20,6 +20,9 @@ import re
|
|||
import tempfile
|
||||
import datetime
|
||||
import uuid
|
||||
import struct
|
||||
import zlib
|
||||
import hashlib
|
||||
from shutil import rmtree
|
||||
from os.path import join, exists, dirname, basename, abspath, normpath, splitext
|
||||
from os.path import relpath
|
||||
|
@ -339,8 +342,65 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
|
|||
|
||||
return toolchain
|
||||
|
||||
def _printihex(ihex):
|
||||
import pprint
|
||||
pprint.PrettyPrinter().pprint(ihex.todict())
|
||||
|
||||
def _real_region_size(region):
|
||||
try:
|
||||
part = intelhex_offset(region.filename, offset=region.start)
|
||||
return (part.maxaddr() - part.minaddr()) + 1
|
||||
except AttributeError:
|
||||
return region.size
|
||||
|
||||
def _fill_header(region_list, current_region):
|
||||
"""Fill an application header region
|
||||
|
||||
This is done it three steps:
|
||||
* Fill the whole region with zeros
|
||||
* Fill const, timestamp and size entries with their data
|
||||
* Fill the digests using this header as the header region
|
||||
"""
|
||||
region_dict = {r.name: r for r in region_list}
|
||||
header = IntelHex()
|
||||
header.puts(current_region.start, b'\x00' * current_region.size)
|
||||
start = current_region.start
|
||||
for member in current_region.filename:
|
||||
_, type, subtype, data = member
|
||||
member_size = Config.header_member_size(member)
|
||||
if type == "const":
|
||||
fmt = {"8": "<B", "16": "<H", "32": "<L", "64": "<Q"}[subtype]
|
||||
header.puts(start, struct.pack(fmt, int(data, 0)))
|
||||
elif type == "timestamp":
|
||||
fmt = {"32": "<L", "64": "<Q"}[subtype]
|
||||
header.puts(start, struct.pack(fmt, time()))
|
||||
elif type == "size":
|
||||
fmt = {"32": "<L", "64": "<Q"}[subtype]
|
||||
size = sum(_real_region_size(region_dict[r]) for r in data)
|
||||
header.puts(start, struct.pack(fmt, size))
|
||||
start += Config.header_member_size(member)
|
||||
start = current_region.start
|
||||
for member in current_region.filename:
|
||||
_, type, subtype, data = member
|
||||
if type == "digest":
|
||||
if data == "header":
|
||||
ih = header
|
||||
else:
|
||||
ih = intelhex_offset(region_dict[data].filename, offset=region_dict[data].start)
|
||||
if subtype == "CRCITT32":
|
||||
header.puts(start, struct.pack("<l", zlib.crc32(ih.tobinarray())))
|
||||
elif subtype.startswith("SHA"):
|
||||
if subtype == "SHA256":
|
||||
hash = hashlib.sha256()
|
||||
elif subtype == "SHA512":
|
||||
hash = hashlib.sha512()
|
||||
hash.update(ih.tobinarray())
|
||||
header.puts(start, hash.digest())
|
||||
start += Config.header_member_size(member)
|
||||
return header
|
||||
|
||||
def merge_region_list(region_list, destination, padding=b'\xFF'):
|
||||
"""Merege the region_list into a single image
|
||||
"""Merge the region_list into a single image
|
||||
|
||||
Positional Arguments:
|
||||
region_list - list of regions, which should contain filenames
|
||||
|
@ -355,6 +415,11 @@ def merge_region_list(region_list, destination, padding=b'\xFF'):
|
|||
for region in region_list:
|
||||
if region.active and not region.filename:
|
||||
raise ToolException("Active region has no contents: No file found.")
|
||||
if isinstance(region.filename, list):
|
||||
header_basename, _ = splitext(destination)
|
||||
header_filename = header_basename + "_header.hex"
|
||||
_fill_header(region_list, region).tofile(header_filename, format='hex')
|
||||
region = region._replace(filename=header_filename)
|
||||
if region.filename:
|
||||
print(" Filling region %s with %s" % (region.name, region.filename))
|
||||
part = intelhex_offset(region.filename, offset=region.start)
|
||||
|
|
|
@ -569,25 +569,29 @@ class Config(object):
|
|||
raise ConfigException(
|
||||
"Bootloader build requested but no bootlader configuration")
|
||||
|
||||
@staticmethod
|
||||
def header_member_size(member):
|
||||
_, _, subtype, _ = member
|
||||
try:
|
||||
return int(subtype) // 8
|
||||
except:
|
||||
if subtype == "CRCITT32":
|
||||
return 32 // 8
|
||||
elif subtype == "SHA256":
|
||||
return 256 // 8
|
||||
elif subtype == "SHA512":
|
||||
return 512 // 8
|
||||
else:
|
||||
raise ValueError("target.header_format: subtype %s is not "
|
||||
"understood" % subtype)
|
||||
|
||||
@staticmethod
|
||||
def _header_size(format):
|
||||
size_in_bytes = 0
|
||||
for _, _, subtype, _ in format:
|
||||
try:
|
||||
size_in_bytes += int(subtype) // 8
|
||||
except:
|
||||
if subtype == "CRCITT32":
|
||||
size_in_bytes += 32 // 8
|
||||
elif subtype == "SHA256":
|
||||
size_in_bytes += 256 // 8
|
||||
else:
|
||||
raise ValueError("target.header_format: subtype %s is not "
|
||||
"understood" % subtype)
|
||||
return size_in_bytes
|
||||
return sum(Config.header_member_size(m) for m in format)
|
||||
|
||||
def _make_header_region(self, start, header_format):
|
||||
size = self._header_size(header_format)
|
||||
region = Region("application_header", start, size, False, None)
|
||||
region = Region("header", start, size, False, None)
|
||||
start += size
|
||||
start = ((start + 7) // 8) * 8
|
||||
return (start, region)
|
||||
|
@ -615,7 +619,7 @@ class Config(object):
|
|||
if self.target.header_format:
|
||||
start, region = self._make_header_region(
|
||||
start, self.target.header_format)
|
||||
yield region
|
||||
yield region._replace(filename=self.target.header_format)
|
||||
if self.target.restrict_size is not None:
|
||||
new_size = int(self.target.restrict_size, 0)
|
||||
new_size = Config._align_floor(start + new_size, self.sectors) - start
|
||||
|
|
Loading…
Reference in New Issue