VMA vs LMA?

Started by dspfun August 29, 2007
Hi!

What is the difference between VMA (Virtual Memory Address) and LMA
(Load Memory Address)?

The Gnu ld documentation has the following explanation:
"Every loadable or allocatable output section has two addresses. The
first is the VMA, or virtual memory address. This is the address the
section will have when the output file is run. The second is the LMA,
or load memory address. This is the address at which the section will
be loaded. In most cases the two addresses will be the same. An
example of when they might be different is when a data section is
loaded into ROM, and then copied into RAM when the program starts up
(this technique is often used to initialize global variables in a ROM
based system). In this case the ROM address would be the LMA, and the
RAM address would be the VMA. "

In the above, "who" copies the data section from ROM to RAM? Isn't
this the same as when a program that is started from a shell is copied
from the harddrive to RAM by a loader, i.e. normal procedure?

As far as I have understood things the loader loads the executable
into RAM (from secondary storage) and then execution starts. So to me
the address of a section when it is run (VMA) is the same as the
address to where the section is loaded (LMA)?

If a section can be loaded to one address and then moved to another
section when run, who then moves the section from the load address
(LMA) to the run address (VMA)?

When is the LMA referenced (and by who) and when is the VMA referenced
(and by who)?

BRs!

dspfun wrote:
> Hi! > > What is the difference between VMA (Virtual Memory Address) and LMA > (Load Memory Address)? >
Your quotation from the ld documentation explains that pretty well, I thought.
> The Gnu ld documentation has the following explanation: > "Every loadable or allocatable output section has two addresses. The > first is the VMA, or virtual memory address. This is the address the > section will have when the output file is run. The second is the LMA, > or load memory address. This is the address at which the section will > be loaded. In most cases the two addresses will be the same. An > example of when they might be different is when a data section is > loaded into ROM, and then copied into RAM when the program starts up > (this technique is often used to initialize global variables in a ROM > based system). In this case the ROM address would be the LMA, and the > RAM address would be the VMA. " > > In the above, "who" copies the data section from ROM to RAM? Isn't > this the same as when a program that is started from a shell is copied > from the harddrive to RAM by a loader, i.e. normal procedure? >
No, these are different situations. When an OS loads code from a file, the OS does the copying. Usually the VMA and LMA are the same, so that the OS loads the initialised data section directly into place. With a ROM'ed program, where the program is run directly from the ROM rather than being first copied into RAM (in which case you have the same situation as an OS and a file), the code at the beginning of the program copies the data across and also clears the bss - this is part of the crt0 startup code.
> As far as I have understood things the loader loads the executable > into RAM (from secondary storage) and then execution starts. So to me > the address of a section when it is run (VMA) is the same as the > address to where the section is loaded (LMA)? >
That is the case *if* the program is copied into RAM before running.
> If a section can be loaded to one address and then moved to another > section when run, who then moves the section from the load address > (LMA) to the run address (VMA)? > > When is the LMA referenced (and by who) and when is the VMA referenced > (and by who)? >
See above.
> BRs! >
On Aug 29, 7:19 am, David Brown <da...@westcontrol.removethisbit.com>
wrote:

> ROM'ed program, where the program is run directly from the ROM rather > than being first copied into RAM (in which case you have the same > situation as an OS and a file), the code at the beginning of the program > copies the data across and also clears the bss - this is part of the
The other place where it's common to see VMA != LMA (and code that cares about the difference) is when initializing the MMU. You may have code that's physically contiguous across a block of LMAs, but the first few bytes set up the MMU and execution then passes to a new VMA.
Thanks for your response!

So, the program is always linked with the VMA addresses, and never
linked with LMA addresses? Or how are references to LMA/VMA sections
resolved?

When writing a program where one wants different LMA and VMA sections
the programmer himself/hersel has to make sure he/she writes the code
that copies the LMA section/data to its appropriate VMA address?


