Add support for compressed early TAs
Add decompression code to the early TA loader and update the Python
script accordingly. The compression algorithm is "deflate", which is
used by zlib and gzip in particular. It allows for compression ratios
comprised between 3 (for bigger TAs) and 4.7 (for smaller ones). Those
numbers were observed with 32-bit TAs (QEMU).
On QEMU (armv7), the code size overhead when CFG_EARLY_TA=y, including
the decompressor, is 12K when DEBUG=0 or 20K when DEBUG=1. The
decompressor allocates about 39K of heap.
Another library compatible with zlib was tried for comparison [1].
The code size overhead with miniz was 8K (DEBUG=0) or 16K (DEBUG=1).
On the other hand, the dynamic allocation was about 43K, so the total
memory required was about same. Speed was not compared. In the end,
zlib was preferred for licensing reasons and because it is widely used.
Link: [1] https://github.com/richgel999/miniz
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU)
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMUv8, pager)
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (D02 32/64 bits)
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (D02 32/64 bits, pager)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/scripts/ta_bin_to_c.py b/scripts/ta_bin_to_c.py
index 13a38c7..31f9643 100755
--- a/scripts/ta_bin_to_c.py
+++ b/scripts/ta_bin_to_c.py
@@ -31,6 +31,7 @@
import os
import re
import uuid
+import zlib
def get_args():
@@ -45,6 +46,10 @@
help='Path to the TA binary. File name has to be: <uuid>.* '
'such as: 8aaaf200-2450-11e4-abe2-0002a5d5c51b.stripped.elf')
+ parser.add_argument('--compress', dest="compress",
+ action="store_true", help='Compress the TA using the DEFLATE '
+ 'algorithm')
+
return parser.parse_args()
def main():
@@ -53,6 +58,13 @@
ta_uuid = uuid.UUID(re.sub('\..*', '', os.path.basename(args.ta)))
+ with open(args.ta, 'rb') as ta:
+ bytes = ta.read()
+ uncompressed_size = len(bytes)
+ if args.compress:
+ bytes = zlib.compress(bytes)
+ size = len(bytes)
+
f = open(args.out, 'w')
f.write('/* Generated from ' + args.ta + ' by ' +
os.path.basename(__file__) + ' */\n\n')
@@ -72,21 +84,21 @@
f.write('\t\t\t')
f.write(', '.join('0x' + csn[i:i+2] for i in range(0, len(csn), 2)))
f.write('\n\t\t},\n\t},\n')
- f.write('\t.size = {:d},'.format(os.path.getsize(args.ta)))
+ f.write('\t.size = {:d},\n'.format(size))
+ if args.compress:
+ f.write('\t.uncompressed_size = '
+ '{:d},\n'.format(uncompressed_size))
f.write('\t.ta = {\n')
i = 0
- with open(args.ta, 'rb') as ta:
- byte = ta.read(1)
- while byte:
- if i % 8 == 0:
- f.write('\t\t');
- f.write('0x' + '{:02x}'.format(ord(byte)) + ',')
- i = i + 1
- byte = ta.read(1)
- if i % 8 == 0 or not byte:
- f.write('\n')
- else:
- f.write(' ')
+ while i < size:
+ if i % 8 == 0:
+ f.write('\t\t');
+ f.write('0x' + '{:02x}'.format(ord(bytes[i])) + ',')
+ i = i + 1
+ if i % 8 == 0 or i == size:
+ f.write('\n')
+ else:
+ f.write(' ')
f.write('\t},\n')
f.write('};\n');
f.close()