为什么要有VMA和LMA两个地址?

这个问题我困扰了好久,做lab1的实验中,那个关于VMA和LMA的描述让我很是迷惑。

今天看LD链接器的说明书info ld, 这里Basic Linker Script Concepts(3.1)节中写道:

We need to define some basic concepts and vocabulary in order todescribe the linker script language.

The linker combines input files into a single output file. The outputfile and each input file are in a special data format known as anobject file format. Each file is called anobject file. The output file is often called anexecutable, but for ourpurposes we will also call it an object file. Each object file has,among other things, a list ofsections. We sometimes refer to asection in an input file as aninput section; similarly, a sectionin the output file is anoutput section.

Each section in an object file has a name and a size. Most sectionsalso have an associated block of data, known as thesectioncontents. A section may be marked asloadable, which mean thatthe contents should be loaded into memory when the output file is run. A section with no contents may beallocatable, which means that anarea in memory should be set aside, but nothing in particular should beloaded there (in some cases this memory must be zeroed out). A sectionwhich is neither loadable nor allocatable typically contains some sortof debugging information.

Every loadable or allocatable output section has two addresses. Thefirst is theVMA, or virtual memory address. This is the addressthe section will have when the output file is run. The second is theLMA, or load memory address. This is the address at which thesection will be loaded. In most cases the two addresses will be thesame. An example of when they might be different is when a data sectionis loaded into ROM, and then copied into RAM when the program starts up(this technique is often used to initialize global variables in a ROMbased system). In this case the ROM address would be the LMA, and theRAM address would be the VMA.


这里面红色部分提到了为什么会有两个地址VMA和LMA, 但是就一句话,我还是没看明白。
http://bbs.sjtu.edu.cn/bbstcon?board=C&reid=1234969508中给出的原因也与上面相同。
后来看了http://hi.baidu.com/armking_home/blog/item/ba428c35b470fdabd1a2d372.html中对于加载器的定义:

Loader,装载器的作用:
1。从二进制文件中读出对应的段的信息,比如text,data,bss等段的信息,
将内容拷贝到对应的LMA的地址处。此谓,装载(对应内容)到装载地址(LMA)。
2。如果发现VMA!=LMA, 即 程序运行时候的地址,和刚刚把程序内容拷贝到的地址LMA,两者不一样,
那么就要把对应的内容,此处主要是data,数据段的内容,从刚刚装载到的位置,LMA处,拷贝到VMA处,
这样,程序运行的时候,才能够在执行的时候,找到对应的VMA处的变量,才能找到对应的值,程序才能正常运行。

一般情况下是LMA = VMA,只有小数情况是不相等:
CPU 从ROM,比如常见的NorFlash中读取代码的速度,要远远小于从RAM,比如常见的SDRAM,中读取的速度,所以,才会牵扯到将代码烧写到ROM 里面,然后代码的最开始,将此部分程序reaload,重载,也就是从此处的ROM的地址,即LMA,重新拷贝到SDRAM中去,也就是VMA的地方,然后从那里运行。
我想我应该明白了为什么要有VMA和LMA两个地址,以及为什么JOS中,kernel的两个地址不一致,而boot的两个地址一致了。

为什么需要VMA和LMA两个地址?
首先在嵌入式系统中,我们考虑ROM与RAM是共享地址空间的。这样我们可以把一些初始化的值先烧到ROM中(处于保密或其他目的,我猜得^__^),我们设定LMA为ROM的地址,VMA为内存的地址。程序在内存中执行时,是根据VMA地址来执行的,也就是PC指针使用的是VMA地址空间。Loader下载程序时,Loader先将某些块程序拷贝到ROM,但由于ROM只读,所以ROM的值不会变。接着比较LMA和VMA,如果不相等,则把LMA处的内容拷贝到VMA所指向的位置,这样就把ROM处的值拷贝到了 RAM.相当于将某些的变量给下附初值了。

为什么boot两个地址一样,但kernel中LMA和VMA两个地址不一样呢?
boot执行时,没有虚拟地址的概念,也没有嵌入式中的ROM,所以boot中两个地址一样。
操作系统kernel一般运行在虚拟地址空间的高地址位,但是实际物理很存很小,boot在实模式下工作,所以boot只能将kernel加载到物理内存的某个位置,这个位置的地址肯定与kernel要运行在的虚拟地址空间的地址不一致。这造成了天然的LMA与VMA的不一致。这种情况与前面提到的嵌入式开发中遇到的情况不一样,但是LMA与VMA两个地址就能解决这两种需求的问题。
ROM使用cpu地址空间,所以必须考虑LMA=VMA的问题,因为ROM只读,不能写,也就是不能在ROM上执行。

回头再来看Loader的作用,就发现前面提到的loader的作用并不正确。上面所说的loader的作用仅是只ROM情况时loader应该具有的功能。其实loader不是都实现这样的功能。JOS中,boot 也是一个Loader,它就没有实现上面定义的功能。Loader的具体功能还要看具体的实现,但大体上实现的都是加载程序,让程序运行。

2012.6.30

其他:flash可以使用CPU地址空间,也可以作为I/O挂载在总线上。当flash较大时,CPU地址线不够用,就挂载在总线上。
            nor型flash按字节读取,支持程序在片内部运行,不必读到Ram中去。Nand型flash是按块读取的。
2012.8.16

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值