LD和NOLOAD部分:了解奇怪的LMA值

我正在编写一个裸机内核,并且在NOLOAD部分的情况下我无法理解ld的输出。我声明只在MMU激活时存在的符号,所以VMA和LMA不一样。 我曾经声明这样那样的一个部分:LD和NOLOAD部分:了解奇怪的LMA值

_foobar_start = .; 

.foobar : AT(ADDR(.foobar) - VA_PA_OFFSET)

{

*.o(.foobar.section*)

}

_foobar_end = .;

现在我节的内容之一是通过引导加载器加载的,所以我只想申报VMA符号在运行时使用,访问数据,所以我尝试了NOLOAD属性:

_foobar_start = .; 

.foobar (NOLOAD) :

{

. += SIZE_OF_FOOBAR;

}

_foobar_end = .;

我知道,我不关心LMA在这种情况下,但我希望看到类似的东西,其中LMA = VMA(见LD manual):

.foobar   0x000000004002c000  0x353c load address 0x000000004002c000 

但我得到一个奇怪的LMA的东西,我不作感:

.foobar   0x000000004002c000  0x353c load address 0x0000000001900000 

如果我使用

.foobar (NOLOAD) : AT(_foobar_start) 

似乎一切都很好,我看迫使VMA = LMA脚本只有

.foobar   0x000000004002c000  0x353c 

即使没有强制VMA = LMA,所产生的ELF是好的,但我得到的,因为其他部分的编译时间一些警告(toto是其他部分):

