In this lesson, you will learn how to bypass the compiler and integrate raw binary files, such as firmware patches, images, or precomputed look-up tables, directly into your final executable memory map.
The Problem: Beyond Source Code
Often, your embedded project requires data that wasn't generated by your C compiler—perhaps a proprietary sensor calibration table or a pre-compiled graphics asset. While you could convert these into giant static const unsigned char arrays in C, that bloats your source code, increases compilation times, and clutters your build directory. Instead, we can use the linker’s ability to treat arbitrary files as object modules.
Linking the Blob
The most efficient way to achieve this is by using the objcopy utility to transform a raw binary file into a relocatable object file that your linker understands. You can convert a file named data.bin into an object file compatible with your architecture (e.g., elf32-littlearm) using a command like this:
arm-none-eabi-objcopy -I binary -O elf32-littlearm --rename-section .data=.rodata,alloc,load,readonly,data,contents data.bin data.o
This command wraps your raw data in an ELF container. Once wrapped, the file has a defined section (usually .rodata) and two automatically generated symbols: _binary_data_bin_start and _binary_data_bin_end.
Accessing the Data in C
Because these symbols are exported by the object file, you can reference them directly in your C code as if they were global arrays:
extern const uint8_t _binary_data_bin_start[];
extern const uint8_t _binary_data_bin_end[];
void process_blob() {
size_t size = _binary_data_bin_end - _binary_data_bin_start;
// Access data via pointers
const uint8_t *blob_ptr = _binary_data_bin_start;
}
By placing these in your linker script’s .rodata section, the linker handles the physical memory placement, ensuring your blob resides exactly where you need it—typically in Flash—without needing to manually manage memory addresses in your source code. This workflow keeps your build system clean and treats raw data as first-class citizens in your binary image.
Key Takeaway: You can integrate external binary data into your executable by converting raw files into object files with objcopy, allowing the linker to map them into specific memory regions while providing accessible symbols for your C code.