【发布时间】:2020-06-08 04:01:28
【问题描述】:
我正在尝试构建和链接单个图像以作为 OS 内核(即在 QEMU 中)加载,目标是 aarch64-unknown-none-softfloat。我使用了一个自定义的 linker.ld 文件,它为内核 ENTRY(_reset) 设置入口点并定位图像
. = 0x40080000
程序计数器 (PC) 处于复位状态的位置。
在我将 0x40080000 处的页面映射到内核将驻留的高内存并启用虚拟内存转换之前,它工作正常。为了保证切换后调试信息网格化,我将标称图像位置改为
. = 0xffffff8200000000
然后重建。
我发现了访问权限:
- 到一些(pub extern)静态,和
- 某些核心库函数
是通过从.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 重定位的代码,以保证代码和数据将相隔一定距离..
【问题讨论】:
标签: rust linker arm64 bare-metal position-independent-code