c - 在嵌入式目标上FLASH的m_text内存区域中保留内存空间

标签 c embedded bare-metal linker-scripts

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

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

固件、质数和引导加载程序分别编译,生成 3 个用于闪存的 .hex 文件。

假设固件代码从 0x2000 开始,长度为 0x2000,在该区域内我想分配一个 1024 字节的扇区,以后可以在不破坏固件的情况下删除和覆盖该扇区。

使用以下代码,我可以读取、删除数据并将数据写入闪存,但我有一些问题:

  1. 使用以下代码,gcc 会在 0x3000 处分配扇区吗?如果没有,怎么办?
  2. 您知道有更好的方法吗?

代码:

...
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 我必须使用链接器脚本。

来自here我读到了这个:

The special linker variable dot `.' always contains the current output location counter. Since the . always refers to a location in an output section, it may only appear in an expression within a SECTIONS command. The . symbol may appear anywhere that an ordinary symbol is allowed in an expression.

Assigning a value to . will cause the location counter to be moved. This may be used to create holes in the output section. The location counter may never be moved backwards.

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

In the previous example, the .text' section fromfile1' is located at the beginning of the output section output'. It is followed by a 1000 byte gap. Then the.text' section from file2' appears, also with a 1000 byte gap following before the.text' section from file3'. The notation= 0x1234' specifies what data to write in the gaps (see section Output section fill).

我的 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 的大小并填充到下一个 1024 字节扇区,以获得我们将导入到素数项目的地址。

我对扇区之前的填充也不太满意,在理想的情况下,我们会用“垃圾代码”或随机数据填充它,我已经看到你可以指定一个模式来填充,但任何一致的模式对于逆向工程师来说,会亮出 0xffffff 或 0x00000 ;)

还有更好的想法吗?

最佳答案

不确定您使用的是什么编译器,但使用 GCC,您可以使用 section 属性指定该部分 details here .

关于c - 在嵌入式目标上FLASH的m_text内存区域中保留内存空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30711729/

相关文章:

c - C中通过http POST发送二进制数据

c - 如何在 C 上将 64 位无符号整型与 32 位无符号整型相乘而不使用 long long?

c - 下面问题中的函数 f(a,b) 是什么意思?

node.js - 如何使用命令行刷新 NUCLEO F401RE

c - 缓冲区中帧的所有权 - C 编程

linux - 为什么从 https 服务器下载文件在带有 montavista linux 的嵌入式设备上不起作用?

c - 进入函数作用域但不在函数调用时指针参数为 NULL

c - 从文件中读取多个字符串

在树莓派裸机编程中创建 C 库 stub

sockets - 如何路由QEMU内部的TCP端口/套接字?