链接脚本;向内存区域添加偏移量;
Linker script; add offset to memory region;
很快,我需要的是一个接一个地放置。尽管这些部分应该位于不同的虚拟地址空间中,但存在一个问题。
详细:
有两段代码。一个部分(引导)在禁用 MMU 的情况下工作,应该链接以便虚拟地址和物理地址相同。另一个部分在启用 MMU(应用程序)并且虚拟地址与物理地址发生偏移时工作。
物理上两个部分应该一个接一个地放置。
这是我正在努力处理的链接描述文件的一部分
MEMORY {
DDR_MEMORY : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
APP_VMA : ORIGIN = 0xFF002000, LENGTH = 0xFFFFFF
BOOT_LMA : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
}
SECTIONS
{
.boot : {
*(.startup)
} >BOOT_LMA AT>DDR_MEMORY
.app : {
*(.text)
*(.text*)
} >APP_VMA AT>DDR_MEMORY
}
结果是:
假设 'startup' 代码是 0x5C 字节。所以引导部分链接为 0x2000 - 0x205C 虚拟和物理。
应用程序代码应该在引导部分后面,我希望它位于 0xFF002060(虚拟)和 0x2060(物理)。但是 APP_VMA
我得到的是 0xFF002000 (没有 0x60 偏移量),物理位置是 0x2060 (这是预期的)。
所以问题是如何将偏移量添加到 APP_VMA 以获得与物理地址匹配的虚拟地址(例如 0xFF002060)?
谢谢。
PS:我使用的是 clang 链接器,但很确定这也适用于 gcc。
很快,解决方案是添加一个 'phony' 部分来增加 APP_VMA
和 DDR_MEMORY
链接器计数器。
我添加了一个大小为 'boot' 的新节,该节增加了链接器计数器并强制链接器将 'app' 放置在正确的虚拟地址 space 中,并且物理上位于引导节之后。
MEMORY {
DDR_MEMORY : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
APP_VMA : ORIGIN = 0xFF002000, LENGTH = 0xFFFFFF
BOOT_LMA : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
}
PHDRS
{
mmu_on PT_LOAD;
no_mmu PT_LOAD;
}
SECTIONS
{
.boot : {
*(.startup)
_boot_sizeof = SIZEOF(.boot);
} >BOOT_LMA : no_mmu
.boot_phony : {
. += _boot_sizeof ;
/* Reserve a space to adjust counters APP_VMA and DDR_MEMORY */
} >APP_VMA AT>DDR_MEMORY :no_mmu
.app : {
*(.text)
*(.text*)
} >APP_VMA AT>DDR_MEMORY : mmu_on
}
很快,我需要的是一个接一个地放置。尽管这些部分应该位于不同的虚拟地址空间中,但存在一个问题。
详细: 有两段代码。一个部分(引导)在禁用 MMU 的情况下工作,应该链接以便虚拟地址和物理地址相同。另一个部分在启用 MMU(应用程序)并且虚拟地址与物理地址发生偏移时工作。
物理上两个部分应该一个接一个地放置。
这是我正在努力处理的链接描述文件的一部分
MEMORY {
DDR_MEMORY : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
APP_VMA : ORIGIN = 0xFF002000, LENGTH = 0xFFFFFF
BOOT_LMA : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
}
SECTIONS
{
.boot : {
*(.startup)
} >BOOT_LMA AT>DDR_MEMORY
.app : {
*(.text)
*(.text*)
} >APP_VMA AT>DDR_MEMORY
}
结果是: 假设 'startup' 代码是 0x5C 字节。所以引导部分链接为 0x2000 - 0x205C 虚拟和物理。
应用程序代码应该在引导部分后面,我希望它位于 0xFF002060(虚拟)和 0x2060(物理)。但是 APP_VMA
我得到的是 0xFF002000 (没有 0x60 偏移量),物理位置是 0x2060 (这是预期的)。
所以问题是如何将偏移量添加到 APP_VMA 以获得与物理地址匹配的虚拟地址(例如 0xFF002060)?
谢谢。
PS:我使用的是 clang 链接器,但很确定这也适用于 gcc。
很快,解决方案是添加一个 'phony' 部分来增加 APP_VMA
和 DDR_MEMORY
链接器计数器。
我添加了一个大小为 'boot' 的新节,该节增加了链接器计数器并强制链接器将 'app' 放置在正确的虚拟地址 space 中,并且物理上位于引导节之后。
MEMORY {
DDR_MEMORY : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
APP_VMA : ORIGIN = 0xFF002000, LENGTH = 0xFFFFFF
BOOT_LMA : ORIGIN = 0x00002000, LENGTH = 0xFFFFFF
}
PHDRS
{
mmu_on PT_LOAD;
no_mmu PT_LOAD;
}
SECTIONS
{
.boot : {
*(.startup)
_boot_sizeof = SIZEOF(.boot);
} >BOOT_LMA : no_mmu
.boot_phony : {
. += _boot_sizeof ;
/* Reserve a space to adjust counters APP_VMA and DDR_MEMORY */
} >APP_VMA AT>DDR_MEMORY :no_mmu
.app : {
*(.text)
*(.text*)
} >APP_VMA AT>DDR_MEMORY : mmu_on
}