【问题标题】:Is the load address at compile time the place to copy the executable in RAM?编译时的加载地址是在 RAM 中复制可执行文件的地方吗?
【发布时间】:2013-09-10 07:36:10
【问题描述】:

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

【问题讨论】:

    标签: c bootloader


    【解决方案1】:

    没错。

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

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

    【讨论】:

    • 我的基本问题如下,“我不能将程序加载到其他位置而不是编译时指定的加载地址吗?”
    • 基本的答案是“加载后不修复引用”。
    【解决方案2】:

    你有没有机会瞄准 ARM?

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

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

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

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

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

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

    如果你好奇,那么我可以给你发一些我的 ARM 架构的链接器脚本。

    【讨论】:

    • 是的,请发送。这会很有帮助。
    • 给我一些联系方式,好吗?或者尝试给我发邮件:(haael@interia.pl)。
    • 我的联系人是 shreyasjoshi11@gmail.com
    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多