Зарезервировать пространство памяти в области памяти m_text FLASH на встроенной цели
У меня есть микроконтроллер с большим количеством вспышки, разделенной на сектора по 1 Кб. Я хочу прошить простые числа в определенную область памяти во время перепрошивки, затем во время первой загрузки будет сгенерирован криптографический ключ, затем простые числа будут стерты и перезаписаны.
Я бы предпочел скрывать простые числа внутри m_text и не создавать область памяти для чтения / записи для простых чисел с помощью сценария компоновщика.
Прошивка, простые числа и загрузчик компилируются отдельно, в результате получается 3.hex файла, которые используются для прошивки.
Скажем, код FW должен начинаться с 0x2000, а его длина - 0x2000. Внутри этой области я хочу выделить сектор размером 1024 байта, который впоследствии можно будет стереть и перезаписать, не перекрывая FW.
С помощью следующего кода я могу читать, стирать и записывать данные на флэш-память, но у меня есть несколько вопросов:
- С помощью следующего кода GCC будет выделять сектор в 0x3000? если нет, то как?
- Знаете ли вы лучший способ сделать это?
Код:
...
typedef uint8_t sector[1024];
uint32_t* prime = (sector*)0x3000;
uint32_t data = *prime;
uint32_t dataToWrite = 0xdeadbeef;
flash_init();
flash_sector_erase(0x3000);
flash_block(0x3000,(uint8_t*)&dataToWrite,4);
data = *prime;
...
Скрипт компоновщика
MEMORY {
...
m_text(rx): ORIGIN = 0x00002000, LENGTH = 0x2000
...
}
ОБНОВЛЕНИЕ: Я должен зарезервировать пространство по указанному флэш-адресу с GCC, он показывает, что другие компиляторы имеют решение для этого, но с GCC я должен использовать сценарии компоновщика.
отсюда я прочитал это:
Специальная переменная компоновщика точка `.' всегда содержит текущий счетчик местоположения выхода. С тех пор. всегда ссылается на местоположение в выходном разделе, оно может появляться только в выражении в команде SECTIONS.. Символ может появляться везде, где в выражении допускается обычный символ.
Присвоение значения. приведет к перемещению счетчика местоположения. Это может быть использовано для создания отверстий в секции вывода. Счетчик местоположения никогда не может быть перемещен назад.
SECTIONS
{
output :
{
file1(.text)
. = . + 1000;
file2(.text)
. += 1000;
file3(.text)
} = 0x1234;
}
В предыдущем примере
.text' section from
file1'находится в начале секции выводаoutput'. It is followed by a 1000 byte gap. Then the
.text'раздел изfile2' appears, also with a 1000 byte gap following before the
.text'раздел изfile3'. The notation
= 0x1234'указывает, какие данные записывать в пропуски (см. Раздел Вывод заполненной секции).
Мой раздел m_text выглядит так:
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
Итак, что я могу сделать, это изменить его на:
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
. = NEXT(0x400); /* move to start of next 1kb section*/
. += 0x400; /* jump 1k forward */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
Теперь мы зарезервировали данные на флэш-памяти, но адрес будет зависеть от размера.text с, что не идеально, но это может сработать, если мы перейдем от прямой адресации в коде FW к имени раздела, а затем примем размер.text из проекта FW и padd в следующий сектор размером 1024 байта, чтобы получить адрес, который мы импортируем в проект простого числа.
Я также не очень доволен заполнением перед сектором, в идеальном мире мы бы заполняли его "мусорным кодом" или случайными данными, я видел, что вы можете указать шаблон для заполнения, но любой последовательный шаблон будет сиять целых 0xffffff или 0x00000 для обратного инженера;)
есть идеи получше?
2 ответа
Вы можете найти массив в m_text
раздел с использованием gcc __attribute__((section("m_text") ))
,
Область памяти не является разделом. Таким образом, вам нужно добавить этот раздел в скрипт компоновщика, поместив его в эту область памяти (не уверен, если оба используют разные пространства имен, но было бы лучше иметь разные имена для региона и раздела). Если это не загружено с программой, это должно быть NOLOAD
(так же, как .bss
).
Или вы используете только компоненты C и не имеете никаких средств компоновки. Однако это предотвратит загрузку данных с помощью программы, поэтому она работает только в том случае, если вы собираетесь программировать эту область отдельно от программы.
Не уверен, какой компилятор вы используете, но с помощью GCC вы можете указать раздел с помощью section
подробности атрибута здесь.