> No, these are different situations. When an OS loads code from a file, > the OS does the copying. Usually the VMA and LMA are the same, so that > the OS loads the initialised data section directly into place. With a > ROM'ed program, where the program is run directly from the ROM rather > than being first copied into RAM (in which case you have the same > situation as an OS and a file), the code at the beginning of the program > copies the data across and also clears the bss - this is part of the > crt0 startup code.
Why does crt0 (C runtime 0) have code that copies data from LMA to VMA? Is it there so the C programmer doesn't have to write his own "LMA data to VMA data copy code"? If so, how would one make use of the crt0 "LMA data to VMA data copy code"?
dspfun wrote:
> Thanks for your response! > > So, the program is always linked with the VMA addresses, and never > linked with LMA addresses? Or how are references to LMA/VMA sections > resolved? >
They are not resolved. Consider the different possible cases: LMA/VMA are the same, because you are running entirely from RAM. There's no problem, and nothing more to think about. LMA/VMA are different because you are using a processor with an MMU on a big system (such as a PC). Let the native tools handle the linking and let the OS handle the loading, and forget the details. LMA/VMA are different because you are using a small system with an MMU but no OS (or only a limited OS). Forget it until you understand a bit more about what you are doing. LMA/VMA are different because you have a program in flash, initialised data in flash, and variables in ram. This is extremely common in embedded systems - I'll assume this is the situation you are talking about here from now on. For the code section, the LMA and the VMA are the same - the program runs directly from the flash it resides in. Similarly, the LMA and VMA for bss data (i.e., uninitialised data that is cleared at startup) is the same, although the LMA doesn't really matter as nothing is ever loaded. The only complication is the initialised data section, which can be thought of as two parts - a RAM block containing the variables (this is at the VMA), and a flash block containing their initial values (at the LMA). Startup code copies the initial values into the ram. The linking process "resolves" accesses to symbols (code or data), using only VMA addresses - it is only interested in how the memory looks once the program has started. The only exception is that the startup code also refers to the LMA of the data section, so that it can do the initial copy.
> When writing a program where one wants different LMA and VMA sections > the programmer himself/hersel has to make sure he/she writes the code > that copies the LMA section/data to its appropriate VMA address? >
No, it's part of the crt0 code - the code generated by your compiler, library and linker in collusion, which runs before the start of main(). Sometimes it's useful to write this sort of stuff yourself, but that is considered relatively advanced and you don't want to go there until you understand the process better.
> >> No, these are different situations. When an OS loads code from a file, >> the OS does the copying. Usually the VMA and LMA are the same, so that >> the OS loads the initialised data section directly into place. With a >> ROM'ed program, where the program is run directly from the ROM rather >> than being first copied into RAM (in which case you have the same >> situation as an OS and a file), the code at the beginning of the program >> copies the data across and also clears the bss - this is part of the >> crt0 startup code. > > Why does crt0 (C runtime 0) have code that copies data from LMA to > VMA? Is it there so the C programmer doesn't have to write his own > "LMA data to VMA data copy code"? If so, how would one make use of the > crt0 "LMA data to VMA data copy code"? >
If you follow your compiler's documentation and examples, you'll see this initial copying happening "magically" - standard linker scripts will ensure the code is linked in. You did not say which processor you were using, but many gcc setups come with sets of linker scripts including "ram" and "rom" versions - the "rom" versions will do this initial copying. Write yourself a tiny program with initialised data, generate the object files, and examine the result by reading the disassembly or by using a debugger to single-step at the assembly level through the startup code. That will make it clear what is happening.
Hi,

    I still cannot understand the difference between both since I'm a
beginner yet.

    In my case, I have a ldscript which will be linked by the linker to
form an image.

    But when I look into the ldscipt, something puzzles me a lot. It sets
the memory as below:

     MEMORY{
         flash (rx) : ORIGIN = 0x80000000,   LENGTH = 0x00200000
         ram  (!rx) : ORIGIN = 0x82000000,   LENGTH = 0x00200000
         loadregion : ORIGIN = 0xA2000000,   LENGTH = 0x00200000
     }

     And the SECTION part
     SECTIONS{
     .text : { _stext = .; _ftext = . ; *(.text) *(.text.*) ...; } >flash
AT>loadregion =0 _etext = .; PROVIDE (etext = .);
     ...
     .data :  { . = ALIGN(0x40);  _fdata = . ; *(.data) *(.data.*) . =
ALIGN (8); } >ram AT>loadregion 
     ...
     }
     
    What confused me most is the fact that the real flash address is start
from 0xA0000000 and the real memory address is start from 0xA2000000.

    According to you, the LMA now becomes RAM address, but the VMA becomes
Flash address? 
    Since the codes will run in Flash, how and what the LMA functions?

    But if I change the LMA, say modifying the loadregion part to a
different address like 0xc8000000, the image will not even run. Why?

    I have read the ld document for details but get nothing helpful.
    Does anyone give me some comments?

