Перейти к содержанию
    

Автоматическое размещение секции по нужному адресу

захотелось сделать собственный boolloader с шифрованием.

план действий такой: загрузчик есть обычная программа Си, всю секцию .text которой я размещаю во FLASH-области загрузчика AVR. но тут возникает проблема: прерывания я не использую, и получается, что вся таблица векторов напрасно занимает память. ничего проще, чем сместить адрес секции .text так, чтобы на начало области загрузчика пришлось как раз начало собственно кода инициализации программы, мне в голову не пришло.

 

конечно, можно все делать руками: вычислять размер таблицы векторов, вычислять новый адрес для начала загрузчика и т.п.... но хочется как-то это упростить. посему вопрос: есть ли возможность каким-либо способом передать компоновщику адрес секции, взяв его из результата работы препроцессора? т.е. я определяю макрос START_BOOT_ADDR в тексте программы, его значение вычисляется компилятором и... и как-то попадает в опцию -Wl,--section-start=.text=START_BOOT_ADDR... это возможно? или есть более кошерный способ достичь желаемого?

 

Да, вот еще что: в конце кода компилятор добавляет совершенно ненужные команды cli и rjmp $ - нет ли способа от них избавиться?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть ли возможность каким-либо способом передать компоновщику адрес секции, взяв его из результата работы препроцессора? т.е. я определяю макрос START_BOOT_ADDR в тексте программы, его значение вычисляется компилятором и... и как-то попадает в опцию -Wl,--section-start=.text=START_BOOT_ADDR... это возможно? или есть более кошерный способ достичь желаемого?

если подойти к проблеме с другой стороны

START_BOOT_ADDR = 0x1000
LDFLAGS += -Wl,--section-start=.text=$(START_BOOT_ADDR)
CDEFS+= -DSTART_BOOT_ADDR=$(START_BOOT_ADDR)

Так получше? К тому же отсюда можно и фьюзами при прошивке управлять

 

Насчет rjmp - нафига его удалять, если для штатного сброса собакой можно просто выйти из функции? У Вас ведь есть варианты, где надо устроить сброс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

получше, да не совсем. речь вот о чем: начало загрузчика определяется фьюзами - это понятно. допустим, для atmega16 я выбрал начало 0x1C00. так вот, 0x54 - это размер таблицы векторов для этого контроллера, т.е. секцию я должен поместить по адресу 0x1C00*2 - 0x0054, тогда как раз само тело загрузчика окажется с самого начала области, а таблица векторов будет перезаписана при загрузке основного приложения. все просто, но для сборки проекта под разные МК каждый раз надо вспоминать, какой размер таблицы векторов прерываний у этого контроллера... а ведь в соответствующем хидере имеется макрос _VECTORS_SIZE, который можно было бы использовать для автоматического вычисления смещения (для atmega16 _VECTORS_SIZE == 0x54)... улавливаете идею?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

улавливаете идею?

Возьмите для этого случая отдельный стартап, прибейте там всю секцию .vectors

Тем более, что инициализация Вам какая нужна? Имхо, только clr R1, установка стека и вызов самого бута. Если Бут может вызываться прямо из приложения, сделайте его с параметром, например ненулевым, а по старту - вызов с нулевым. Я тут немного побредил на тему бута под мегу48, там лежит еще очень сырой стартап - не было выравнивания на границу страницы и еще многих вещей. Но Вашей задаче-то оно не надо. Все начинается с .init0

ЗЫ вспомнил: от .vectors все-таки нужен переход на стартовую метку

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

все эти манипуляции со стартапами - это как-то довольно туманно для меня... как они делаются?

спасибо за попытки помочь, но все же вы пытаетесь склонить меня к вашему подходу, или предложить вообще третий вариант... мне же хотелось бы получить (если существует) способ сделать то, что я хочу. в принципе, взять калькулятор и, открыв соответствующий инклюд, несложно вычислить и вручную адрес секции, и не думаю, что это будет намного сложнее всего уже предложенного... скорее наоборот...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы не линковались вектора, нужно закомментить строчку в скрипте линкера:

KEEP(*(.vectors))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы не линковались вектора, нужно закомментить строчку в скрипте линкера:

KEEP(*(.vectors))

а нельзя ли линкеру как-то через параметры командной строки сказать, чтобы эту секцию он не линковал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что сделал примерно следующее:

Makefile

START_BOOT_ADDR = 0x1000
MAIN_BOOT_ADDR = 0x1010
LDFLAGS += -Wl,--section-start=.boot0=$(START_BOOT_ADDR)
LDFLAGS += -Wl,--section-start=.boot1=$(MAIN_BOOT_ADDR)

main.c

void pre_boot(void) __attribute__((section(".boot0"),used,naked));
void Boot_Loader(void) __attribute__((section(".boot1"), used,OS_main));
void pre_boot(void)
{
  asm("clr r1"::);
  SP = RAMEND;
  asm("rjmp Boot_Loader"::);
}

Это годится хоть для совместного использования с бутом, хоть для совместной заливки хоть для раздельной

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...