Цитата(alvy @ Jul 1 2010, 06:21)

Можно с этого места поподробнее?

Т.е. саму идею понял, но как это все должно выглядеть - не совсем
для gcc примерно так:
Код
boot_app_cross_table.h:
struct boot_app_cross_table
{
uint32_t (*Serial_no)();
void (*AES_init)(uint32_t *init_vector);
void (*AES_decode)(uint32_t *block);
bool (*TCP_send)(void const * from, size_t size);
}extern Bootloader;
//=========
bootloader.cpp:
extern uint32_t Serial_no();
void AES_init(uint32_t * init_vector)
{
AES.init(init_vector);
}
void AES_decode(uint32_t * block)
{
AES.decode(block);
}
extern void TCP_send(void const * from, size_t size);
__attribute__((section, ".boot_app_cross"))
Bootloader =
{
Serial_no,
AES_init,
AES_decode,
TCP_send,
};
//=========
bootloader.ld:
MEMORY
{
.....
CROSS (rx) : ORIGIN = 0x00100040, LENGTH = 4 * 4
....
}
SECTIONS
{
.....
.cross :
{
KEEP(*(.boot_app_cross*))
} > CROSS
//=========
application.cpp:
#include "boot_app_cross_table"
void Test()
{
printf("Serial number: %d", Bootloader.Serial_no());
}
//=========
makefile:
LDFLAGS += -Wl,--defsym,Bootloader=0x00100040
Цитата(Yaumen @ Jul 1 2010, 08:30)

Вот тут немного поподробнее. С загрузчиком все понятно, у него свой main(), который может располагаться где угодно в пределах первых 2-х секторов, а переход на main() действительно будет по 0-му адресу.
До main() еще дойти надо. До вызова main() исполняется startup-код, который готовит переменные, настраивает стеки и кое-какую периферию, вызывает конструкторы глобальных объектов и уже после всего этого вызывает main(). А сам стартап-код вызывается из вектора исключения RESET.
Цитата(Yaumen @ Jul 1 2010, 08:30)

Теперь о пользовательской программе. У него также main может располагаться в любом месте оставшейся памяти и об адресе этого main() загрузчик естественно ничего не знает.
У приложения точно так-же есть своя таблица векторов. В которой вектор RESET указывает на стартап-код. А стартап-код вызывает main(). Загрузчик копирует эту таблицу в начало ОЗУ и делает remap. Таблица оказывается отражена на адрес 0. По адресу 0 оказывается команда перехода на стартап-код приложения. Осталось перейти на адрес 0.
Цитата(Yaumen @ Jul 1 2010, 08:30)

Есть еще один минус у двух проектов. Я планирую использовать AES шифрование, которое жестко будет зашито в загрузчик, а значит все пользовательские программы необходимо шифровать одним и тем же ключем, это же касается и сигнатуры. Мне кажется это неправильно!!!
Почему? А если все программы будут с разными ключами - как вы их загрузите в одно устройство?
Цитата(Yaumen @ Jul 1 2010, 08:30)

разработан протокол обмена, позволяющий передавать файлы больших размеров, склеивать их на приемном устройстве, вести одновременный прием от нескольких устройств, ну и т.д. Это достаточно большой кусок куда, который не хотелось бы дублировать
Нужна ли вся эта функциональность загрузчику? Может ему достаточно сильно урезанной версии? Или может у приложения есть возможность сохранить образ прошивки в какой-то внешней памяти, а загрузчик тогда будет брать шифрованную прошивку из этой памяти? А как аварийный вариант и для первоначальной загрузки предусмотреть что-нибудь типа uart?