Thanks!

                                    Mike


     


>Hi, > > I still cannot understand the difference between both since I'm a >beginner yet. > > In my case, I have a ldscript which will be linked by the linker to >form an image. > > But when I look into the ldscipt, something puzzles me a lot. It
sets
>the memory as below: > > MEMORY{ > flash (rx) : ORIGIN = 0x80000000, LENGTH = 0x00200000 > ram (!rx) : ORIGIN = 0x82000000, LENGTH = 0x00200000 > loadregion : ORIGIN = 0xA2000000, LENGTH = 0x00200000 > } > > And the SECTION part > SECTIONS{ > .text : { _stext = .; _ftext = . ; *(.text) *(.text.*) ...; } >flash >AT>loadregion =0 _etext = .; PROVIDE (etext = .); > ... > .data : { . = ALIGN(0x40); _fdata = . ; *(.data) *(.data.*) . = >ALIGN (8); } >ram AT>loadregion > ... > } > > What confused me most is the fact that the real flash address is
start
>from 0xA0000000 and the real memory address is start from 0xA2000000. > > According to you, the LMA now becomes RAM address, but the VMA
becomes
>Flash address? > Since the codes will run in Flash, how and what the LMA functions? > > But if I change the LMA, say modifying the loadregion part to a >different address like 0xc8000000, the image will not even run. Why? > > I have read the ld document for details but get nothing helpful. > Does anyone give me some comments? > >Thanks! > > Mike > > > > >
hi, in my application , my data is too big and when load into target i got not enough memory message , so i decided to put my data into ROM using VMA and then load it when i need using LMA. simple. but i dont know how to tell compiler about VMA and LMA. any link or example is very helpful. Thanks
On Feb 10, 4:40=A0pm, "faraz_naqvi" <faraz...@hotmail.com> wrote:
> >Hi, > > > =A0 =A0I still cannot understand the difference between both since I'm =
a
> >beginner yet. > > > =A0 =A0In my case, I have a ldscript which will be linked by the linker=
to
> >form an image. > > > =A0 =A0But when I look into the ldscipt, something puzzles me a lot. It > sets > >the memory as below: > > > =A0 =A0 MEMORY{ > > =A0 =A0 =A0 =A0 flash (rx) : ORIGIN =3D 0x80000000, =A0 LENGTH =3D 0x00=
200000
> > =A0 =A0 =A0 =A0 ram =A0(!rx) : ORIGIN =3D 0x82000000, =A0 LENGTH =3D 0x=
00200000
> > =A0 =A0 =A0 =A0 loadregion : ORIGIN =3D 0xA2000000, =A0 LENGTH =3D 0x00=
200000
> > =A0 =A0 } > > > =A0 =A0 And the SECTION part > > =A0 =A0 SECTIONS{ > > =A0 =A0 .text : { _stext =3D .; _ftext =3D . ; *(.text) *(.text.*) ...;=
}
> >flash > >AT>loadregion =3D0 _etext =3D .; PROVIDE (etext =3D .); > > =A0 =A0 ... > > =A0 =A0 .data : =A0{ . =3D ALIGN(0x40); =A0_fdata =3D . ; *(.data) *(.d=
ata.*) . =3D
> >ALIGN (8); } >ram AT>loadregion > > =A0 =A0 ... > > =A0 =A0 } > > > =A0 =A0What confused me most is the fact that the real flash address is > start > >from 0xA0000000 and the real memory address is start from 0xA2000000. > > > =A0 =A0According to you, the LMA now becomes RAM address, but the VMA > becomes > >Flash address? > > =A0 =A0Since the codes will run in Flash, how and what the LMA function=
s?
> > > =A0 =A0But if I change the LMA, say modifying the loadregion part to a > >different address like 0xc8000000, the image will not even run. Why? > > > =A0 =A0I have read the ld document for details but get nothing helpful. > > =A0 =A0Does anyone give me some comments? > > >Thanks! > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
Mike
> > hi, in my application , my data is too big and when =A0load into target i > got not enough memory message , so i decided to put my data into ROM usin=
g
> VMA and then load it when i need using LMA. simple. > > but i dont =A0know how to =A0tell compiler about VMA and LMA. > any link or example is very helpful. > > Thanks
I don't understand. How will using VMA/LMA make your application fit? Are you planning to break it into smaller pieces? Rick