Вобщем нужно собрать проект состоящий с:
1. загрузчик
2. ос
3. юзерский код

Флеш должна быть распределена примерно так:
Vector_table
Reset (entry point)
.text (оs+user)
.const (оs+user)
.loader (text+const)

RAM:
.bss | .loader
.kernelbss |
секции .bss и .loader лежат в по одному и тому же адресу.

Система стартует в следующем порядке:
1. Reset
2. OS инициализация+поддержка c++
3. User init (инициализация основного железа,...)
4. loader
5. user
6. OS
7. main()

Сам код из .loader должен быть независим от остального, но содержит функции(довольно много) с такими же именами, как в .text , но с немного другим телом.
Весь этот .loader скомпилен как position independent code.
Запускается он user-кодом. При старте либо копирует себя в RAM:.loader (затирая при этом все, что там было наинициализировано) и дальше продолжает выполнятся оттуда(затем reset()) либо делает немного работы и выходит(назад в user), не затронув при этом RAM.

Все это нужно для того, чтобы загрузчик мог как обновлять прошивку (.text), так и обновлятся сам. Запускается он из user пока временно, потом будет стартовать из Reset, которая тоже будет частью loader-а.
Вся эта муть в итоге должна быть в одном elf-файле и нормально дебажится дебагером, при этом все debug-символы должны быть на месте.
Проблемы следующие:
1. Конфликт имен. На gcc я это решил partial-линкировкой + локализацией всех символов в loader(objcopy -G). через armlink+fromelf ничего толкового не вышло, либо не видно символов либо конфликт.

2. Загруженный код в RAM должен тоже нормально дебажится. gdb вообще слетает, когда туда дойдет дело, в Keil видно только ассемблер без всяких символов, что тоже не идет.

3. armcc любит заменять разные операторы библиотечными функциями и кладет их в секцию .text, А loader должен быть независим от секции .text. Через scatter-file 2 копии библиотек тоже втулить нельзя, матерится:
Код
LOAD_BOOT_ROM 0x08000000 {
    .boot +0 {
        boot.o (.boot)
    }
    .boot1 +0 {
        boot.o (.boot)
    }
}

armlink ... --scatter=...
Error: L6223E: Ambiguous selectors found for boot.o(.boot) from Exec regions .boot and .boot1.


4. Странности с секциями bss/kernelbss. при том, что в scatter-file написано следующее:
Код
bssregion +0{
        *.o (.bss)
        *.o (.kbss)
    }

armlink генерит по 2-3 bssregion-а с разными размерами(иногда нулевыми). И в коде, где нужно знать адрес этого региона и его размер подставляет адрес и размер первого:
CODE

test.cpp:

#define __section(a) __attribute__ ((section(a)))

__section(".kbss") int aa;
long long bb;

armcc --thumb --cpu=Cortex-M3 -O3 -Otime --bss_threshold=0 -g --no_rtti --no_rtti_data --no_exceptions -c test.cpp
armlink --cpu=Cortex-M3 --no_ref_cpp_init --no_startup --vfemode=off -o test.elf --scatter=scatter.sc test.o
arm-none-eabi-objdump -h test.elf

test.elf: file format elf32-littlearm

Sections:
Idx Name Size VMA LMA File off Algn
0 bssregion 00000004 20000000 20000000 00000034 2**2
CONTENTS, ALLOC, LOAD, DATA
1 bssregion 0000000c 20000004 20000004 00000038 2**3
ALLOC
2 .debug_abbrev 00000c08 00000000 00000000 00000038 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000090 00000000 00000000 00000c40 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_pubnames 00000020 00000000 00000000 00000cd0 2**0
CONTENTS, READONLY, DEBUGGING
5 .note 00000018 00000000 00000000 00000e2c 2**2
CONTENTS, READONLY
6 .comment 00000138 00000000 00000000 00000e44 2**0
CONTENTS, READONLY