ARV 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба захотелось сделать собственный boolloader с шифрованием. план действий такой: загрузчик есть обычная программа Си, всю секцию .text которой я размещаю во FLASH-области загрузчика AVR. но тут возникает проблема: прерывания я не использую, и получается, что вся таблица векторов напрасно занимает память. ничего проще, чем сместить адрес секции .text так, чтобы на начало области загрузчика пришлось как раз начало собственно кода инициализации программы, мне в голову не пришло. конечно, можно все делать руками: вычислять размер таблицы векторов, вычислять новый адрес для начала загрузчика и т.п.... но хочется как-то это упростить. посему вопрос: есть ли возможность каким-либо способом передать компоновщику адрес секции, взяв его из результата работы препроцессора? т.е. я определяю макрос START_BOOT_ADDR в тексте программы, его значение вычисляется компилятором и... и как-то попадает в опцию -Wl,--section-start=.text=START_BOOT_ADDR... это возможно? или есть более кошерный способ достичь желаемого? Да, вот еще что: в конце кода компилятор добавляет совершенно ненужные команды cli и rjmp $ - нет ли способа от них избавиться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба есть ли возможность каким-либо способом передать компоновщику адрес секции, взяв его из результата работы препроцессора? т.е. я определяю макрос 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 - нафига его удалять, если для штатного сброса собакой можно просто выйти из функции? У Вас ведь есть варианты, где надо устроить сброс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба получше, да не совсем. речь вот о чем: начало загрузчика определяется фьюзами - это понятно. допустим, для atmega16 я выбрал начало 0x1C00. так вот, 0x54 - это размер таблицы векторов для этого контроллера, т.е. секцию я должен поместить по адресу 0x1C00*2 - 0x0054, тогда как раз само тело загрузчика окажется с самого начала области, а таблица векторов будет перезаписана при загрузке основного приложения. все просто, но для сборки проекта под разные МК каждый раз надо вспоминать, какой размер таблицы векторов прерываний у этого контроллера... а ведь в соответствующем хидере имеется макрос _VECTORS_SIZE, который можно было бы использовать для автоматического вычисления смещения (для atmega16 _VECTORS_SIZE == 0x54)... улавливаете идею? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба улавливаете идею? Возьмите для этого случая отдельный стартап, прибейте там всю секцию .vectors Тем более, что инициализация Вам какая нужна? Имхо, только clr R1, установка стека и вызов самого бута. Если Бут может вызываться прямо из приложения, сделайте его с параметром, например ненулевым, а по старту - вызов с нулевым. Я тут немного побредил на тему бута под мегу48, там лежит еще очень сырой стартап - не было выравнивания на границу страницы и еще многих вещей. Но Вашей задаче-то оно не надо. Все начинается с .init0 ЗЫ вспомнил: от .vectors все-таки нужен переход на стартовую метку Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба все эти манипуляции со стартапами - это как-то довольно туманно для меня... как они делаются? спасибо за попытки помочь, но все же вы пытаетесь склонить меня к вашему подходу, или предложить вообще третий вариант... мне же хотелось бы получить (если существует) способ сделать то, что я хочу. в принципе, взять калькулятор и, открыв соответствующий инклюд, несложно вычислить и вручную адрес секции, и не думаю, что это будет намного сложнее всего уже предложенного... скорее наоборот... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Чтобы не линковались вектора, нужно закомментить строчку в скрипте линкера: KEEP(*(.vectors)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Чтобы не линковались вектора, нужно закомментить строчку в скрипте линкера: KEEP(*(.vectors)) а нельзя ли линкеру как-то через параметры командной строки сказать, чтобы эту секцию он не линковал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Присоединяюсь к вопросу :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Только что сделал примерно следующее: 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"::); } Это годится хоть для совместного использования с бутом, хоть для совместной заливки хоть для раздельной Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться