VMA vs LMA?

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!

Reply to
dspfun
Loading thread data ...

Your quotation from the ld documentation explains that pretty well, I thought.

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.

That is the case *if* the program is copied into RAM before running.

See above.

Reply to
David Brown

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.

Reply to
larwe

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?

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"?

Reply to
dspfun

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.

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.

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.

Reply to
David Brown

Hi,

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

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

But when I look into the ldscipt, something puzzles me a lot. It set 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.*) ...; } >flas 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 star from 0xA0000000 and the real memory address is start from 0xA2000000.

According to you, the LMA now becomes RAM address, but the VMA become 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 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

Reply to
Mike_big

sets

start

becomes

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

Reply to
faraz_naqvi

a

to

200000
00200000
200000
}

ata.*) . =3D

s?

Mike

g

I don't understand. How will using VMA/LMA make your application fit? Are you planning to break it into smaller pieces?

Rick

Reply to
rickman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.