背景: 闪存在0x02000000 / 2M,SDRAM在0x10000 / 16M,处理器:ks8695。
Bootloader和OS刻录到闪存中,复位时,OS复制到地址0x10000的SDRAM,然后将PC(程序计数器)设置为0x10000(即运行OS)。
由于PC设置为0x10000(因为处理器此时可以执行OS的第一条指令),为什么需要指定OS的文本部分的绝对地址(通过设置-Ttext = 0x10000)链接时呢? (当我将-Ttext设置为0x0时,操作系统将无法正常运行。)
致以最诚挚的问候,
wenlujon
答案 0 :(得分:1)
我认为您回答了自己的问题 - 系统中的RAM位于0x10000。执行代码的两种主流方式是存储和下载(SnD)和eXecute-in-place(XIP)。看起来你将代码存储在flash中并将其复制到RAM中。因此,二进制文件中的所有地址都必须用RAM起始地址进行偏移,否则它们在二进制文件中会出错。
如果您的闪存是NOR,那么技术上可以将其保留在NOR中并运行代码(XIP),尽管它可能不适合您的平台。
这有帮助吗?
答案 1 :(得分:0)
您的电脑处于0x10000,因此您必须将其链接到0x10000,因为您的代码正在进行绝对寻址。
引导加载程序没有进行任何链接或符号解析,它只是将一些二进制blob复制到0x10000,然后将PC设置为0x10000。所以你的代码必须准备好在0x10000运行,这就是你需要在链接器中指定它的原因。
函数调用通常使用PC相对寻址来完成,但是当您想要访问数据时,这不是必需的。假设您有一个表T.如果您在0x0处链接,并且您的表位于0x1234。您可能有一些指示该地址的指令。
现在您将代码移动到0x10000。你的表地址现在是0x11234,但你的代码现在没有被移动,所以它试图加载0x1234的数据,那里没有任何东西,或废话。
现在,当您将代码与偏移量链接时,用于访问T的指令集也会相应地进行修改。这就是链接的所有内容,将符号解析为地址!
答案 2 :(得分:0)
是的,绝对寻址是一个很好的理由,但第一条指令呢?它绝不应该与绝对寻址有关。
如果OS的第一条指令是0xe1a00000,则OS的偏移量0x10000处的指令为0xe3a01303。如果-Ttext设置为0x0,通过查看映射文件,我们在地址0x0处获得0xe1a00000,在地址0x10000处获得0xe3a01303(目标板中的CPU仍然根本不知道这一点!)。
当bootloader将操作系统复制到地址0x10000时,它会将0xe1a00000复制到0x10000,将0xe3a01303复制到0x20000(它们只是数据),我是对的吗? 然后将PC设置为0x10000,CPU应执行0xe1a00000,因为指令占用地址0x10000,但CPU实际执行0xe3a01303,地址为0x20000。