warning: dot moved backwards before `.toto 

我希望了解这些内容。

当我指定NOLOAD时,是否有原因导致LMA = VMA?

编辑:这里是全链接文件触发问题。我加了一些意见,针点问题

OUTPUT_ARCH(CONFIG_LINKER_ARCH) 

OUTPUT_FORMAT(CONFIG_LINKER_FORMAT)

_kern_phys_base = OCRAM_BASE_PA + OCRAM_OFFSET;

_kern_offset = KERNEL_VA_PA_OFFSET;

SECTIONS

{

. = _kern_phys_base;

_start_image_addr = .;

. = ALIGN(0x1000);

_early_text_start = .;

.early_text :

{

KEEP(*(.text.boot))

KEEP(*(.text.mmu))

}

. = ALIGN(4);

.early_rodata :

{

*(.rodata.boot*)

*(.rodata.mmu*)

}

_early_text_end = .;

. = ALIGN(0x1000);

_early_data_start = .;

.early_data :

{

*(.data.boot)

}

_early_data_end = .;

. = ALIGN(0x4000);

_early_bss_start = .;

.early_bss :

{

*(.bss.mmu)

*(.bss.boot)

}

. = ALIGN(16);

_early_bss_end = .;

_early_end = .;

/*

* The following part is accessed only once the MMU has been

* activated, so we first need to jump into "high" memory

*/

. += _kern_offset;

. = ALIGN(0x1000);

_text_start = .;

.text : AT(ADDR(.text) - _kern_offset)

{

*(.text .text.*)

}

_text_end = .;

. = ALIGN(0x1000);

_rodata_start = .;

.rodata : AT(ADDR(.rodata) - _kern_offset)

{

*(.rodata*)

}

_rodata_end = .;

. = ALIGN(4);

_arm_extab_start = .;

.ARM.extab : AT(ADDR(.ARM.extab) - _kern_offset)

{

*(.ARM.extab)

}

_arm_extab_end = .;

. = ALIGN(4);

_arm_exidx_start = .;

.ARM.exidx : AT(ADDR(.ARM.exidx) - _kern_offset)

{

*(.ARM.exidx)

}

_arm_exidx_end = .;

. = ALIGN(4);

_kernel_debug_info_start = .;

_kernel_debug_info_end = .;

. = ALIGN(4);

_emergency_code_vstart = .;

_emergency_code_vend = .;

/*

* This is where I use the NOLOAD, with AT this time

* This 'archive' part is not located in OCRAM, but some

* where else in RAM

*/

_archive_point_save = .;

. = DDR_BASE_VA;

. = ALIGN(512);

_archive_start = .;

.archive_data (NOLOAD) : AT(_archive_start)

{

codes.o(.rawdata*)

}

_archive_end = .;

. = _archive_point_save;

/* Back to OCRAM VMA */

. = ALIGN(0x1000);

_data_start = .;

.data : AT(ADDR(.data) - _kern_offset)

{

*(.data*)

}

_data_end = .;

. = ALIGN(32);

_bss_start = .;

.bss : AT(ADDR(.bss) - _kern_offset)

{

*(.bss .bss.*)

}

. = ALIGN(16);

_bss_end = .;

/*

* Second location, also in RAM, just after the '.archive_data' section

* This time I didn't put the AT to show the difference in output

*/

_dyn_archive_point_save = .;

. = _archive_end;

. = ALIGN(0x1000);

_dyn_archive_start = .;

.dyn_archive (NOLOAD) :

{

. += _dyn_archive_space;

}

_dyn_archive_end = .;

. = _dyn_archive_point_save;

/* Back to OCRAM VMA */

. = ALIGN(0x1000);

_kernel_stack_guard = .;

. += 0x1000;

.stack (NOLOAD) :

{

_kernel_stack_end = .;

/* 2 pages of 4 kB */

. += 0x2000;

_kernel_stack_start = .;

}

_kernel_image_end = .;

}

这里是objdump -x输出:

build/kernel/kernel.elf:  file format elf32-littlearm 

build/kernel/kernel.elf

architecture: arm, flags 0x00000102:

EXEC_P, D_PAGED

start address 0x00910000

Program Header:

0x70000001 off 0x0003072c vaddr 0x4003072c paddr 0x0093072c align 2**2

filesz 0x000000a0 memsz 0x000000a0 flags r--

LOAD off 0x00010000 vaddr 0x00910000 paddr 0x00910000 align 2**16

filesz 0x00002828 memsz 0x00008000 flags rwx

LOAD off 0x00018000 vaddr 0x40018000 paddr 0x00918000 align 2**16

filesz 0x000199e0 memsz 0x0001fa28 flags rwx

LOAD off 0x00038000 vaddr 0x41028000 paddr 0x01928000 align 2**16

filesz 0x00000000 memsz 0x00100000 flags rw-

LOAD off 0x00039000 vaddr 0x40039000 paddr 0x40039000 align 2**16

filesz 0x00000000 memsz 0x00002000 flags rw-

LOAD off 0x00040000 vaddr 0x41000000 paddr 0x41000000 align 2**16

filesz 0x00000000 memsz 0x00028000 flags rw-

private flags = 5000200: [Version5 EABI] [soft-float ABI]

Sections:

Idx Name Size VMA LMA File off Algn

0 .early_text 000015c0 00910000 00910000 00010000 2**5

CONTENTS, ALLOC, LOAD, READONLY, CODE

1 .early_rodata 00000030 009115c0 009115c0 000115c0 2**2

CONTENTS, ALLOC, LOAD, READONLY, DATA

2 .early_data 00000828 00912000 00912000 00012000 2**3

CONTENTS, ALLOC, LOAD, DATA

3 .early_bss 00004000 00914000 00914000 00012828 2**14

ALLOC

4 .text 000142d8 40018000 00918000 00018000 2**5

CONTENTS, ALLOC, LOAD, READONLY, CODE

5 .rodata 000036c0 4002d000 0092d000 0002d000 2**2

CONTENTS, ALLOC, LOAD, READONLY, DATA

6 .ARM.extab 0000006c 400306c0 009306c0 000306c0 2**2

CONTENTS, ALLOC, LOAD, READONLY, DATA

7 .ARM.exidx 000000a0 4003072c 0093072c 0003072c 2**2

CONTENTS, ALLOC, LOAD, READONLY, DATA

8 .archive_data 00028000 41000000 41000000 00040000 2**0

ALLOC

9 .data 000009e0 40031000 00931000 00031000 2**3

CONTENTS, ALLOC, LOAD, DATA

10 .bss 00006048 400319e0 009319e0 000319e0 2**3

ALLOC

11 .dyn_archive 00100000 41028000 01928000 00038000 2**0

ALLOC

12 .stack 00002000 40039000 40039000 00039000 2**0

ALLOC

13 .comment 0000002d 00000000 00000000 000319e0 2**0

CONTENTS, READONLY

14 .ARM.attributes 00000037 00000000 00000000 00031a0d 2**0

CONTENTS, READONLY

SYMBOL TABLE:

no symbols

正如你可以看到:.archive_data.stack正确地得到VMA = LMA但.dyn_archive没有。如果我删除的.archive_dataAT,我得到比.dyn_archive相同的行为与地址0x1900000

回答:

看来我最后的评论是有效的,如证实(至少对扩大我们的手册中解释)on the binutils ML

由“LMA后退”场景触发的警告以及每次正确更新LMA都是手动更新的警告是正确的方法。

以上是 LD和NOLOAD部分:了解奇怪的LMA值 的全部内容, 来源链接: utcz.com/qa/262495.html

回到顶部