VMA:Virtual Memory Address 虚拟地址,即运行地址。指代码真正运行起来的空间,可以是flash区也可以是SRAM区。
LMA:Load Memory Address 加载地址,一般是flash区,因为SRAM掉电数据会丢失。但调试的时候例外,因为SRAM调试时,可以将所有代码加载到SRAM区执行。
下面通过几个Q&A来说明两者。
Q:什么时候VMA和LMA相同?
A:比如,代码段会下载到flash中,程序也从flash区中取址、译码、执行。
Q:什么时候VMA和LMA不同?
A:对于.rodata 或者.text段,代码下载到flash中,但是出于对速度的要求,需要程序在SRAM中运行。此时LMA=flash地址,VMA=SRAM地址。
对于.data, .bss段,VMA和LMA肯定是不一样的。所以ld文件中一般可以看到
Q:谁负责把代码从LMA中搬到VMA中?
A:脱离调试环境的情况下,都是用户代码来实现代码搬移。在APT系列芯片的驱动中,通常有一个mem_init.c,里面的main()函数就是用来实现data段数据从flash搬移到sram中的。 但是在调试环境下要看IDE,有些IDE,会根据ld文件自动加载SRAM。
Q:既然代码搬移是用户程序完成的,那为什么要告诉编译器LMA和VMA不同呢?
A:以变量来举例。假如一个芯片,如APT32F102x系列,flash区是0x0000~0xffff,sram区是0x20000000~0x20000fff。 一个有初值的变量a (.data段),它的VMA一定只能在SRAM区,因为要可以读写,假设VMA = 0x20000010;而LMA一定在flash中,因为芯片下电时初始值不能丢,假设LMA = 0xfff0。 那么在程序执行的时候,这个变量地址应该是什么呢?0x20000010。这个信息就是VMA告诉编译器的。而0xfff0应该是main()函数memery copy的一部分。