Questions about the LMA and VMA in a linker script
Hi, I got some question about the AT directive in linker script. I have post this question to binutils{at}sourceware.org with no reply. Hopefully someone can help me out. After some searching and asking, I finally know that the AT directive tell the linker about LMA of a section. For example there is some linker script like this: SECTIONS { . = 0X80100000; .text : AT(0x100000) { *(.text .stub .text.* .gnu.linkonce.t.*) } ... blah blah ... } Now 0x8010000 is a VMA, and 0x100000 is a LMA. My question is, is LMA the same as the physical address in a ELF program header ? A typical ELF declaration would be something like this: typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr; Is LMA just **p_paddr** in the program header? My understanding is, when the linker link all the object files together and then output a executable file of ELF format, those LMA declare in the linker script would be the **p_paddr** in the executable file, so the loader can correspondingly put that program on the physical address as declared by **p_paddr**. Is that correct? Please correct me if you may. I'm reading some low level code and is not really familiar with those low level stuff. Thanks in advance! Ruan.
Replying to all this time. Currently, I'm most recently familiar with small non-MMU processors (not running linux), and in that case, the VMA is the final address (typically in RAM) that the section will be loaded to. The LMA is the address (typically in ROM) that the section will be at when the program starts execution. A typical example of this is initialized data. In the image, this "initialized data" section will be stored in ROM and copied to RAM by the C runtime library before calling main. In the linux kernel, the kernel image will be linked against its final virtual address (the VMA) and the LMA would correspond to the physical address that the kernel will be loaded at (since the MMU is typically off when the kernel image is loaded). There are lots of variations and reasons why things might not be exactly like I described (different architectures have different conventions), but that's the jist of things. On Wed, Jul 13, 2016 at 7:33 PM, walker lala <ablacktshirt@gmail.com> wrote:
Hi, I got some question about the AT directive in linker script. I have post this question to binutils{at}sourceware.org with no reply. Hopefully someone can help me out.
After some searching and asking, I finally know that the AT directive tell the linker about LMA of a section.
For example there is some linker script like this:
SECTIONS { . = 0X80100000; .text : AT(0x100000) { *(.text .stub .text.* .gnu.linkonce.t.*) }
... blah blah ... }
Now 0x8010000 is a VMA, and 0x100000 is a LMA.
My question is, is LMA the same as the physical address in a ELF program header ? A typical ELF declaration would be something like this:
typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;
Is LMA just **p_paddr** in the program header?
My understanding is, when the linker link all the object files together and then output a executable file of ELF format, those LMA declare in the linker script would be the **p_paddr** in the executable file, so the loader can correspondingly put that program on the physical address as declared by **p_paddr**. Is that correct? Please correct me if you may. I'm reading some low level code and is not really familiar with those low level stuff.
Thanks in advance! Ruan.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
On Wed, Jul 13, 2016 at 7:33 PM, Yubin Ruan <ablacktshirt@gmail.com <mailto:ablacktshirt@gmail.com>> wrote:
Hi, I got some question about the AT directive in linker script. I have post this question to binutils{at}sourceware.org <http://sourceware.org> with no reply. Hopefully someone can help me out.
After some searching and asking, I finally know that the AT directive tell the linker about LMA of a section.
For example there is some linker script like this:
SECTIONS { . = 0X80100000; .text : AT(0x100000) { *(.text .stub .text.* .gnu.linkonce.t.*) }
... blah blah ... }
Now 0x8010000 is a VMA, and 0x100000 is a LMA.
My question is, is LMA the same as the physical address in a ELF program header ? A typical ELF declaration would be something like this:
typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;
Is LMA just **p_paddr** in the program header?
My understanding is, when the linker link all the object files together and then output a executable file of ELF format, those LMA declare in the linker script would be the **p_paddr** in the executable file, so the loader can correspondingly put that program on the physical address as declared by **p_paddr**. Is that correct? Please correct me if you may. I'm reading some low level code and is not really familiar with those low level stuff.
Thanks in advance! Ruan.
On 2016, July 14, at 14:07, Dave Hylands wrote: Replying to all this time.
Currently, I'm most recently familiar with small non-MMU processors (not running linux), and in that case, the VMA is the final address (typically in RAM) that the section will be loaded to. The LMA is the address (typically in ROM) that the section will be at when the program starts execution.
A typical example of this is initialized data. In the image, this "initialized data" section will be stored in ROM and copied to RAM by the C runtime library before calling main.
In the linux kernel, the kernel image will be linked against its final virtual address (the VMA) and the LMA would correspond to the physical address that the kernel will be loaded at (since the MMU is typically off when the kernel image is loaded).
There are lots of variations and reasons why things might not be exactly like I described (different architectures have different conventions), but that's the jist of things.
-- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
Thank you for replying. I think I understand what you mean. But I still want the answer to my question, that is, is LMA just **p_paddr** in the program header? Regards, Ruan
On Thu, Jul 14, 2016 at 1:45 AM, Yubin Ruan <ablacktshirt@gmail.com> wrote:
On Wed, Jul 13, 2016 at 7:33 PM, Yubin Ruan <ablacktshirt@gmail.com
<mailto:ablacktshirt@gmail.com>> wrote:
Hi, I got some question about the AT directive in linker script. I have post this question to binutils{at}sourceware.org <http://sourceware.org> with no reply.
Hopefully someone can help me out.
After some searching and asking, I finally know that the AT directive tell the linker about LMA of a section.
For example there is some linker script like this:
SECTIONS { . = 0X80100000; .text : AT(0x100000) { *(.text .stub .text.* .gnu.linkonce.t.*) }
... blah blah ... }
Now 0x8010000 is a VMA, and 0x100000 is a LMA.
My question is, is LMA the same as the physical address in a ELF program header ? A typical ELF declaration would be something like this:
typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;
Is LMA just **p_paddr** in the program header?
...snip...
Thank you for replying. I think I understand what you mean. But I still want the answer to my question, that is, is LMA just **p_paddr** in the program header?
I'm pretty sure that's the case. There are actually 2 sets of headers. You can use: objdump -p foo.elf to view the "private" headers which shows you the p_vaddr and p_paddr fields. And you can use objdump -h foo.elf to view the section headers. Here's some example output for a typical embedded program: 2216 >objdump -p firmware.elf firmware.elf: file format elf32-little Program Header: LOAD off 0x00008000 vaddr 0x08000000 paddr 0x08000000 align 2**15 filesz 0x0000288c memsz 0x0000288c flags r-x LOAD off 0x00010000 vaddr 0x08020000 paddr 0x08020000 align 2**15 filesz 0x00040470 memsz 0x00040470 flags r-x LOAD off 0x00058000 vaddr 0x20000000 paddr 0x08060470 align 2**15 filesz 0x00000108 memsz 0x000064f0 flags rw- LOAD off 0x0005e4f0 vaddr 0x200064f0 paddr 0x08060578 align 2**15 filesz 0x00000000 memsz 0x00004000 flags rw- LOAD off 0x0005a4f0 vaddr 0x2000a4f0 paddr 0x08060578 align 2**15 filesz 0x00000000 memsz 0x00000800 flags rw- 2217 >objdump -h firmware.elf firmware.elf: file format elf32-little Sections: Idx Name Size VMA LMA File off Algn 0 .isr_vector 0000288c 08000000 08000000 00008000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .text 00040470 08020000 08020000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .data 00000108 20000000 08060470 00058000 2**2 CONTENTS, ALLOC, LOAD, DATA 3 .bss 000063e8 20000108 08060578 00058108 2**2 ALLOC 4 .heap 00004000 200064f0 08060578 0005e4f0 2**0 ALLOC 5 .stack 00000800 2000a4f0 08060578 0005a4f0 2**0 ALLOC 6 .ARM.attributes 00000037 00000000 00000000 00058108 2**0 CONTENTS, READONLY 7 .comment 000000e0 00000000 00000000 0005813f 2**0 CONTENTS, READONLY -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
On 2016年07月16日 02:42, Dave Hylands wrote:
On Thu, Jul 14, 2016 at 1:45 AM, Yubin Ruan <ablacktshirt@gmail.com <mailto:ablacktshirt@gmail.com>> wrote:
On Wed, Jul 13, 2016 at 7:33 PM, Yubin Ruan <ablacktshirt@gmail.com <mailto:ablacktshirt@gmail.com> <mailto:ablacktshirt@gmail.com <mailto:ablacktshirt@gmail.com>>> wrote:
Hi, I got some question about the AT directive in linker script. I have post this question to binutils{at}sourceware.org <http://sourceware.org> <http://sourceware.org> with no reply.
Hopefully someone can help me out.
After some searching and asking, I finally know that the AT directive tell the linker about LMA of a section.
For example there is some linker script like this:
SECTIONS { . = 0X80100000; .text : AT(0x100000) { *(.text .stub .text.* .gnu.linkonce.t.*) }
... blah blah ... }
Now 0x8010000 is a VMA, and 0x100000 is a LMA.
My question is, is LMA the same as the physical address in a ELF program header ? A typical ELF declaration would be something like this:
typedef struct { Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ Elf32_Addr p_paddr; /* Segment physical address */ Elf32_Word p_filesz; /* Segment size in file */ Elf32_Word p_memsz; /* Segment size in memory */ Elf32_Word p_flags; /* Segment flags */ Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;
Is LMA just **p_paddr** in the program header?
...snip...
Thank you for replying. I think I understand what you mean. But I still want the answer to my question, that is, is LMA just **p_paddr** in the program header?
I'm pretty sure that's the case. There are actually 2 sets of headers. You can use:
objdump -p foo.elf
to view the "private" headers which shows you the p_vaddr and p_paddr fields.
And you can use
objdump -h foo.elf
to view the section headers.
Here's some example output for a typical embedded program:
2216 >objdump -p firmware.elf
firmware.elf: file format elf32-little
Program Header: LOAD off 0x00008000 vaddr 0x08000000 paddr 0x08000000 align 2**15 filesz 0x0000288c memsz 0x0000288c flags r-x LOAD off 0x00010000 vaddr 0x08020000 paddr 0x08020000 align 2**15 filesz 0x00040470 memsz 0x00040470 flags r-x LOAD off 0x00058000 vaddr 0x20000000 paddr 0x08060470 align 2**15 filesz 0x00000108 memsz 0x000064f0 flags rw- LOAD off 0x0005e4f0 vaddr 0x200064f0 paddr 0x08060578 align 2**15 filesz 0x00000000 memsz 0x00004000 flags rw- LOAD off 0x0005a4f0 vaddr 0x2000a4f0 paddr 0x08060578 align 2**15 filesz 0x00000000 memsz 0x00000800 flags rw-
2217 >objdump -h firmware.elf
firmware.elf: file format elf32-little
Sections: Idx Name Size VMA LMA File off Algn 0 .isr_vector 0000288c 08000000 08000000 00008000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .text 00040470 08020000 08020000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .data 00000108 20000000 08060470 00058000 2**2 CONTENTS, ALLOC, LOAD, DATA 3 .bss 000063e8 20000108 08060578 00058108 2**2 ALLOC 4 .heap 00004000 200064f0 08060578 0005e4f0 2**0 ALLOC 5 .stack 00000800 2000a4f0 08060578 0005a4f0 2**0 ALLOC 6 .ARM.attributes 00000037 00000000 00000000 00058108 2**0 CONTENTS, READONLY 7 .comment 000000e0 00000000 00000000 0005813f 2**0 CONTENTS, READONLY
-- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
Thanks :-) Your reply really eliminate my doubts. Regards, Ruan.
participants (3)
-
Dave Hylands -
walker lala -
Yubin Ruan