2017-12-18 60 views
0

私はベアメタルカーネルを作成していますが、NOLOADセクションの場合はldの出力を理解するのが難しいです。私は、MMUが有効になっている場合にのみ存在するシンボルを宣言しているので、VMAとLMAは同じではありません。私はこのようなセクションの宣言に使用 :私のセクションのコンテンツの今LDとNOLOADセクション:奇妙なLMA値を理解する

_foobar_start = .; 
.foobar : AT(ADDR(.foobar) - VA_PA_OFFSET) 
{ 
    *.o(.foobar.section*) 
} 
_foobar_end = .; 

1はブートローダーによってロードされているので、私はデータのみにアクセスするには、実行時に使用されるVMAシンボルを宣言したいですので、私はNOLOAD属性を試してみました:

_foobar_start = .; 
.foobar (NOLOAD) : 
{ 
    . += SIZE_OF_FOOBAR; 
} 
_foobar_end = .; 

LD manualを参照してください)私はこのケースではLMAを気にしないけど、私はどこLMA = VMA、のようなものを見ることが予想さ:

.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はOKですが、私はので、他のセクションのコンパイル時にいくつかの警告を取得する(totoです他のセクション):

warning: dot moved backwards before `.toto 

と私はそれらを読んで取得したいのですが。

NOLOADを指定すると、LMA = VMAが得られない理由はありますか?

EDIT:問題を引き起こす完全なリンカーファイルです。私はポイントに問題

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を削除した場合、私はアドレス0x1900000

+0

場合によっては、完全なリンカーファイルを投稿することもできます。同様に、リンクされた実行可能ファイルの 'objdump -x'も便利です。 –

+1

同じ動作を引き起こすリンカファイルの短いバージョンを作ろうとします。 'objdump -x'に関しては、私は申し訳ありませんが、いくつかのサブ部分を印刷することはできません。すぐに更新。 – Vinz

+0

@ Michael-Petch:出力は十分にきれいです。 – Vinz

答えて

0

.dyn_archiveと同じ動作を得ることがon the binutils ML

(少なくとも手動の私達の解釈の延長に)確認されたように、私の最後のコメントは、有効であると思われます

「LMA go backwards」シナリオによって引き起こされた警告と手作業で.が更新されるたびにLMAを正しく更新する警告が正しい方法です。

関連する問題