首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是什么决定了内存重映射操作后的位置独立性?

是什么决定了内存重映射操作后的位置独立性?
EN

Stack Overflow用户
提问于 2020-03-30 18:45:28
回答 1查看 112关注 0票数 2

我已经开始阅读Miro Samek的用GNU建造裸金属臂系统,并发现自己被困在了一个特定的点上。造成我困惑的原因出现在PDF第10页的注释中:

注意:函数low_level_init()可以使用C/C++编码,但有以下限制。函数必须在ARM状态下执行,它不能依赖于.data节的初始化或.bss节的清除。此外,如果要执行内存重映射,则必须在low_level_init()函数中执行,因为在此函数返回后,代码不再与位置无关。

代码“不再独立于位置”到底是怎么回事?似乎引用的代码(可在PDF的第7-9页上查看)在从low_level_init / _cstartup标签返回后仍然是独立的。_cstartup标签之后的说明唯一不同之处是,它们引用了链接器脚本中定义的标签(指南第3节)。

那么,重新映射究竟如何影响它后面的指令是否与位置无关?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-30 22:31:25

位置无关是一个负载时间概念,而不是运行时概念。位置无关是一种代码质量,它允许将其加载到内存中的任何地址,并且仍然可以工作,但是位置无关并不是运行程序的质量。

一旦我们有了引用代码的调用堆栈和/或(重新定位)数据,我们就不再具有代码或数据的位置独立性,并且无法移动它们。实际上,当程序开始执行时(尽管位置无关代码),位置独立性就消失了。

这两个返回地址--通过调用(例如BL)动态生成--以及指向代码的数据指针(代码指针向量(在vtable中),以及初始化的全局函数指针)破坏正在运行的程序的位置独立性。

作者的警告节点是描述位置独立性消失的一种方式。更令人困惑的是,通过非常仔细的操作,即使代码的执行已经开始,它们仍然允许实际移动代码,因此,在执行开始后,位置独立性实际上会持续一些小的时间。

但是一个程序不能正常工作(例如,调用和使用函数指针)而不放弃位置独立性,因此他们选择在low_level_init的末尾画一条线。

例如,reset代码需要很长的时间来使用非标准调用来调用low_level_init --在不使用BLmov lr,pc的情况下为其提供lr值(这将捕获cstartup的预映射(ROM)地址。) lr值提供的是low_level_init将“返回”的(重新定位的) cstartup地址!

代码语言:javascript
复制
    (10) LDR r0,=_reset /* pass the reset address as the 1st argument */
    (11) LDR r1,=_cstartup /* pass the return address as the 2nd argument */
    (12) MOV lr,r1 /* set the return address after the remap */
    (13) LDR sp,=__stack_end__ /* set the temporary stack pointer */
    (14) B low_level_init /* relative branch enables remap */
_cstartup:

BMOV lr,r1相结合的调用就是调用。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60937370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档