重用代码存储器来存储数据

hen*_*rik 13 c embedded gcc ld

我有一些在内存有限的系统上运行的C代码.代码执行基本上有两个阶段,即启动阶段和主阶段.启动阶段包括生成主阶段使用的一些参数的代码.在主要阶段期间生成数据.

由于启动阶段只运行一次,我想在主阶段重用启动代码用于数据存储的内存空间.

我已经测试了一种方法来处理这个:

  • 自定义链接描述文件,将与启动阶段关联的代码和数据放在.startup部分中.此部分与.bss放在同一地址,即主阶段使用的bss部分.
    启动代码调用启动阶段的入口点,当它返回时,在主阶段调用main之前,它会清除.bss部分.
    Xrossref命令在链接描述文件中用于帮助将代码和数据放到正确的位置.

这有效,但它有它的怪癖.要获取.startup部分中的启动代码和数据,我必须在编译期间使用gcc给出的输入节名称列出它们.

现在我想启用lto(链接时间优化),并且由于输入节名称已更改,因此会破坏上述方法.

考虑测试新方法:

  • 将启动代码和主代码构建为两个独立的程序.每个程序都是单独构建和优化的,并组合成一个引导映像.
    优点是主代码不会调用意外放置在启动部分中的函数(执行主代码时不再存在).另一个优点是我只需要为每个阶段指定入口点,链接器将完成剩下的任务,找出该阶段所需的代码和数据.
    从启动输出并由main使用的参数数据可以放置在公共bss部分或堆栈中.

缺点是我无法看到启动代码和主代码如何共享两个阶段中使用的功能.如果共享函数很小,尝试共享它们可能是一个坏主意,因为lto将受到更多限制或最终内联两个版本的共享函数.

有没有人知道这个的首选方法或对新建议的方法有任何评论?

Jim*_*ion 1

我见过的方法(Rabbit 处理器)是使用覆盖层。[涉及到一些硬件,所以我不确定这个类比是否完美。]无论如何,[在我看来]这个概念就像电梯。您拥有少量的程序空间(电梯轿厢),该空间始终安全且可行。但是,如果您想访问另一个“楼层”,您可以返回电梯(PC 位于那个小地址空间中),然后切换设置以激活另一组内存。然后您可以退出电梯并到达新楼层。

您的问题略有不同(想要使用更少的内存而不是没有足够的地址线),但可以应用相同的策略。

从电梯开始。运行第一个启动代码,该代码设置某些数据值,也可能在安全区域中。退回电梯。覆盖启动代码空间。现在您可以退出电梯了。但您仍然需要新空间的地址。这些需要存储在某个地方。也许您有两组具有重叠地址的函数指针,一组用于启动,另一组用于主代码。只需在正确的时间使用正确的功能即可。