Keil™, An ARM® Company

RealView Linker and Utilities Guide

RW data compression

3.3.6. RW data compression

RW data areas typically contain a large number of repeated values, for example, zeros making them suitable for compression. RW data compression is enabled by default to minimize ROM size.

The ARM libraries contain some decompression algorithms and the linker chooses the optimal one to add to your image to decompress the data areas when the image is executed. However, you can override the algorithm chosen by the linker.

Choosing a compressor

armlink gathers information about the content of data sections before choosing the most appropriate compression algorithm to generate the smallest image. If compression is appropriate, the linker can only use one data compressor for all the compressible data sections in the image and different compressions might be tried on these sections to produce the best overall size. Compression is applied automatically if:

Compressed data size + Size of decompressor < Uncompressed data size

Once a compressor has been chosen, armlink adds the decompressor to the code area of your image. If the final image does not contain any compressed data, no decompressor is added.

You can override the compression used by the linker by either:

  • using the ‑‑datacompressor off option to turn off compression

  • specifying a compressor of your choosing.

Use the command-line option ‑‑datacompressor list to get a list of compressors available in the linker, for example:

Num	Compression algorithm
========================================================
0	Run‑length encoding
1	Run‑length encoding, with LZ77 on small‑repeats
2	Complex LZ77 compression

How is compression applied?

Run-length compression encodes data as non repeated bytes and repeated zero-bytes. Non repeated bytes are output unchanged, followed by a count of zero-bytes. Limpel-Ziv 1977 (LZ77) compression keeps track of the last n bytes of data seen and, when a phrase is encountered that has already been seen, it outputs a pair of values corresponding to the position of the phrase in the previously-seen buffer of data, and the length of the phrase.

To specify a compressor, use the required ID on the linker command line, for example:

armlink ‑‑datacompressor 2 ...

When choosing a compressor be aware that:

  • Compressor 0 performs well on data with large areas of zero-bytes but few nonzero bytes.

  • Compressor 1 performs well on data where the nonzero bytes are repeating.

  • Compressor 2 performs well on data that contains repeated values.

The linker prefers compressor 0 or 1 where the data contains mostly zero-bytes (>75%). Compressor 2 is chosen where the data contains few zero-bytes (<10%). If the image is made up only of ARM code, then ARM decompressors are used automatically. If the image contains any Thumb code, Thumb decompressors are used. If there is no clear preference, all compressors are tested to produce the best overall size (see Choosing a compressor).

Note

It is not possible to add your own compressors into the linker. The algorithms that are available, and how the linker chooses to use them, might change in the future.

Working with RW data compression

When working with RW data compression:

  • Use the linker option ‑‑map to see where compression has been applied to regions in your code.

  • The linker does not apply compression if a Load$$region_name$$Base symbol is used, where region_name follows any execution region containing compressed data in the same load region.

  • If you are using an ARM processor with on-chip cache, enable the cache after decompression to avoid code coherency problems.

In RVCT v2.0 and earlier, only the __main section and the region tables had to be placed in a root region. In RVCT v2.1 and above, RW data compression requires that additional sections (such as __dc*.o sections) be placed in a root region.

If you are using a scatter-loading description file:

  • Where coded, decompressor objects named __dc*.o, must be in a root region, for example:

    LR 0x8000
    
    {
    
        ER_ROOT +0
        {
            __main.o(*)
            * (Region$$Table)
            __scatter*.o(*)
            __dc*.o(*)
        }
    
    }
    

    Or, preferably, use InRoot$$Sections to place all library sections that must be in a root region, for example:

    LR 0x8000
    
    {
    
        ER_ROOT +0
        {
            * (InRoot$$Sections)
        }
    
    }
    

    See Assigning sections to a root region for more information.

  • Specify that a load or execution region must not be compressed by adding the NOCOMPRESS attribute. See Formal syntax of the scatter-loading description file for more information.

Copyright © 2007 ARM Limited. All rights reserved.ARM DUI 0377A