在嵌入式目标上FLASH的m_text内存区域预留内存空间



我有一个微控制器,其中有许多闪存分为1k闪存扇区。我想在闪烁期间将素数闪存到特定的内存区域,然后在第一次启动期间将生成一个加密密钥,然后素数将被擦除和覆盖。

我更愿意隐藏质数在m_text中,而不是用链接器脚本为质数创建一个读写内存区域。

固件,素数和引导加载程序分别编译,导致用于flash的3 .hex文件。

假设FW代码从0x2000开始,它是0x2000长,在该区域内,我想分配一个1024字节的扇区,以后可以擦除和覆盖而不阻塞FW。

使用以下代码,我可以读取,擦除和写入数据到闪存,但我有一些问题:

    下面的代码将gcc分配扇区在0x3000?如果不是,怎么做?
  1. 你知道更好的方法吗?
代码:

...
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在给定的flash地址保留空间,似乎其他编译器对此有解决方案,但与GCC一起,我必须使用链接器脚本。

从这里我读到这个:

特殊的链接器变量点'。'总是包含当前输出位置计数器。自从。总是指输出中的一个位置section中,它只能出现在section中的表达式中命令。的。符号可以出现在普通符号所在的任何地方

赋值给。将导致位置计数器被移动。这可以用来在输出部分创建孔洞。的位置计数器不能向后移动。

SECTIONS
{
  output :
    {
      file1(.text)
      . = . + 1000;
      file2(.text)
      . += 1000;
      file3(.text)
    } = 0x1234;
}

在前面的示例中,定位了.text' section from文件e1'在输出部分的开头,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代码中的直接地址更改为节名,然后从FW项目中获取。text的大小,并添加到下一个1024字节扇区,以获得我们将导入到素数项目的地址,则可能会起作用。

我对扇区之前的填充也不太满意,在理想的世界里,我们会用"垃圾代码"或随机数据填充它,我已经看到你可以指定一个模式来填充,但是任何一致的模式都会像0xffffff或0x00000一样发光到逆向工程师;)

有更好的主意吗?

不确定您使用的是哪种编译器,但使用GCC,您可以在这里指定section属性详细信息的部分

您可以使用gcc __attribute__((section("m_text") ))将数组定位到m_text部分。

一个内存区域不是一个section。因此,您需要将该部分添加到链接器脚本中,并将其放入该内存区域(不确定,如果两者使用不同的名称空间,但是为区域和部分使用不同的名称会更好)。如果它没有加载到程序中,它必须是NOLOAD(很像.bss)。

或者你只使用C结构而不使用链接器。但是,这将阻止数据与程序一起加载,因此只有当您打算将该区域与程序分开编程时才有效。

最新更新