重定位一般有两个目的:
①、程序文件过大,这时候需要把超出储存器(NorFlash或SRAM)部分的代码,“放到”(也即重定位)SDRAM中去执行;
②、程序烧写在NorFlash并且使用了全局变量。
这篇文章着重解析第二个目的,对于第一个目的后续有时间再写。
如果你的程序是烧写在NorFlash中,并且程序里使用了全局变量(不包括静态全局变量,下同),那么你就需要重定位了。为什么?
因为:
①、全局变量是保存在程序文件里的
②、NorFlash可以像SRAM一样读数据,但是不能像SRAM简单地写数据
所以程序运行时可以读取这个全局变量,但是不能写这个全局变量,因为该全局变量储存在NorFlash里面。
这时候重定位就派上用场了,用通俗易懂地描述这个过程:
假设你的全局变量位于程序中0x800的位置,那么程序在使用这个全局变量前,就需要把所有的全局变量“映射”到SDRAM那边过去,包括全局变量的初始值都“映射”过去,然后后续程序使用这些全局变量的时候,全部都在SDRAM那边访问、读、写。
这里面就涉及到两个概念:
①、运行地址(又称链接地址、重定位地址、RunTimeAddress)
②、加载地址(又称储存地址、LoadAddress)
运行地址也即是程序运行时实际上所指向的地址,而加载地址指代码所保存的地址。
假设某个变量的:
运行地址=0x3000 0000
加载地址=0x800
那么就是该变量是储存在程序中0x800的位置,但是运行的时候,要访问的话,就要到0x30000000的地方去访问、读和写
所以我们的全局变量重定位时,就要把运行地址设置在SDRAM的地址(0x3000 0000),而加载地址并不固定,它紧随着程序.text段放置。
因此重定位涉及两个步骤:①、设置运行地址 ②、将值从加载地址复制到运行地址
以上是重定位的简单介绍