为什么要在静态链接中指定地址?
background: 在0x02000000/2M处闪烁,SDRAM在0x10000/16M处,处理器:ks8695。在复位时,将OS复制到地址0x10000处的SDRAM,然后将PC(程序计数器)设置为0x10000(即运行OS),将Bootloader和OS烧入闪存中。为什么要在静态链接中指定地址?
由于PC设置为0x10000(因为此时处理器可以执行OS的第一条指令),为什么需要指定OS的文本部分的绝对地址(通过设置-Ttext = 0x10000 )何时链接? (当我将-Ttext设置为0x0时,操作系统将无法正常运行)。
最好的问候,
wenlujon
你的电脑在0x10000,所以你必须在0x10000链接它,因为你的代码是在进行绝对寻址。
引导加载程序没有执行任何链接或符号解析,它只是将一些二进制blob复制到0x10000,然后将PC设置为0x10000。所以你的代码必须准备好在0x10000运行,这就是为什么你需要在链接器中指定它。
函数调用通常是使用PC相对寻址完成的,但当您想要访问数据时,并不是必需的。假设你有一个表T.如果你在0x0连接,并且你的表在0x1234。你可能有一些指向这个地址的指令。
现在您将您的代码移至0x10000。你的表地址现在是0x11234,但你的代码现在不会被移动,所以它试图在0x1234加载数据,没有任何东西或废话。
现在,当您将代码与偏移链接时,用于访问T的指令集相应地进行了修改。这就是所有链接的目的,将符号解析为adrresses!
我觉得你有点回答了你自己的问题 - 在你的系统中的RAM位于在0x10000。执行代码的两种主流方式是存储和下载(SnD)和就地执行(XIP)。好像你在闪存中存储代码并将其复制到RAM中。因此,二进制文件中的所有地址必须与RAM起始地址偏移,否则它们在二进制文件中将会出错。
如果您的闪存是NOR,您可以在技术上将其保留在NOR中,然后运行代码(XIP),尽管它可能不适合您的平台。
这有帮助吗?
是的,绝对寻址是一个很好的理由,但第一条指令呢?它不应该与绝对地址有关。
给定OS的第一条指令是0xe1a00000,OS的偏移量0x10000处的指令是0xe3a01303。如果通过查看映射文件将-Ttext设置为0x0,则我们在地址0x0处获得0xe1a00000,在地址0x10000处获得0xe3a01303(目标板中的CPU仍然不知道这一点!)。
当引导程序将操作系统复制到地址0x10000时,它会将0xe1a00000复制到0x10000和0xe3a01303到0x20000(它们只是数据),对吗? 然后将PC设置为0x10000,CPU应该执行0xe1a00000,因为指令占地址0x10000的地址为,但是CPU实际上执行的是地址0x20000的0xe3a01303。
- 由于0xe1a00000位于SDRAM的0x10000处,当PC设置为0x10000时,为什么CPU不执行0xe1a00000?
- CPU如何知道0xe3a01303被分配给0x10000,因为这项工作是由我的个人电脑中的链接器完成的?
这不是你在第一篇文章中描述的内容。没有更多关于你的引导程序的文档,很难说出发生了什么。 可能是有一个“重新映射”选项,这改变了ARM内存映射 – shodanex 2010-03-05 08:20:56
请注意我这篇文章和第一个之间的区别。 你是什么意思的“重映射”?是否有可能导致上面提到的怪异行为?谢谢。 – wenlujon 2010-03-05 10:40:42
答案是 1. CPU确实执行0xe1a00000; 2. GDB认为它执行0xe3a01303,这是错误的,因为-Ttext被设置为0x0而不是0x10000(支持)。 – wenlujon 2010-03-08 03:06:34
您应该编辑您的问题,并将您的答案放在问题中,以便阅读。 – shodanex 2010-03-08 08:58:52
你的答案在下面是一个好的,其他人可以参考它。 – wenlujon 2010-03-09 14:10:04