C 在嵌入式目标闪存的m_文本存储区域中保留存储空间

C 在嵌入式目标闪存的m_文本存储区域中保留存储空间,c,embedded,bare-metal,linker-scripts,C,Embedded,Bare Metal,Linker Scripts,我有一个微控制器,有很多闪存,分为1k闪存扇区。 我想在闪烁期间将素数闪烁到一个特定的内存区域,然后在第一次引导期间将生成一个加密密钥,然后素数将被擦除和覆盖 我更喜欢将素数隐藏在m_文本中,而不是使用链接器脚本为素数创建读/写内存区域 固件、素数和引导加载程序分别编译,生成用于闪存的3.hex文件 假设FW代码从0x2000开始,长度为0x2000,在该区域内,我想分配一个1024字节的扇区,以后可以在不阻塞FW的情况下擦除和覆盖该扇区 使用以下代码,我可以读取、擦除和写入闪存中的数据,但我有

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

我更喜欢将素数隐藏在m_文本中,而不是使用链接器脚本为素数创建读/写内存区域

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

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

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

  • 使用以下代码,gcc是否将扇区分配到0x3000?如果没有,怎么做
  • 你知道更好的方法吗 代码:

    链接器脚本

    MEMORY {
      ...
      m_text(rx): ORIGIN = 0x00002000, LENGTH = 0x2000
      ...
    }
    
    更新: 我必须使用GCC在给定的闪存地址上预留空间,其他编译器对此有解决方案,但使用GCC我必须使用链接器脚本

    我从中读到:

    特殊链接器变量点“.”始终包含当前输出 位置计数器。从那以后。始终引用输出中的位置 节中,它只能出现在节中的表达式中 指挥部。这个符号可以出现在普通符号所在的任何位置 在表达式中允许

    给…赋值。将导致位置计数器移动。 这可用于在输出截面中创建孔。地点 计数器不能向后移动

    在上一个示例中,file1'中的
    .text'部分位于
    在输出部分的开头
    output'。然后是一个
    1000字节的间隔。然后,
    file2'中的
    .text'部分也会出现 在中的
    .text”部分之前有1000字节的间隙
    file3'。符号
    =0x1234'指定要在中写入的数据 间隙(请参见“输出”部分“填充”)

    我的m_文本部分如下所示:

      .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
    
    现在我们在闪存上保留了数据,但地址将取决于的大小。文本的大小并不理想,但是,如果我们将FW代码中的直接寻址改为节名,然后将.text的大小从FW项目和padd移到下一个1024字节的扇区,以获得我们将导入素数项目的地址,那么这可能会起作用

    我对扇区之前的填充也不太满意,在一个理想的世界中,我们会用“垃圾代码”或随机数据填充它,我已经看到您可以指定填充的模式,但任何一致的模式都会在逆向工程中亮起0xffffff或0x00000;)


    有更好的主意吗?

    您可以使用gcc
    \uu属性((section(“m\u text”))
    将数组定位到
    m\u text
    部分

    内存区域不是节。因此,您需要将此节添加到链接器脚本中,将其放入此内存区域(不确定,如果两者使用不同的名称空间,但最好为区域和节使用不同的名称)。如果该程序未加载,则必须是
    NOLOAD
    (很像
    .bss


    或者只使用C构造,而根本不使用链接器工具。但是,这将阻止数据随程序加载,因此只有当您打算将该区域与程序分开编程时,它才起作用。

    不确定您使用的编译器是什么,但对于GCC,您可以使用
    section
    属性指定该节。

    质数和引导加载程序是分开编译的,产生用于闪存的3.hex文件。@Maidenone:那么我要么使用C-only方法,使用转换为实际类型的绝对地址(很像外围寄存器-您可以使用
    const
    来防止意外写入),要么使用
    NOLOAD
    方法。但是我如何控制内存分配的位置呢?假设程序从0开始,长度为200,我希望在不覆盖程序数据的情况下将素数设置为50。@MaideOne:您必须更改程序的闪存区域,以排除保留(m_文本)区域。最好的建议是对数组/表使用最上面的扇区,对程序使用最下面的所有扇区,反之亦然(对于ARM,最好保留较低的两个扇区,因为ARM希望其重置向量位于较低的1/2字处)。请注意,如果要从引导加载程序中分别擦除/写入表,则每个表都需要一个单独的扇区。@Maidenone:请注意,您不分配,而是保留该区域。这是一个很小但很重要的区别。类似的问题。
      .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