This tool implements data/bss sections compile-time compression and runtime decompression similar to a feature found in commercial ARM toolchains (IAR, ARM Compiler).
- LD linker (directed by a modified .ld script) creates an additional .idata section containing data/bss ranges table and a free space to place the init data generated by the tool later
- the compressor tool gets data/bss ranges
- tries various compression algorithms on each section to find best ones
- builds an init image consisting of addresses+methods table, decompressors code, compressed data
- places the init image into .idata section (overwriting the linker-provided table)
- shrinks the .idata section to the actual size (an ELF file itself is not shrunk for now, but the ELF to bin/hex conversion by objcopy uses shrunk size)
- marks data/bss section as non-loadable (to exclude from bin/hex conversion)
- writes the output ELF image
The decompressor code for each algorithm is either taken from tool's .bin files compiled for a particular arch or is identified inside the user's app code and referenced by pointer (thus occupying zero additional space).
A custom init code (should be executed before main(), normally called right after SystemInit()) iterates over the data/bss table, gets source/destination/size/decompressor values for each section and calls the decompressor function
- zero - fills the dst with zeroes, uses no compressed data. Reuses memset/memclr functions from the "main" code
- fill - fills the dst with byte value specified in src. Reuses memset function from the "main" code
- PackBits - a slightly modified PackBits algorithm. Efficient on data with long repetitions of the same byte
- LZ77RLE - an LZ77 combined with RLE compression of repeated zeroes. Uses the same packed data format as produced by some versions or IAR and AC. Efficient on data with repeating byte patterns and long runs of 00 bytes.
- copy - worst case, no compression, just copy the data as is. Reuses memcpy function from the "main" code
The sample code is a modified Alex Taradov's STM32G071 starter project with the following changes:
- linker script: don't place .data load image into flash, generate .idata section placeholder
- C startup code: process .idata init table
- main: added dummy initialized/uninitialized arrays to place some content into .data/.bss
- Makefile: additional build step to invoke the compressor tool
Requirements: arm-none-eabi-gcc
toolchain in $PATH
- build decompressors by invoking
make
incompression
- build the sample code by invoking
make
insample/make
. The intermediate noncompressed ELF will be output tobuild/Demo.elf'. The compressed ELF will be output to
build/Demo.comp.elf. Try
arm-none-eabi-readelf -e` on both of them to see the difference