我有一个微控制器,闪存分为1k个闪存扇区。 我希望在闪存期间将素数闪存到特定的存储区域,然后在第一次启动期间将生成加密密钥,然后将删除和覆盖素数。
我更希望隐藏m_text中的素数,而不是使用链接描述文件为素数创建读/写内存区域。
固件,素数和引导程序分别编译,产生3个用于闪存的.hex文件。
假设FW代码从0x2000开始并且它是0x2000长,在该区域内我想分配一个1024字节的扇区,以后可以擦除和覆盖,而不会使FW变砖。
使用以下代码,我可以读取,擦除和写入闪存数据,但我有一些问题:
代码:
...
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我读到了这个:
特殊链接器变量dot`。'始终包含当前输出 地点柜台。自从。始终指的是输出中的位置 部分,它可能只出现在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
现在我们已经在flash上保留了数据,但地址将取决于.text的大小并不理想,但是如果我们从FW代码中的直接寻址更改为节名称然后取从FW项目和padd到。下一个1024字节扇区的.text大小,以获取我们将导入Prime数字项目的地址。
我对扇区之前的填充也不太满意,在一个理想的世界中,我们会用#"垃圾代码"或随机数据,我已经看到你可以指定一个模式来填充,但任何一致的模式将向反向工程师发出高达0xffffff或0x00000;)
任何更好的想法?
答案 0 :(得分:1)
您可以使用gcc cat
将数组定位到m_text
部分。
内存区域不是一个部分。因此,您需要将此部分添加到链接器脚本,将其放入此内存区域(不确定,如果两者都使用不同的命名空间,但为区域和节具有不同的名称将是更好的样式)。如果未加载该程序,则必须为__attribute__((section("m_text") ))
(非常类似于NOLOAD
)。
或者您只使用C构造而根本没有链接器。但是,这会阻止数据加载程序,因此只有在打算从程序中单独编程该区域时才能正常工作。
答案 1 :(得分:1)
不确定您使用的编译器,但使用GCC,您可以指定section
属性details here的部分。