This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
partial c++ code binary update on embedded target
- From: Riccardo Manfrin <riccardomanfrin at gmail dot com>
- Cc: binutils at sourceware dot org
- Date: Wed, 21 Aug 2013 09:42:26 +0200
- Subject: partial c++ code binary update on embedded target
- References: <52146EB0 dot 7080103 at gmail dot com>
Hi,
I'm writing a C++ application for an embedded ARM-CM3 target
(arm-none-eabi-). The application is made by a fixed core (flashed once
and forever) and an upgradeable part. The upgradeable part is a
collection (a "library") of classes, virtual tables, function
definitions and global data/bss variables.
The library has a symbol table defined at compile time (no dynamic
relocation) that specifies for any exported symbol the absolute position
it can be found :
0x8000 0000 lib_foo0: 0x8000 0100
0x8000 0004 lib_foo1: 0x8000 0040
...
The application fixed part knows the symbol names and the type of object
associated to them and can access the correct address through variable
aliasing.
Maybe I'm doing it wrong, but my idea is to compile the application as a
single binary and place all the upgradeable part in a dedicated section
at an offset corresponding to a dedicated region of flash memory.
If the upgradeable part needs to be updated I just have to recompile the
whole application, strip the "upgradeable" special section and
(over)write the dedicated flash region with the new version of the
stripped library.
I have two concerns:
1) How do I force the upgradeable part to be placed in a separate
section (lets call it the ".upgradeable_section")? For a class, the
"__attribute__ ((section(".upgradeable_
section")))" does not work and a class can also have a virtual table
which is automatically handled by the compiler.
2) If I place all the .data, .bss and .text into a unique section, is
there a way to identify those parts of the library that are read/write
and need to be copied in RAM at startup?
My answer to these two points is to use a linkerscript similar to the
following:
MEMORY
{
rom (rx) : ORIGIN = 0x01000000, LENGTH = 512K
ram (rwx) : ORIGIN = 0x00000000, LENGTH = 32K
}
SECTIONS
{
.text:
{
…
} > rom
. = DLL_MEM_ADDRESS;
.dll_rom:
{
/**
* Put here all files and sections going in ROM (flash)
*/
foo_dll.o(.text)
} > rom
.dll_ram:
{
/**
* Put here all files and sections going in RAM
*/
foo_dll.o(.data .bss)
} >ram AT>rom
}
Is this solution applicable? Is there a better one than writing each
single file of the library in the linkerscript (I feel really bad doing
this)?
For instance, I see that the .text section can be made by several
suffixes (e.g. .text.foo, ...), is this exploitable in some way?
Sorry in advance for any unforgivable, embarrassing mistake I'm writing
through this post and thanks for the support.
RM