LMA与VMA总结

ldscript

ldscipt是gcc下的链接脚本, 顾名思义, 就是告诉别人, 这些代码该怎么链接.
链接就是,将多个目标文件合并为一个目标文件,称作可执行文件。
每个目标文件都包含一连串的section,最常见,最基础的至少有:
.text,代码段,就是CPU要运行的指令代码;
.data,数据段,程序中包含的一些数据,放在这个段里;
.bss,未初始化段,记录了程序里有哪些未初始化的变量,就相当于只记录对应的名字,留着程序运行前去初始化为0,所以,此处并不占用具体空间。

基本格式

section_name  vma : AT(lma)
  {
      output-section-command
    output-section-command
     ...
   } [AT>lma_region]

例如:

.text 0x30000000 : AT(0x40000000)
{
     *(.text)
}

表示的是代码的运行时地址为 0x30000000 。假如你的ROM在 0x0 地址,程序放在ROM中,那个时候程序是不能正常运行的(位置无关代码除外),必须将代码COPY到VMA也就是0x30000000 中才能正常运行。至于那个 AT(lma) 的关键字,只指示代码连接的时候应该放在什么地方,注意好这个英文是 load memory address,是指程序应该装载在什么地方。elf格式的文件里面不但包含了代码,还包含了各种各样的信息,例如上面说的每个段的lma和vma,还有其他信息都包含在里面了。默认状态下,lma 是等于当前的vma的.。但关键字AT指明了LMA。接下来就说说LMA和VMA是何方神圣了。

VMA

英文解释:
VMA(Virtual Memory Address):the address the section will have when the output file is run;
那啥是虚拟内存地址呢?就是你程序运行时,程序所在的地址。
此处所谓的虚拟,一般来说,指的是启用了MMU之后,才有了虚拟地址和实地址。
此处,我们可以简单的理解为,就是内存的实际地址即可。
程序运行前,要把程序的内容,拷贝到对应的内存地址处,然后才能运行的。

LMA

英文解释:
LMA(Load Memory Address): the address at which the section will be loaded. 因为我们知道程序运行前要经过:编译,链接,装载,运行等过程。装载到哪呢?没错,就是LMA对应的地址里。

LMA与VMA的区别

如果将程序运行比作吃饭,LMA就好比是厨房,食物需要在厨房准备好。VMA好比是餐厅,在餐厅享受食物。
大多数情况下,那么LMA和VMA是一样的,也就是,程序被加载到内存的什么地方,也就在什么地方运行。
不过也有特例,这里举一个嵌入式的例子,和一个我在写kernel中实际遇到的例子。

1. 嵌入式的例子

因为嵌入式系统中ram内存空间有限,所以一般把程序放在flash中。flash比较于ram写入速度较慢。但flash的空间容量大,所以人们想到将代码放到flash中(因为只读不写),把数据放在ram中,以节约资源。但在运行的时候,代码还是要出现在ram中,怎么办呢?就是将代码段的LMA设置为flash的地址,这样代码就会临时放在flash中,节约资源。等到需要运行的时候,再载入运行地址VMA中。所以这种情况下,VMA不等于LMA。

2. 自身实际遇到的例子

因为为了模仿linux的内核运行地址(从线性空间3GB以上地址运行),所以我的内核代码的运行地址也设为3GB,但是我是用GRUB加载内核代码的,GRUB要求的是要在0x100000开始加载。怎么办?就用VMA=3GB,LMA=grub
要求的地址。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值