我正在尝试构建和链接单个图像以加载为针对 aarch64-unknown-none-softfloat 的 OS 内核(即在 QEMU 中)。我使用一个自定义的 linker.ld 文件来设置内核的入口点ENTRY(_reset)
并定位图像
. = 0x40080000
其中程序计数器 (PC) 处于复位状态。
它工作正常,直到我将 0x40080000 的页面映射到内核将驻留的高内存并启用虚拟内存转换。为了保证切换后调试信息网格,我将标称图像位置更改为
. = 0xffffff8200000000
并重建。
我发现了访问:
- 到一些(酒吧外部)静态,和
- 通过某些核心库函数
是通过从.rodata
. 这在映射之前运行时会破坏代码。如果我把它改回来,它会在我映射后运行它时破坏代码。
它生成的代码在 O1 看起来有点像这样(间接通过 PC 相关页面):
adrp x0, 0x10000 // page offset from PC up to rodata
add x0, 0x120 // byte offset from page in rodata
ldr x0, [x0] // use as address
我需要的是真正跨代码和数据定位独立代码,以便它可以在内存中的两个位置工作,而无需引用任何存储的绝对地址,即使这些地址相对于 PC 可用。
我已经尝试过其他重定位模型,包括 Pic 和 RopiRwpi,但我看不到它生成不同的代码。
谢谢!
编辑:非常感谢临时映射的建议。我见过用的。我更感兴趣的编译器选项将使 -no-dynamic-linker 能够工作,避免生成需要 R_AARCH64_ABS64 重定位的代码,以保证代码和数据将相隔一定距离。