编译时的加载地址是在RAM中复制可执行文件的地方吗?

时间:2013-09-10 07:36:11

标签: c bootloader

我正在尝试编写自己的加载程序。在这个程序中,我将程序复制到RAM中的特定地址,并通过读取精灵的入口点跳转到入口点地址。但是,我无法理解装载程序地址是什么?这是否意味着只需要在编译时指定的加载器地址复制二进制文件。我不能在其他位置加载程序而不是在编译时指定的加载地址?我的基本问题如下:“我不能在其他位置加载程序而不是在编译时指定的加载地址吗?”

3 个答案:

答案 0 :(得分:1)

正。

完全链接的ELF程序不包含重定位信息,这些信息允许您在将程序加载到其他地址后修复引用。

使用链接器的-Ur选项(或适当的链接描述文件),可以生成带有重定位的ELF文件 - 为这些编写加载器更加困难。

答案 1 :(得分:1)

你是否正在瞄准ARM?

您的问题的解决方案是PIC / PIE(位置无关代码/可执行文件)。这样,程序编译如下:

  • 任何函数内跳转都是相对的(如ifs,case,loops等)
  • 使用GOT(全局偏移表)
  • 以两个步骤间接进行任何段内跳转
  • 截面间跳转是相对的或间接的,具体取决于链接器参数“long-jumps”
  • 使用GOT间接进行任何全局数据访问

这样,程序在代码中的任何地方都不包含绝对地址。它在代码中也没有重定位。唯一需要的重新安置就是放置GOT本身。

GOT是一个包含所有全局对象,函数和数据的地址的表。在非PIC代码中,数据的绝对地址直接嵌入代码中。该函数需要知道GOT表地址和GOT表中与特定对象相对应的条目号。对象编号是PIC代码中嵌入的唯一内容。 GOT地址通过我遇到的两种方式之一呈现给函数:附加在函数体末端或预定义CPU寄存器中的重定位。我发现后一种选择更好。

如果您的程序最初加载了内存映射ROM,并且您希望将其复制到RAM中以加快速度并允许修改数据,那么PIC非常有用。

请注意,您可以在没有PIC的情况下完成上述所有操作,这只是更麻烦。您将在代码内部进行大量重定位(如果PIC移动函数代码只是一个简单的memcpy),您必须立即复制所有数据块(正确编写的PIC可执行文件允许在不同的位置移动单个对象)记忆区域。)

如果您很好奇,那么我可以向您发送一些用于ARM体系结构的链接描述文件。

答案 2 :(得分:0)