|
gnu ld - как сделать "дырку" в памяти |
|
|
|
Aug 14 2012, 11:10
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Мне надо расположить прошивку в нижней и верхней части флеша, с пустым местом посередине. Оптимально - чтобы было занято нижние 4к и столько, сколько нужно - сверху. Но в принципе пойдет и указать размер верхнего сегмента руками. Пробовал так: Код MEMORY { ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000C000 rom1 (rx) : ORIGIN = 0x08000000, LENGTH = 0x00001000 rom2 (rx) : ORIGIN = 0x08000000 + 0x00040000 - 0x0001000, LENGTH = 0x00001000 }
SECTIONS { .text : { KEEP(*(.vectors)) *(.text .text.*) *(.rodata) } > rom1
.text2 : { *(.text .text.*) *(.rodata) } > rom2 ... } Ругается section `.text' will not fit in region `rom1'. Понятно, что можно руками распихать разные файлы по разным секциям, но нет ли способа сделать это автоматически?
|
|
|
|
|
Aug 15 2012, 05:36
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
В Makefile Код MY_FLASH_ABS_ADDRESS = 0x0F80 LDFLAGS += -Wl,--section-start=.section_my=$(MY_FLASH_ABS_ADDRESS) В программе Код #define PROGMEM_SECTION_MY __attribute__((section(".section_my")))
const uint8_t PROGMEM_SECTION_MY my_data[128] = {....}; Таким макаром можно зарезервировать место во флеше и проинитить его нужными данными. Я так делал для резервирования места в конце флеша, но думаю, что это должно сработать и с любым другим местом (я не проверял). PS: проверил - не работает Ругается что на .text налезает...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 16 2012, 04:35
|
Частый гость
 
Группа: Участник
Сообщений: 107
Регистрация: 26-09-10
Пользователь №: 59 748

|
Цитата(Непомнящий Евгений @ Aug 15 2012, 10:40)  Да, линкер какой-то недоделанный  С линкером все в порядке, просто постановка задачи достаточно странная.
|
|
|
|
|
Aug 16 2012, 04:50
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (MBR @ Aug 16 2012, 07:35)  С линкером все в порядке, просто постановка задачи достаточно странная. Постановка нормальная. Задачи бывают разные. У больших MSP430, например, область векторов прибита гвоздями посреди флеша. Или я хочу, чтобы сегменты стека при размещении "прижимались" к концу, а не началу региона. Желание вполне естественное, а линкер такого не позволяет. А ИАР позволял.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Aug 16 2012, 06:30
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 15-12-11
Из: Краснодар
Пользователь №: 68 865

|
Цитата(demiurg_spb @ Aug 15 2012, 09:36)  В Makefile Код MY_FLASH_ABS_ADDRESS = 0x0F80 LDFLAGS += -Wl,--section-start=.section_my=$(MY_FLASH_ABS_ADDRESS) В программе Код #define PROGMEM_SECTION_MY __attribute__((section(".section_my")))
const uint8_t PROGMEM_SECTION_MY my_data[128] = {....}; Таким макаром можно зарезервировать место во флеше и проинитить его нужными данными. Я так делал для резервирования места в конце флеша, но думаю, что это должно сработать и с любым другим местом (я не проверял). PS: проверил - не работает Ругается что на .text налезает... У нас примерно так и сделано, и все работает. Единственно, __attribute__((section(".section_my"))) стоит в конце, после определения переменной. используем GNU ARM, и компилятор, и линковщик
|
|
|
|
|
Aug 16 2012, 10:20
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(MBR @ Aug 16 2012, 08:35)  С линкером все в порядке, просто постановка задачи достаточно странная. Расширенно задача звучит так: Есть STM32F10xx, в которых загрузчик должен начинаться с начала флеша (так как первые 4к автоматом защищаются от записи при установке защиты на чтение). Но загрузчик в 4к не влезает, к тому ж он может впоследствии улучшаться (и увеличиваться в размере). Поэтому фиксировать под него скажем первые 8к флеша неохота. Идея такая - загрузчик занимает первые 4 к, затем располагается прошивка (всегда по фиксированному адресу 08001000), а затем в верхней области флеша продолжается загрузчик. Если впоследствии загрузчик вырастет, можно будет взять новый загрузчик и слить со старой прошивкой, не перекомпиливая ее. Ну а если прошивка не помещается в "дырку" - сливатель выдаст ошибку. Была кстати идея слинковать снача без дырки, затем вычитать из elf размеры всех функций, сгенерить нужный скрипт для линкера (указав порядок размещения функций) и слинковать заново
|
|
|
|
|
Aug 16 2012, 17:49
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 15-12-11
Из: Краснодар
Пользователь №: 68 865

|
Непомнящий Евгений, я так понял, с дыркой собирается именно загрузчик, грузится во флеш, а потом основная прошивка как-то отдельно догружается? Или после смены загрузчика перекомпилируются только его файлы, а линкуется все вместе с основной прошивкой (которая не перекомпилируется при этом)? Ну то есть в любом случае размер основной программы известен заранее, ну и значит положение дырки и размер секции text тоже известен. А для высоких адресов загрузчика создаем отдельную секцию и располагаем ее по заданному адресу. И двигаем этот адрес вниз по мере роста загрузчика Или я что-то не понял?
Сообщение отредактировал IgorKossak - Aug 16 2012, 18:25
Причина редактирования: бездумное цитирование
|
|
|
|
|
Aug 17 2012, 05:15
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(aas @ Aug 16 2012, 21:49)  Ну то есть в любом случае размер основной программы известен заранее, ну и значит положение дырки и размер секции text тоже известен. А для высоких адресов загрузчика создаем отдельную секцию и располагаем ее по заданному адресу. И двигаем этот адрес вниз по мере роста загрузчика Все так, но как это сделать? Пока единственный рабочий вариант - руками указывать, какие входные секции куда размещаются, что тоскливо. Код .text : { KEEP(*(.vectors)) *file1.obj(.text .text.*) *file2.obj(.text .text.*) *file3.obj(.text .text.*) } > rom1
.text2 : { *(.text .text.*) *(.rodata) } > rom2
|
|
|
|
|
Sep 4 2012, 07:30
|
Частый гость
 
Группа: Участник
Сообщений: 107
Регистрация: 26-09-10
Пользователь №: 59 748

|
Цитата(Непомнящий Евгений @ Aug 16 2012, 14:20)  Идея такая - загрузчик занимает первые 4 к, затем располагается прошивка (всегда по фиксированному адресу 08001000), а затем в верхней области флеша продолжается загрузчик. Мое предложение - сделать это первичным и вторичным загрузчиком. Первичный никогда не стирается и всегда занимает меньше 4 к. Основная его задача - инициализация железа и запуск вторичного загрузчика (возможно, обновление себя и вторичного загрузчика). Точка входа во вторичный загрузчик располагается по фиксированному адресу.
|
|
|
|
|
Sep 4 2012, 07:40
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
 радикальная идея. Минусы: 1. надо поместиться в т.ч. в младшие модели с 16к флеши. т.е. общий размер загрузчика не более 8 к. В 8 к у меня с трудом уместился загрузчик без всякого разделения на части 2. усложняются процессы сборки образа и перепрошивки 3. функциональность не делится на две независимые части. А если принудительно поделить - сильно вырастет размер.
|
|
|
|
|
Sep 4 2012, 08:17
|
Частый гость
 
Группа: Участник
Сообщений: 107
Регистрация: 26-09-10
Пользователь №: 59 748

|
Цитата(Непомнящий Евгений @ Sep 4 2012, 11:40)   радикальная идея. Минусы: 1. надо поместиться в т.ч. в младшие модели с 16к флеши. т.е. общий размер загрузчика не более 8 к. В 8 к у меня с трудом уместился загрузчик без всякого разделения на части 2. усложняются процессы сборки образа и перепрошивки 3. функциональность не делится на две независимые части. А если принудительно поделить - сильно вырастет размер. 1. Зачем? Фиксированный адрес джампа, а где будет находиться основной загрузчик - пофигу. 2. Да ладно. Один раз скрипт накататься 3. В том то и суть, что делится. Плюсом, можно вынести работу с железом в первичный загрузчик, а вторичный сделать аппаратно-независимым, только дергать логические функции. Я подобные схемы очень часто видел в прошивках тех же сотовых телефонов - абстракция протокола загрузчика + защита от взлома через подмену вторичного загрузчика. 8к. У Вас там цифровая подпись что-ли?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|