この記事で関係するターゲット
前の記事 参照linker.cmd
[zephyr_base]/samples/hello_world/microkernel/outdir/linker.cmdMEMORY { RAM (wx) : ORIGIN = 0x00100000, LENGTH = 192*1K IDT_LIST : ORIGIN = 2K, LENGTH = 2K } OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) SECTIONS { _image_rom_start = 0x00100000; _image_text_start = 0x00100000; text () : { *(.text_start) *(".text_start.*") *(.text) *(".text.*") *(.gnu.linkonce.t.*) *(.eh_frame) *(.init) *(.fini) *(.eini) } > RAM _image_text_end = .; devconfig () : { __devconfig_start = .; *(".devconfig.*") KEEP(*(SORT(".devconfig*"))) __devconfig_end = .; } > RAM gpio_compat () : { __gpio_compat_start = .; *(".gpio_compat.*") KEEP(*(SORT(".gpio_compat*"))) __gpio_compat_end = .; } > RAM rodata () : { *(.rodata) *(".rodata.*") *(.gnu.linkonce.r.*) . = ALIGN(8); _idt_base_address = .; . += (8 * 256); . = ALIGN(4); _irq_to_interrupt_vector = .; . += 128; } > RAM _image_rom_end = .; __data_rom_start = ALIGN(4); datas () : { _image_ram_start = .; __data_ram_start = .; *(.data) *(".data.*") . = ALIGN(4); } > RAM initlevel () : { __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; } > RAM _k_task_list ALIGN(4) : ALIGN(4) { _k_task_list_start = .; *(._k_task_list.public.*) *(._k_task_list.private.*) _k_task_list_idle_start = .; *(._k_task_list.idle.*) KEEP(*(SORT("._k_task_list*"))) _k_task_list_end = .; } > RAM _k_task_ptr () : { _k_task_ptr_start = .; *(._k_task_ptr.public.*) *(._k_task_ptr.private.*) *(._k_task_ptr.idle.*) KEEP(*(SORT("._k_task_ptr*"))) _k_task_ptr_end = .; } > RAM _k_pipe_ptr () : { _k_pipe_ptr_start = .; *(._k_pipe_ptr.public.*) *(._k_pipe_ptr.private.*) KEEP(*(SORT("._k_pipe_ptr*"))) _k_pipe_ptr_end = .; } > RAM _k_mem_map_ptr () : { _k_mem_map_ptr_start = .; *(._k_mem_map_ptr.public.*) *(._k_mem_map_ptr.private.*) KEEP(*(SORT("._k_mem_map_ptr*"))) _k_mem_map_ptr_end = .; } > RAM _k_event_list () : { _k_event_list_start = .; *(._k_event_list.event.*) KEEP(*(SORT("._k_event_list*"))) _k_event_list_end = .; } > RAM __data_ram_end = .; bss (NOLOAD ) : { . = ALIGN(4); __bss_start = .; *(.bss) *(".bss.*") *(COMMON) . = ALIGN(4); __bss_end = .; } > RAM noinit (NOLOAD ) : { *(.noinit) *(".noinit.*") KEEP(*(.intStubSect)) } > RAM _image_ram_end = .; _end = .; . = ALIGN(((4) << 10)); __bss_num_words = (__bss_end - __bss_start) >> 2; intList () : { KEEP(*(.spurIsr)) KEEP(*(.spurNoErrIsr)) __INT_LIST_START__ = .; LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) KEEP(*(.intList)) __INT_LIST_END__ = .; } > IDT_LIST initlevel_error () : { KEEP(*(SORT(.init_[_A-Z0-9]*))) } ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.") } SECTIONS { .shstrtab 0 (): { *(.shstrtab) } .symtab 0 (): { *(.symtab) } .strtab 0 (): { *(.strtab) } .iplt 0 (): { *(.iplt) } .igot.plt 0 (): { *(.igot.plt) } .rel.plt 0 (): { *(.rel.plt) } .rela.plt 0 (): { *(.rela.plt) } .rel.dyn 0 (): { *(".rel.*") } .rela.dyn 0 (): { *(".rela.*") } .comment 0 (): { *(.comment) } .debug 0 (): { *(.debug) } .line 0 (): { *(.line) } .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } .debug_aranges 0 (): { *(.debug_aranges) } .debug_pubnames 0 (): { *(.debug_pubnames) } .debug_pubtypes 0 (): { *(.debug_pubtypes) } .debug_line 0 (): { *(.debug_line) } .debug_info 0 (): { *(.debug_info) } .debug_macinfo 0 (): { *(.debug_macinfo) } .debug_abbrev 0 (): { *(.debug_abbrev) } .debug_loc 0 (): { *(.debug_loc) } .debug_ranges 0 (): { *(.debug_ranges) } .debug_str 0 (): { *(.debug_str) } .debug_frame 0 (): { *(.debug_frame) } .debug_macro 0 (): { *(.debug_macro) } .trashcan : { *(.*) } } ASSERT(SIZEOF(.trashcan) == 0, "Section(s) undefined in the linker script used.")
MEMORY
MEMORY { /* 物理アドレス空間(?)の0x00100000〜0x0012FFFF へ "RAM" リージョンを割り当てる */ RAM (wx) : ORIGIN = 0x00100000, LENGTH = 192*1K /* 物理アドレス空間(?)の0x00002000〜0x00003FFFへ、"IDT_LIST" リージョンを割り当てる */ IDT_LIST : ORIGIN = 2K, LENGTH = 2K }参考:3.7 MEMORY Command "RAM"リージョンのアドレスは、ブートローダなど(TODO x86だとUEFI、その他はu-bootなど?それともROMからeXecute In Place?)が zephyr.bin をROMからRAMへロードする時に必要となる?
OUTPUT_FORMAT, OUTPUT_ARCH
/* デフォルトフォーマット、ビッグエンディアンでのフォーマット、リトルエンディアンでのフォーマット */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") /* ターゲットのアーキテクチャ */ OUTPUT_ARCH(i386)参考:3.4.3 Commands Dealing with Object File Formats 3.4.5 Other Linker Script Commands
SECTIONS
/* 入力ファイル中のセクションを、出力ファイルのどのセクションに割り当てるか */ SECTIONS {参考:3.6 SECTIONS Command
_image_rom_start シンボル
_image_rom_start = 0x00100000;
image_rom_start grep 結果
$ grep image_rom_start * -RI include/arch/arc/v2/linker.ld: _image_rom_start = .; include/arch/arc/v2/linker_harvard.ld: _image_rom_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_rom_start = CONFIG_FLASH_BASE_ADDRESS; include/arch/nios2/linker.ld: _image_rom_start = CONFIG_FLASH_BASE_ADDRESS; include/arch/x86/linker-common-sections.h: _image_rom_start = PHYS_LOAD_ADDR; include/linker-defs.h:extern char _image_rom_start[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_ROM_START ((vaddr_t)&_image_rom_start) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_rom_start = 0x00100000; samples/hello_world/microkernel/outdir/linker.cmd: _image_rom_start = 0x00100000; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000100000 _image_rom_start = 0x100000 tests/kernel/test_mem_safe/src/main.c:#define ROM_START ((uint32_t)&_image_rom_start) tests/kernel/test_mem_safe/src/main.c:char * const p_image_rom_start = (char *)ROM_START; tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_rom_start, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_write(p_image_rom_start, 1, -EFAULT)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_rom_start - 1, 1, -EFAULT));
_image_text_start シンボル
_image_text_start = 0x00100000;
image_text_start grep 結果
$ grep image_text_start -RI include/arch/arc/v2/linker.ld: _image_text_start = .; include/arch/arc/v2/linker_harvard.ld: _image_text_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_text_start = .; include/arch/nios2/linker.ld: _image_text_start = .; include/arch/x86/linker-common-sections.h: _image_text_start = PHYS_LOAD_ADDR; include/linker-defs.h:extern char _image_text_start[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_TEXT_START ((vaddr_t)&_image_text_start) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_text_start = 0x00100000; samples/hello_world/microkernel/outdir/linker.cmd: _image_text_start = 0x00100000; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000100000 _image_text_start = 0x100000
text セクション
/* 出力ファイルのtextセクションに割り当てる */ text () : { /* 入力ファイルのtext_startセクション */ /* textセクションの先頭から処理を実行するため、text_startと特別に名前をつけて、他のtextセクションと区別している? (elfではなくbinファイルの場合、ENTRY()でスタートアップルーチンを指定できないため) */ *(.text_start) /* 入力ファイルのtext_start.* セクション。TODO ""で囲う意味は? */ *(".text_start.*") /* 入力ファイルのtextセクション */ *(.text) /* 入力ファイルのtext.*セクション */ *(".text.*") /* 入力ファイルのgnu.linkonce.t.*セクション */ /* 7.78 .section name 参照*/ *(.gnu.linkonce.t.*) /* 入力ファイルのeh_frameセクション */ /* 7.10 CFI directives 参照 */ /* Exception Handling 参照 */ *(.eh_frame) /* 17.20.5 How Initialization Functions Are Handled 参照 */ *(.init) *(.fini) /* TODO 調査 */ *(.eini) } > RAM /* textセクションを"RAM"リージョンに割り当てる */参考: 3.6.4 Input Section Description
_image_text_end シンボル
_image_text_end = .;シンボル_image_text_endに現在のロケーションカウンタをセットする。 参考: 3.10.5 The Location Counter
image_text_end grep 結果
$ grep image_text_end * -RI include/arch/arc/v2/linker.ld: _image_text_end = .; include/arch/arc/v2/linker_harvard.ld: _image_text_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_text_end = .; include/arch/nios2/linker.ld: _image_text_end = .; include/arch/x86/linker-common-sections.h: _image_text_end = .; include/linker-defs.h:extern char _image_text_end[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_TEXT_END ((vaddr_t)&_image_text_end) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_text_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _image_text_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000102f64 _image_text_end = .
devconfig セクション
/* 出力ファイルのdevconfigセクションに割り当てる */ devconfig () : { /* シンボル__devconfig_startに現在のロケーションカウンタをセット。下記参照 */ __devconfig_start = .; /* 入力ファイルのdevconfig.*セクション */ *(".devconfig.*") /* KEEP: 3.6.4.4 Input Section and Garbage Collection */ /* *, SORT: 3.6.4.2 Input Section Wildcard Patterns */ /* 入力ファイルのdevconfig*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで削除されないようにする(KEEP) */ KEEP(*(SORT(".devconfig*"))) /* シンボル__devconfig_endに現在のロケーションカウンタをセット。下記参照 */ __devconfig_end = .; } > RAM /* devconfigセクションを"RAM"リージョンに割り当てる */
_devconfig_start grep 結果
$ grep _devconfig_start * -RI include/arch/arc/v2/linker.ld: __devconfig_start = .; include/arch/arc/v2/linker_harvard.ld: __devconfig_start = .; include/arch/arm/cortex_m/scripts/linker.ld: __devconfig_start = .; include/arch/nios2/linker.ld: __devconfig_start = .; include/arch/x86/linker-common-sections.h: __devconfig_start = .; samples/hello_world/microkernel/outdir/final-linker.cmd: __devconfig_start = .; samples/hello_world/microkernel/outdir/linker.cmd: __devconfig_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000102f64 __devconfig_start = .
gpio_compat セクション
/* 出力ファイルのgpio_compatセクションに割り当てる */ gpio_compat () : { /* シンボル__gpio_compat_startに現在のロケーションカウンタをセット。下記参照 */ __gpio_compat_start = .; /* 入力ファイルのgpio_compat.*セクション */ *(".gpio_compat.*") /* 入力ファイルのgpio_compat*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(".gpio_compat*"))) /* シンボル__gpio_compat_endに現在のロケーションカウンタをセット。下記参照 */ __gpio_compat_end = .; } > RAM /* gpio_compatセクションを"RAM"リージョンに割り当てる */
__gpio_compat_start grep 結果
$ grep _gpio_compat_start * -RI drivers/gpio/gpio_api_compat.c:extern struct gpio_compat_cb __gpio_compat_start[]; drivers/gpio/gpio_api_compat.c: for (cb = __gpio_compat_start; cb != __gpio_compat_end; cb++) { include/arch/arc/v2/linker.ld: __gpio_compat_start = .; include/arch/arc/v2/linker_harvard.ld: __gpio_compat_start = .; include/arch/arm/cortex_m/scripts/linker.ld: __gpio_compat_start = .; include/arch/x86/linker-common-sections.h: __gpio_compat_start = .; samples/hello_world/microkernel/outdir/final-linker.cmd: __gpio_compat_start = .; samples/hello_world/microkernel/outdir/linker.cmd: __gpio_compat_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000102fd0 __gpio_compat_start = .
__gpio_compat_end grep 結果
$ grep _gpio_compat_end * -RI drivers/gpio/gpio_api_compat.c:extern struct gpio_compat_cb __gpio_compat_end[]; drivers/gpio/gpio_api_compat.c: for (cb = __gpio_compat_start; cb != __gpio_compat_end; cb++) { include/arch/arc/v2/linker.ld: __gpio_compat_end = .; include/arch/arc/v2/linker_harvard.ld: __gpio_compat_end = .; include/arch/arm/cortex_m/scripts/linker.ld: __gpio_compat_end = .; include/arch/x86/linker-common-sections.h: __gpio_compat_end = .; samples/hello_world/microkernel/outdir/final-linker.cmd: __gpio_compat_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __gpio_compat_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000102fd0 __gpio_compat_end = .
rodata セクション
/* 出力ファイルのrodataセクションに割り当てる */ rodata () : { /* 入力ファイルのrodataセクション */ *(.rodata) /* 入力ファイルのrodata.*セクション */ *(".rodata.*") /* 入力ファイルのgnu.linkonce.r.*セクション */ /* 7.78 .section name 参照*/ *(.gnu.linkonce.r.*) /* 現在のロケーションカウンタを8バイトアライメントする */ /* ALIGN: 3.10.9 Builtin Functions*/ . = ALIGN(8); /* シンボル_idt_base_addressに現在のロケーションカウンタをセット。下記参照 */ _idt_base_address = .; /* 現在のロケーションカウンタを2048(8 * 256)すすめる */ /* ロケーションカウンタ:3.10.5 The Location Counter */ /* +=: 3.10.6 Operators */ . += (8 * 256); /* 現在のロケーションカウンタを4バイトアライメントする */ . = ALIGN(4); /* シンボル_irq_to_interrupt_vectorに現在のロケーションカウンタをセット。下記参照 */ _irq_to_interrupt_vector = .; /* 現在のロケーションカウンタを128すすめる */ . += 128; } > RAM /* rodataセクションを"RAM"リージョンに割り当てる */
idt_base_address grep 結果
$ grep idt_base_address * -RI arch/x86/core/crt0.S: GDATA(_idt_base_address) arch/x86/core/crt0.S: .long _idt_base_address /* physical start address */ arch/x86/core/dynamic.c: idt_entry = (IDT_ENTRY *)(_idt_base_address + (vector << 3)); arch/x86/core/intconnect.c: * The _idt_base_address symbol is used to determine the base address of the IDT. arch/x86/core/intconnect.c: IDT_ENTRY *idt = (IDT_ENTRY *)_idt_base_address; arch/x86/core/intconnect.c: pIdtEntry = (unsigned long long *)(_idt_base_address + (vector << 3)); arch/x86/include/nano_private.h:/* the _idt_base_address symbol is generated via a linker script */ arch/x86/include/nano_private.h:extern unsigned char _idt_base_address[]; include/arch/x86/linker-defs-arch.h: _idt_base_address = .;\ samples/hello_world/microkernel/outdir/final-linker.cmd: . = ALIGN(8); _idt_base_address = .; KEEP(*(staticIdt)) samples/hello_world/microkernel/outdir/linker.cmd: . = ALIGN(8); _idt_base_address = .; . += (8 * 256); samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001032c0 _idt_base_address = . samples/task_profiler/profiler/scripts/profile_kernel.py: ("_idt_base_address" in s)): samples/task_profiler/profiler/scripts/profile_kernel.py: # First get IDT table address '_idt_base_address' symbol samples/task_profiler/profiler/scripts/profile_kernel.py: if sym == '_idt_base_address': tests/kernel/test_static_idt/microkernel/src/static_idt.c: /* the _idt_base_address symbol is generated via a linker script */ tests/kernel/test_static_idt/microkernel/src/static_idt.c:extern unsigned char _idt_base_address[]; tests/kernel/test_static_idt/microkernel/src/static_idt.c: pIdtEntry = (IDT_ENTRY *) (_idt_base_address + (TEST_SOFT_INT << 3)); tests/kernel/test_static_idt/microkernel/src/static_idt.c: pIdtEntry = (IDT_ENTRY *) (_idt_base_address + (IV_DIVIDE_ERROR << 3));
irq_to_interrupt_vector grep 結果
$ grep irq_to_interrupt_vector * -RI arch/x86/core/Kconfig: size of the _irq_to_interrupt_vector_table, which is used at runtime drivers/interrupt_controller/ioapic_intr.c: if (_irq_to_interrupt_vector[irq]) { drivers/interrupt_controller/ioapic_intr.c: if (_irq_to_interrupt_vector[irq]) { drivers/interrupt_controller/ioapic_intr.c: rteValue = (_irq_to_interrupt_vector[irq] & drivers/interrupt_controller/loapic_intr.c: if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) { drivers/interrupt_controller/loapic_intr.c: if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) { drivers/interrupt_controller/loapic_intr.c: _irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]); drivers/interrupt_controller/system_apic.c: _irq_to_interrupt_vector[irq] = vector; include/arch/x86/arch.h:extern unsigned char _irq_to_interrupt_vector[]; include/arch/x86/arch.h: ((unsigned int) _irq_to_interrupt_vector[irq]) include/arch/x86/linker-defs-arch.h: /* Use the real _irq_to_interrupt_vector[] array */ include/arch/x86/linker-defs-arch.h: _irq_to_interrupt_vector = .; \ samples/hello_world/microkernel/outdir/final-linker.cmd: . = ALIGN(4); _irq_to_interrupt_vector = .; KEEP(*(irq_int_vector_map)) samples/hello_world/microkernel/outdir/linker.cmd: . = ALIGN(4); _irq_to_interrupt_vector = .; . += 128; samples/hello_world/microkernel/outdir/zephyr.lst: _irq_to_interrupt_vector[irq] = vector; samples/hello_world/microkernel/outdir/zephyr.lst: _irq_to_interrupt_vector[irq] = vector; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000103ac0 _irq_to_interrupt_vector = .
_image_rom_end シンボル
_image_rom_end = .;シンボル_image_rom_endに現在のロケーションカウンタをセットする。
image_rom_end grep 結果
$ grep image_rom_end * -RI include/arch/arc/v2/linker.ld: _image_rom_end = .; include/arch/arc/v2/linker_harvard.ld: _image_rom_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_rom_end = .; include/arch/nios2/linker.ld: _image_rom_end = .; include/arch/x86/linker-common-sections.h: _image_rom_end = .; include/linker-defs.h:extern char _image_rom_end[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_ROM_END ((vaddr_t)&_image_rom_end) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_rom_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _image_rom_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000103b40 _image_rom_end = . tests/kernel/test_mem_safe/src/main.c:#define ROM_END ((uint32_t)&_image_rom_end) tests/kernel/test_mem_safe/src/main.c:char * const p_image_rom_end = (char *)ROM_END; tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_rom_end - 1, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_write(p_image_rom_end - 1, 1, -EFAULT));
__data_rom_start シンボル
__data_rom_start = ALIGN(4);シンボル__data_rom_startに現在のロケーションカウンタを4バイトアライメントした値をセットする。
_data_rom_start grep 結果
$ grep _data_rom_start * -RI arch/arc/core/prep_c.c: volatile uint32_t *pROM = (uint32_t *)&__data_rom_start; arch/arm/core/cortex_m/prep_c.c: volatile uint32_t *pROM = (uint32_t *)&__data_rom_start; arch/nios2/core/prep_c.c: volatile uint32_t *pROM = (uint32_t *)&__data_rom_start; arch/x86/core/crt0.S: movl $__data_rom_start, %esi /* DATA in ROM (src) */ include/arch/arc/v2/linker.ld: #define _DATA_IN_ROM __data_rom_start include/arch/arc/v2/linker.ld: __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ include/arch/arc/v2/linker_harvard.ld: #define _DATA_IN_ROM __data_rom_start include/arch/arc/v2/linker_harvard.ld: __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ include/arch/arm/cortex_m/scripts/linker.ld: #define _DATA_IN_ROM __data_rom_start include/arch/arm/cortex_m/scripts/linker.ld: __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ include/arch/nios2/linker.ld:#define _DATA_IN_ROM __data_rom_start include/arch/nios2/linker.ld: __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ include/arch/x86/linker-common-sections.h: * case, the LMA is set to __data_rom_start so the data section is concatenated include/arch/x86/linker-common-sections.h: __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ include/arch/x86/linker-common-sections.h: SECTION_AT_PROLOGUE(_DATA_SECTION_NAME, (OPTIONAL), , __data_rom_start) include/linker-defs.h:GDATA(__data_rom_start) include/linker-defs.h:extern char __data_rom_start[]; samples/hello_world/microkernel/outdir/final-linker.cmd: __data_rom_start = ALIGN(4); samples/hello_world/microkernel/outdir/linker.cmd: __data_rom_start = ALIGN(4); samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000103b40 __data_rom_start = ALIGN (0x4)
datas セクション
/* 出力ファイルのdatasセクションに割り当てる */ datas () : { /* シンボル_image_ram_startに現在のロケーションカウンタをセット。下記参照 */ _image_ram_start = .; /* シンボル__data_ram_startに現在のロケーションカウンタをセット。下記参照 */ __data_ram_start = .; /* 入力ファイルのdataセクション */ *(.data) /* 入力ファイルのdata.*セクション */ *(".data.*") /* 現在のロケーションカウンタを4バイトアライメントする */ . = ALIGN(4); } > RAM /* datasセクションを"RAM"リージョンに割り当てる */
image_ram_start grep 結果
$ grep image_ram_start * -RI include/arch/arc/v2/linker.ld: _image_ram_start = .; include/arch/arc/v2/linker_harvard.ld: _image_ram_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_ram_start = .; include/arch/nios2/linker.ld: _image_ram_start = .; include/arch/x86/linker-common-sections.h: _image_ram_start = .; include/linker-defs.h:extern char _image_ram_start[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_RAM_START ((vaddr_t)&_image_ram_start) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_ram_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _image_ram_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000103b40 _image_ram_start = . tests/kernel/test_mem_safe/src/main.c:#define RAM_START ((uint32_t)&_image_ram_start) tests/kernel/test_mem_safe/src/main.c:char * const p_image_ram_start = (char *)RAM_START; tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_ram_start, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_write(p_image_ram_start, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_write(p_image_ram_start - 1, 1, -EFAULT));
_data_ram_start grep 結果
$ grep _data_ram_start * -RI arch/arc/core/prep_c.c: volatile uint32_t *pRAM = (uint32_t *)&__data_ram_start; arch/arm/core/cortex_m/prep_c.c: volatile uint32_t *pRAM = (uint32_t *)&__data_ram_start; arch/nios2/core/prep_c.c: volatile uint32_t *pRAM = (uint32_t *)&__data_ram_start; arch/x86/core/crt0.S: movl $__data_ram_start, %edi /* DATA in RAM (dest) */ include/arch/arc/v2/linker.ld: __data_ram_start = .; include/arch/arc/v2/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/arc/v2/linker_harvard.ld: __data_ram_start = .; include/arch/arc/v2/linker_harvard.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/arm/cortex_m/scripts/linker.ld: __data_ram_start = .; include/arch/arm/cortex_m/scripts/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/nios2/linker.ld: __data_ram_start = .; include/arch/nios2/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/x86/linker-common-sections.h: __data_ram_start = .; include/arch/x86/linker-common-sections.h:__data_size = (__data_ram_end - __data_ram_start); include/linker-defs.h:GDATA(__data_ram_start) include/linker-defs.h:extern char __data_ram_start[]; samples/hello_world/microkernel/outdir/final-linker.cmd: __data_ram_start = .; samples/hello_world/microkernel/outdir/linker.cmd: __data_ram_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000103b40 __data_ram_start = .
initlevel セクション
/* 出力ファイルのinitlevelセクションに割り当てる */ initlevel () : { /* シンボル__device_init_startに現在のロケーションカウンタをセット。下記参照 */ __device_init_start = .; /* シンボル__device_PRIMARY_startに現在のロケーションカウンタをセット。下記参照 */ __device_PRIMARY_start = .; /* 入力ファイルのinit_PRIMARY0,init_PRIMARY1,...,init_PRIMARY9セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_PRIMARY[0-9]))); /* 入力ファイルのinit_PRIMARY10,init_PRIMARY11,...,init_PRIMARY99セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); /* シンボル__device_SECONDARY_startに現在のロケーションカウンタをセット。下記参照 */ __device_SECONDARY_start = .; /* 入力ファイルのinit_SECONDARY0,init_SECONDARY1,...,init_SECONDARY9セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_SECONDARY[0-9]))); /* 入力ファイルのinit_SECONDARY10,init_SECONDARY11,...,init_SECONDARY99セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); /* シンボル__device_NANOKERNEL_startに現在のロケーションカウンタをセット。下記参照 */ __device_NANOKERNEL_start = .; /* 入力ファイルのinit_NANOKERNEL0,init_NANOKERNEL1,...,init_NANOKERNEL9セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_NANOKERNEL[0-9]))); /* 入力ファイルのinit_NANOKERNEL10,init_NANOKERNEL11,...,init_NANOKERNEL99セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); /* シンボル__device_MICROKERNEL_startに現在のロケーションカウンタをセット。下記参照 */ __device_MICROKERNEL_start = .; /* 入力ファイルのinit_MICROKERNEL0,init_MICROKERNEL1,...,init_MICROKERNEL9セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_MICROKERNEL[0-9]))); /* 入力ファイルのinit_MICROKERNEL10,init_MICROKERNEL11,...,init_MICROKERNEL99セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); /* シンボル__device_APPLICATION_startに現在のロケーションカウンタをセット。下記参照 */ __device_APPLICATION_start = .; /* 入力ファイルのinit_APPLICATION0,init_APPLICATION1,...,init_APPLICATION9セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_APPLICATION[0-9]))); /* 入力ファイルのinit_APPLICATION10,init_APPLICATION11,...,init_APPLICATION99セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); /* シンボル__device_init_endに現在のロケーションカウンタをセット。下記参照 */ __device_init_end = .; } > RAM /* initlevelセクションを"RAM"リージョンに割り当てる */
_device_init_start grep 結果
$ grep _device_init_start * -RI include/linker-defs.h:#define DEVICE_COUNT ((__device_init_end - __device_init_start) / __DEVICE_STR_SIZEOF) include/linker-defs.h: __device_init_start = .; \ kernel/nanokernel/device.c:extern struct device __device_init_start[]; kernel/nanokernel/device.c: for (info = __device_init_start; info != __device_init_end; info++) { kernel/nanokernel/device.c: *device_list = __device_init_start; kernel/nanokernel/device.c: *device_count = __device_init_end - __device_init_start; kernel/nanokernel/device.c: (chk_dev - __device_init_start))) { kernel/nanokernel/device.c: (busy_dev - __device_init_start)); kernel/nanokernel/device.c: (busy_dev - __device_init_start)); samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (info = __device_init_start; info != __device_init_end; info++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (info = __device_init_start; info != __device_init_end; info++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001041e0 __device_init_start = .
_device_PRIMARY_start grep 結果
$ grep _device_PRIMARY_start * -RI kernel/nanokernel/device.c:extern struct device __device_PRIMARY_start[]; kernel/nanokernel/device.c: __device_PRIMARY_start, samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001041e0 __device_PRIMARY_start = .
_device_SECONDARY_start grep 結果
$ grep _device_SECONDARY_start * -RI kernel/nanokernel/device.c:extern struct device __device_SECONDARY_start[]; kernel/nanokernel/device.c: __device_SECONDARY_start, samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000104228 __device_SECONDARY_start = .
_device_NANOKERNEL_start grep 結果
$ grep _device_NANOKERNEL_start * -RI kernel/nanokernel/device.c:extern struct device __device_NANOKERNEL_start[]; kernel/nanokernel/device.c: __device_NANOKERNEL_start, samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000104240 __device_NANOKERNEL_start = .
_device_MICROKERNEL_start grep 結果
$ grep _device_MICROKERNEL_start * -RI kernel/nanokernel/device.c:extern struct device __device_MICROKERNEL_start[]; kernel/nanokernel/device.c: __device_MICROKERNEL_start, samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000104240 __device_MICROKERNEL_start = .
_device_APPLICATION_start grep 結果
$ grep _device_APPLICATION_start * -RI kernel/nanokernel/device.c:extern struct device __device_APPLICATION_start[]; kernel/nanokernel/device.c: __device_APPLICATION_start, samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x000000000010424c __device_APPLICATION_start = .
_device_init_end grep結果
$ grep _device_init_end * -RI include/linker-defs.h:#define DEVICE_COUNT ((__device_init_end - __device_init_start) / __DEVICE_STR_SIZEOF) include/linker-defs.h: __device_init_end = .; \ kernel/nanokernel/device.c:extern struct device __device_init_end[]; kernel/nanokernel/device.c: __device_init_end, kernel/nanokernel/device.c: for (info = __device_init_start; info != __device_init_end; info++) { kernel/nanokernel/device.c: *device_count = __device_init_end - __device_init_start; samples/hello_world/microkernel/outdir/final-linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __device_init_start = .; __device_PRIMARY_start = .; KEEP(*(SORT(.init_PRIMARY[0-9]))); KEEP(*(SORT(.init_PRIMARY[1-9][0-9]))); __device_SECONDARY_start = .; KEEP(*(SORT(.init_SECONDARY[0-9]))); KEEP(*(SORT(.init_SECONDARY[1-9][0-9]))); __device_NANOKERNEL_start = .; KEEP(*(SORT(.init_NANOKERNEL[0-9]))); KEEP(*(SORT(.init_NANOKERNEL[1-9][0-9]))); __device_MICROKERNEL_start = .; KEEP(*(SORT(.init_MICROKERNEL[0-9]))); KEEP(*(SORT(.init_MICROKERNEL[1-9][0-9]))); __device_APPLICATION_start = .; KEEP(*(SORT(.init_APPLICATION[0-9]))); KEEP(*(SORT(.init_APPLICATION[1-9][0-9]))); __device_init_end = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (info = __device_init_start; info != __device_init_end; info++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (info = __device_init_start; info != __device_init_end; info++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x000000000010424c __device_init_end = .
_k_task_list セクション
/* 出力ファイルの_k_task_listセクションに割り当てる */ /* 下記参照 */ _k_task_list ALIGN(4) : ALIGN(4) { /* シンボルk_task_list_startに現在のロケーションカウンタをセット。下記参照 */ _k_task_list_start = .; /* 入力ファイルの_k_task_list.public.*セクション */ *(._k_task_list.public.*) /* 入力ファイルの_k_task_list.private.*セクション */ *(._k_task_list.private.*) /* シンボルk_k_task_list_idle_startに現在のロケーションカウンタをセット。下記参照 */ _k_task_list_idle_start = .; /* 入力ファイルの_k_task_list.idle.*セクション */ *(._k_task_list.idle.*) /* 入力ファイルの_k_task_list*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT("._k_task_list*"))) /* シンボルk_k_task_list_endに現在のロケーションカウンタをセット。下記参照 */ _k_task_list_end = .; } > RAM /* _k_task_listセクションを"RAM"リージョンに割り当てる */
_k_task_list ALIGN(4) : ALIGN(4)
1番目のALIGN(4)は、_k_task_listセクションのVMA(virtual memory address:実行時にロードされるアドレス?)を、現在のロケーションカウンタを4バイトアライメントした値にする。3.6.3 Output Section Address 参照
2番目のALIGN(4)は、_k_task_listセクションのVMAを現在のロケーションカウンタを4バイトアライメントした値にする。あれ、1番目のALIGN(4)と同じだ。
3.6.8.3 Forced Output Alignment 参照
ただし、[Bug ld/18174] New: Improve documentation on Forced Output Section Align を参照すると、昔はVMAだけでなく、LMAにも影響を与えていたようなので、その名残か???。
TODO 二番目のALIGN(4)を削除してELFファイルを生成し、readelfで結果を確認する。
k_task_list_start grep結果
$ grep k_task_list_start * -RI include/arch/arc/v2/linker.ld: _k_task_list_start = .; include/arch/arc/v2/linker_harvard.ld: _k_task_list_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_task_list_start = .; include/arch/nios2/linker.ld: _k_task_list_start = .; include/arch/x86/linker-common-sections.h: _k_task_list_start = .; samples/hello_world/microkernel/outdir/final-linker.cmd: _k_task_list_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_task_list_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x000000000010424c _k_task_list_start = .
k_task_list_idle_start grep結果
$ grep k_task_list_idle_start * -RI include/arch/arc/v2/linker.ld: _k_task_list_idle_start = .; include/arch/arc/v2/linker_harvard.ld: _k_task_list_idle_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_task_list_idle_start = .; include/arch/nios2/linker.ld: _k_task_list_idle_start = .; include/arch/x86/linker-common-sections.h: _k_task_list_idle_start = .; samples/hello_world/microkernel/outdir/final-linker.cmd: _k_task_list_idle_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_task_list_idle_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x000000000010428c _k_task_list_idle_start = .
k_task_list_end grep結果
$ grep k_task_list_end * -RI include/arch/arc/v2/linker.ld: _k_task_list_end = .; include/arch/arc/v2/linker_harvard.ld: _k_task_list_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_task_list_end = .; include/arch/nios2/linker.ld: _k_task_list_end = .; include/arch/x86/linker-common-sections.h: _k_task_list_end = .; samples/hello_world/microkernel/outdir/final-linker.cmd: _k_task_list_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_task_list_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042cc _k_task_list_end = .
_k_task_ptr
/* 出力ファイルの_k_task_ptrセクションに割り当てる */ _k_task_ptr () : { /* シンボルk_k_task_ptr_startに現在のロケーションカウンタをセット。下記参照 */ _k_task_ptr_start = .; /* 入力ファイルの_k_task_ptr.public.*セクション */ *(._k_task_ptr.public.*) /* 入力ファイルの_k_task_ptr.private.*セクション */ *(._k_task_ptr.private.*) /* 入力ファイルの_k_task_ptr.idle.*セクション */ *(._k_task_ptr.idle.*) /* 入力ファイルの_k_task_ptr*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT("._k_task_ptr*"))) /* シンボル_k_task_ptr_endに現在のロケーションカウンタをセット。下記参照 */ _k_task_ptr_end = .; } > RAM /* _k_task_ptrセクションを"RAM"リージョンに割り当てる */
k_task_ptr_start grep結果
$ grep k_task_ptr_start * -RI include/arch/arc/v2/linker.ld: _k_task_ptr_start = .; include/arch/arc/v2/linker_harvard.ld: _k_task_ptr_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_task_ptr_start = .; include/arch/nios2/linker.ld: _k_task_ptr_start = .; include/arch/x86/linker-common-sections.h: _k_task_ptr_start = .; kernel/microkernel/k_task.c:extern ktask_t _k_task_ptr_start[]; kernel/microkernel/k_task.c: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/final-linker.cmd: _k_task_ptr_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_task_ptr_start = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042cc _k_task_ptr_start = .
k_task_ptr_end grep結果
$ grep k_task_ptr_end * -RI include/arch/arc/v2/linker.ld: _k_task_ptr_end = .; include/arch/arc/v2/linker_harvard.ld: _k_task_ptr_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_task_ptr_end = .; include/arch/nios2/linker.ld: _k_task_ptr_end = .; include/arch/x86/linker-common-sections.h: _k_task_ptr_end = .; kernel/microkernel/k_task.c:extern ktask_t _k_task_ptr_end[]; kernel/microkernel/k_task.c: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/final-linker.cmd: _k_task_ptr_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_task_ptr_end = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.lst: for (task_id = _k_task_ptr_start; task_id < _k_task_ptr_end; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_task_ptr_end = .
_k_pipe_ptrセクション
/* 出力ファイルの_k_pipe_ptrセクションに割り当てる */ _k_pipe_ptr () : { /* シンボル_k_pipe_ptr_startに現在のロケーションカウンタをセット。下記参照 */ _k_pipe_ptr_start = .; /* 入力ファイルの_k_pipe_ptr.public.*セクション */ *(._k_pipe_ptr.public.*) /* 入力ファイルの_k_pipe_ptr.private.*セクション */ *(._k_pipe_ptr.private.*) /* 入力ファイルの_k_pipe_ptr*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT("._k_pipe_ptr*"))) /* シンボル_k_pipe_ptr_endに現在のロケーションカウンタをセット。下記参照 */ _k_pipe_ptr_end = .; } > RAM /* _k_pipe_ptrセクションを"RAM"リージョンに割り当てる */
k_pipe_ptr_start grep結果
$ grep k_pipe_ptr_start * -RI include/arch/arc/v2/linker.ld: _k_pipe_ptr_start = .; include/arch/arc/v2/linker_harvard.ld: _k_pipe_ptr_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_pipe_ptr_start = .; include/arch/nios2/linker.ld: _k_pipe_ptr_start = .; include/arch/x86/linker-common-sections.h: _k_pipe_ptr_start = .; kernel/microkernel/k_pipe.c:extern kpipe_t _k_pipe_ptr_start[]; kernel/microkernel/k_pipe.c: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/final-linker.cmd: _k_pipe_ptr_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_pipe_ptr_start = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_pipe_ptr_start = .
k_pipe_ptr_end grep結果
$ grep k_pipe_ptr_end * -RI include/arch/arc/v2/linker.ld: _k_pipe_ptr_end = .; include/arch/arc/v2/linker_harvard.ld: _k_pipe_ptr_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_pipe_ptr_end = .; include/arch/nios2/linker.ld: _k_pipe_ptr_end = .; include/arch/x86/linker-common-sections.h: _k_pipe_ptr_end = .; kernel/microkernel/k_pipe.c:extern kpipe_t _k_pipe_ptr_end[]; kernel/microkernel/k_pipe.c: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/final-linker.cmd: _k_pipe_ptr_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_pipe_ptr_end = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (pipeId = _k_pipe_ptr_start; pipeId < _k_pipe_ptr_end; pipeId++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_pipe_ptr_end = .
_k_mem_map_ptr セクション
/* 出力ファイルの_k_mem_map_ptrセクションに割り当てる */ _k_mem_map_ptr () : { /* シンボル_k_mem_map_ptr_startに現在のロケーションカウンタをセット。下記参照 */ _k_mem_map_ptr_start = .; /* 入力ファイルの_k_mem_map_ptr.public.*セクション */ *(._k_mem_map_ptr.public.*) /* 入力ファイルの_k_mem_map_ptr.private.*セクション */ *(._k_mem_map_ptr.private.*) /* 入力ファイルの_k_mem_map_ptr*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT("._k_mem_map_ptr*"))) /* シンボル_k_mem_map_ptr_endに現在のロケーションカウンタをセット。下記参照 */ _k_mem_map_ptr_end = .; } > RAM /* _k_mem_map_ptrセクションを"RAM"リージョンに割り当てる */
k_mem_map_ptr_start grep結果
$ grep k_mem_map_ptr_start * -RI include/arch/arc/v2/linker.ld: _k_mem_map_ptr_start = .; include/arch/arc/v2/linker_harvard.ld: _k_mem_map_ptr_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_mem_map_ptr_start = .; include/arch/nios2/linker.ld: _k_mem_map_ptr_start = .; include/arch/x86/linker-common-sections.h: _k_mem_map_ptr_start = .; kernel/microkernel/k_memory_map.c:extern kmemory_map_t _k_mem_map_ptr_start[]; kernel/microkernel/k_memory_map.c: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/final-linker.cmd: _k_mem_map_ptr_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_mem_map_ptr_start = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_mem_map_ptr_start = .
k_mem_map_ptr_end grep結果
$ grep k_mem_map_ptr_end * -RI include/arch/arc/v2/linker.ld: _k_mem_map_ptr_end = .; include/arch/arc/v2/linker_harvard.ld: _k_mem_map_ptr_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_mem_map_ptr_end = .; include/arch/nios2/linker.ld: _k_mem_map_ptr_end = .; include/arch/x86/linker-common-sections.h: _k_mem_map_ptr_end = .; kernel/microkernel/k_memory_map.c:extern kmemory_map_t _k_mem_map_ptr_end[]; kernel/microkernel/k_memory_map.c: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/final-linker.cmd: _k_mem_map_ptr_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_mem_map_ptr_end = .; samples/hello_world/microkernel/outdir/zephyr.lst: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/zephyr.lst: for (id = _k_mem_map_ptr_start; id < _k_mem_map_ptr_end; id++) { samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_mem_map_ptr_end = . kawashimajun-no-MacBook-Air:zephyr-v1.4.0 junkawa$
_k_event_list セクション
/* 出力ファイルの_k_event_listセクションに割り当てる */ _k_event_list () : { /* シンボル_k_event_list_startに現在のロケーションカウンタをセット。下記参照 */ _k_event_list_start = .; /* 入力ファイルの_k_event_list.event.*セクション */ *(._k_event_list.event.*) /* 入力ファイルの_k_event_list*セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT("._k_event_list*"))) /* シンボル_k_event_list_endに現在のロケーションカウンタをセット。下記参照 */ _k_event_list_end = .; } > RAM /* _k_event_listセクションを"RAM"リージョンに割り当てる */
k_event_list_start grep結果
$ grep k_event_list_start * -RI include/arch/arc/v2/linker.ld: _k_event_list_start = .; include/arch/arc/v2/linker_harvard.ld: _k_event_list_start = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_event_list_start = .; include/arch/nios2/linker.ld: _k_event_list_start = .; include/arch/x86/linker-common-sections.h: _k_event_list_start = .; kernel/microkernel/k_event.c:extern kevent_t _k_event_list_start[]; kernel/microkernel/k_event.c: __ASSERT((vaddr_t)e >= (vaddr_t)&_k_event_list_start,\ samples/hello_world/microkernel/outdir/final-linker.cmd: _k_event_list_start = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_event_list_start = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042d4 _k_event_list_start = .
k_event_list_end grep結果
$ grep k_event_list_end * -RI include/arch/arc/v2/linker.ld: _k_event_list_end = .; include/arch/arc/v2/linker_harvard.ld: _k_event_list_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _k_event_list_end = .; include/arch/nios2/linker.ld: _k_event_list_end = .; include/arch/x86/linker-common-sections.h: _k_event_list_end = .; kernel/microkernel/k_event.c:extern kevent_t _k_event_list_end[]; kernel/microkernel/k_event.c: __ASSERT((vaddr_t)e < (vaddr_t)&_k_event_list_end, \ samples/hello_world/microkernel/outdir/final-linker.cmd: _k_event_list_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _k_event_list_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042e4 _k_event_list_end = . tests/kernel/test_events/src/events.c:extern kevent_t _k_event_list_end[];
__data_ram_end シンボル
/* シンボル__data_ram_endに現在のロケーションカウンタをセット。下記参照 */ __data_ram_end = .;
_data_ram_end grep結果
$ grep _data_ram_end * -RI include/arch/arc/v2/linker.ld: __data_ram_end = .; include/arch/arc/v2/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/arc/v2/linker_harvard.ld: __data_ram_end = .; include/arch/arc/v2/linker_harvard.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/arm/cortex_m/scripts/linker.ld: __data_ram_end = .; include/arch/arm/cortex_m/scripts/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/nios2/linker.ld: __data_ram_end = .; include/arch/nios2/linker.ld:__data_size = (__data_ram_end - __data_ram_start); include/arch/x86/linker-common-sections.h: __data_ram_end = .; include/arch/x86/linker-common-sections.h:__data_size = (__data_ram_end - __data_ram_start); samples/hello_world/microkernel/outdir/final-linker.cmd: __data_ram_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __data_ram_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042e4 __data_ram_end = .
bss セクション
/* 出力ファイルのbssセクションに割り当てる。NOLOADは下記参照 */ /* bss:4.5 bss Section */ bss (NOLOAD ) : { /* 現在のロケーションカウンタを4バイトアライメントする */ . = ALIGN(4); /* シンボル__bss_startに現在のロケーションカウンタをセット。下記参照 */ __bss_start = .; /* 入力ファイルのbssセクション */ *(.bss) /* 入力ファイルのbss.*セクション */ *(".bss.*") /* 入力ファイルのCOMMONセクション */ /* COMMON: 3.6.4.3 Input Section for Common Symbols*/ *(COMMON) /* 現在のロケーションカウンタを4バイトアライメントする */ . = ALIGN(4); /* シンボル__bss_endに現在のロケーションカウンタをセット。下記参照 */ __bss_end = .; } > RAM /* bssセクションを"RAM"リージョンに割り当てる */bss ALIGN(4) : と、. = ALIGN(4); は同じになる? (セクションをアライメントすると、そのセクション内のロケーションカウンタもアライメントされる?)
セクションでロードされないから、ロケーションカウンタでアドレスだけ指定している?
bss (NOLOAD ) :
3.6.8.1 Output Section TypeNOLOAD The section should be marked as not loadable, so that it will not be loaded into memory when the program is run.
_bss_start grep結果
$ grep _bss_start * -RI arch/arc/core/prep_c.c: volatile uint32_t *pBSS = (uint32_t *)&__bss_start; arch/arm/core/cortex_m/prep_c.c: volatile uint32_t *pBSS = (uint32_t *)&__bss_start; arch/nios2/core/prep_c.c: volatile uint32_t *pBSS = (uint32_t *)&__bss_start; arch/x86/core/crt0.S: * Clear BSS: bzero (__bss_start, __bss_num_words*4) arch/x86/core/crt0.S: movl $__bss_start, %edi /* load BSS start address */ arch/x86/core/crt0.S: movl $__bss_start, %edi /* load BSS start address */ include/arch/arc/v2/linker.ld: __bss_start = .; include/arch/arc/v2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arc/v2/linker_harvard.ld: __bss_start = .; include/arch/arc/v2/linker_harvard.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arm/cortex_m/scripts/linker.ld: __bss_start = .; include/arch/arm/cortex_m/scripts/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/nios2/linker.ld: __bss_start = .; include/arch/nios2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/x86/linker-common-sections.h: __bss_start = .; include/arch/x86/linker-common-sections.h: __bss_num_words = (__bss_end - __bss_start) >> 2; include/linker-defs.h:GDATA(__bss_start) include/linker-defs.h:extern char __bss_start[]; samples/hello_world/microkernel/outdir/final-linker.cmd: __bss_start = .; samples/hello_world/microkernel/outdir/final-linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/linker.cmd: __bss_start = .; samples/hello_world/microkernel/outdir/linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/zephyr.lst: movl $__bss_start, %edi /* load BSS start address */ samples/hello_world/microkernel/outdir/zephyr.map: 0x00000000001042e8 __bss_start = . samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000012 __bss_num_words = ((__bss_end - __bss_start) >> 0x2)
_bss_end grep結果
$ grep _bss_end * -RI include/arch/arc/v2/linker.ld: __bss_end = ALIGN(4); include/arch/arc/v2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arc/v2/linker_harvard.ld: __bss_end = ALIGN(4); include/arch/arc/v2/linker_harvard.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arm/cortex_m/scripts/linker.ld: __bss_end = ALIGN(4); include/arch/arm/cortex_m/scripts/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/nios2/linker.ld: __bss_end = ALIGN(4); include/arch/nios2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/x86/linker-common-sections.h: __bss_end = .; include/arch/x86/linker-common-sections.h: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/final-linker.cmd: __bss_end = .; samples/hello_world/microkernel/outdir/final-linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/linker.cmd: __bss_end = .; samples/hello_world/microkernel/outdir/linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000104330 __bss_end = . samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000012 __bss_num_words = ((__bss_end - __bss_start) >> 0x2)
noinitセクション
/* 出力ファイルのnoinitセクションに割り当てる。NOLOADは下記参照 */ noinit (NOLOAD ) : { /* 入力ファイルのnoinitセクション */ *(.noinit) /* 入力ファイルのnoinit.*セクション */ *(".noinit.*") /* 入力ファイルのintStubSectセクション。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(.intStubSect)) } > RAM /* nonitセクションを"RAM"リージョンに割り当てる */
noinit (NOLOAD ) :
3.6.8.1 Output Section TypeNOLOAD The section should be marked as not loadable, so that it will not be loaded into memory when the program is run.
image_ram_end シンボル
/* シンボルimage_ram_endに現在のロケーションカウンタをセット。下記参照 */ image_ram_end = .;
image_ram_end grep結果
$ grep image_ram_end * -RI include/arch/arc/v2/linker.ld: _image_ram_end = .; include/arch/arc/v2/linker_harvard.ld: _image_ram_end = .; include/arch/arm/cortex_m/scripts/linker.ld: _image_ram_end = .; include/arch/nios2/linker.ld: _image_ram_end = .; include/arch/x86/linker-common-sections.h: _image_ram_end = .; include/linker-defs.h:extern char _image_ram_end[]; misc/debug/mem_safe_check_boundaries.c:#define IMAGE_RAM_END ((vaddr_t)&_image_ram_end) samples/hello_world/microkernel/outdir/final-linker.cmd: _image_ram_end = .; samples/hello_world/microkernel/outdir/linker.cmd: _image_ram_end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000105c40 _image_ram_end = . tests/kernel/test_mem_safe/src/main.c:#define RAM_END ((uint32_t)&_image_ram_end) tests/kernel/test_mem_safe/src/main.c:char * const p_image_ram_end = (char *)RAM_END; tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_ram_end - 1, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_write(p_image_ram_end - 1, 1, 0)); tests/kernel/test_mem_safe/src/main.c: update_rv(&rv, test_width_read(p_image_ram_end, 1, -EFAULT));
_end シンボル
/* シンボル_endに現在のロケーションカウンタをセット。下記参照 */ _end = .;
" _end" grep結果
$ grep " _end" * -RI include/arch/arm/cortex_m/scripts/linker.ld: _end = .; /* end of image */ include/arch/nios2/linker.ld: _end = .; /* end of image */ include/linker-defs.h:extern char _end[]; samples/hello_world/microkernel/outdir/final-linker.cmd: _end = .; samples/hello_world/microkernel/outdir/linker.cmd: _end = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000105c40 _end = .
現在のロケーションカウンタ
/* 現在のロケーションカウンタを4096バイト(4KB)アライメントする */ . = ALIGN(((4) << 10));
__bss_num_words シンボル
/* シンボル__bss_num_wordsに 出力bss領域のワード数(1ワード=4バイトで換算)をセット。下記参照 */ __bss_num_words = (__bss_end - __bss_start) >> 2;
_bss_num_words grep結果
$ grep _bss_num_words * -RI arch/arc/core/prep_c.c: for (n = 0; n < (unsigned int)&__bss_num_words; n++) { arch/arm/core/cortex_m/prep_c.c: for (n = 0; n < (unsigned int)&__bss_num_words; n++) { arch/nios2/core/prep_c.c: for (n = 0; n < (unsigned int)&__bss_num_words; n++) { arch/x86/core/crt0.S: * Clear BSS: bzero (__bss_start, __bss_num_words*4) arch/x86/core/crt0.S: movl $__bss_num_words, %ecx /* number of quad bytes in .bss */ arch/x86/core/crt0.S: movl $__bss_num_words, %ecx /* number of quad bytes */ include/arch/arc/v2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arc/v2/linker_harvard.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/arm/cortex_m/scripts/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/nios2/linker.ld: __bss_num_words = (__bss_end - __bss_start) >> 2; include/arch/x86/linker-common-sections.h: __bss_num_words = (__bss_end - __bss_start) >> 2; include/linker-defs.h:GDATA(__bss_num_words) include/linker-defs.h:extern int __bss_num_words[]; samples/hello_world/microkernel/outdir/final-linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/linker.cmd: __bss_num_words = (__bss_end - __bss_start) >> 2; samples/hello_world/microkernel/outdir/zephyr.lst: movl $__bss_num_words, %ecx /* number of quad bytes */ samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000012 __bss_num_words = ((__bss_end - __bss_start) >> 0x2)
intList セクション
initList セクションは、 isrList.bin バイナリファイルとして抜き出される。前の記事の isrList.bin 参照
/* 出力ファイルのintListセクションに割り当てる */ intList () : { /* 入力ファイルのspurIsrセクション。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ /* (恐らく) struct genidt_header_s の void *spurious_addr; */ KEEP(*(.spurIsr)) /* 入力ファイルのspurNoErrIsrセクション。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ /* (恐らく) struct genidt_header_s の void *spurious_no_error_addr; */ KEEP(*(.spurNoErrIsr)) /* シンボル__INT_LIST_START__に現在のロケーションカウンタをセット。下記参照 */ __INT_LIST_START__ = .; /* 下記参照*/ /* (恐らく) struct genidt_header_s の unsigned int num_entries; */ LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) /* 入力ファイルの.intListセクション。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ /* (恐らく) struct genidt_entry_s []*/ KEEP(*(.intList)) /* シンボル__INT_LIST_END__に現在のロケーションカウンタをセット。下記参照 */ __INT_LIST_END__ = .; } > IDT_LIST /* intListセクションを"IDT_LIST"リージョンに割り当てる */
LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14)
LONG: 3.6.5 Output Section Data参照入力ファイルの.intListセクションのサイズを20 (0x14)で割った値を、現在のロケーションカウンタに(?)セットする。
20は、struct genidt_entry_s 構造体のサイズ。LONG()でセットするのは、割り込み・例外のエントリ数。
前の記事の isrList.bin 参照
__INT_LIST_START__ grep結果
$ grep __INT_LIST_START__ * -RI include/arch/x86/linker-common-sections.h: __INT_LIST_START__ = .; include/arch/x86/linker-common-sections.h: LONG((__INT_LIST_END__ - __INT_LIST_START__) / __ISR_LIST_SIZEOF) samples/hello_world/microkernel/outdir/final-linker.cmd: __INT_LIST_START__ = .; samples/hello_world/microkernel/outdir/final-linker.cmd: LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) samples/hello_world/microkernel/outdir/linker.cmd: __INT_LIST_START__ = .; samples/hello_world/microkernel/outdir/linker.cmd: LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000808 __INT_LIST_START__ = . samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000808 0x4 LONG 0x10 ((__INT_LIST_END__ - __INT_LIST_START__) / 0x14)
__INT_LIST_END__ grep結果
$ grep __INT_LIST_END__ * -RI include/arch/x86/linker-common-sections.h: LONG((__INT_LIST_END__ - __INT_LIST_START__) / __ISR_LIST_SIZEOF) include/arch/x86/linker-common-sections.h: __INT_LIST_END__ = .; samples/hello_world/microkernel/outdir/final-linker.cmd: LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) samples/hello_world/microkernel/outdir/final-linker.cmd: __INT_LIST_END__ = .; samples/hello_world/microkernel/outdir/linker.cmd: LONG((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) samples/hello_world/microkernel/outdir/linker.cmd: __INT_LIST_END__ = .; samples/hello_world/microkernel/outdir/zephyr.map: 0x0000000000000808 0x4 LONG 0x10 ((__INT_LIST_END__ - __INT_LIST_START__) / 0x14) samples/hello_world/microkernel/outdir/zephyr.map: 0x000000000000094c __INT_LIST_END__ = .
initlevel_error セクション
/* 出力ファイルのinitlevel_errorセクションに割り当てる */ initlevel_error () : { /* 入力ファイルのinit__,init_A,init_B,...,init_Z,init_0,init_1,...,init_9(?)セクションを名前で昇順に並び替える(SORT)。リンク時ガベージコレクションで未使用のセクションが削除されないようにする(KEEP) */ KEEP(*(SORT(.init_[_A-Z0-9]*))) }
ASSERTマクロ
ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")initlevel_error セクション のサイズが 0 の場合、エラーを表示して処理を終了する。
SIZEOF: 3.10.9 Builtin Functions 参照。 ASSERT: 3.4.5 Other Linker Script Commands 参照。
}
}SECITONSコマンドの終了。
SECTIONS
SECTIONS { .shstrtab 0 (): { *(.shstrtab) } .symtab 0 (): { *(.symtab) } .strtab 0 (): { *(.strtab) } .iplt 0 (): { *(.iplt) } .igot.plt 0 (): { *(.igot.plt) } .rel.plt 0 (): { *(.rel.plt) } .rela.plt 0 (): { *(.rela.plt) } .rel.dyn 0 (): { *(".rel.*") } .rela.dyn 0 (): { *(".rela.*") } .comment 0 (): { *(.comment) } .debug 0 (): { *(.debug) } .line 0 (): { *(.line) } .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } .debug_aranges 0 (): { *(.debug_aranges) } .debug_pubnames 0 (): { *(.debug_pubnames) } .debug_pubtypes 0 (): { *(.debug_pubtypes) } .debug_line 0 (): { *(.debug_line) } .debug_info 0 (): { *(.debug_info) } .debug_macinfo 0 (): { *(.debug_macinfo) } .debug_abbrev 0 (): { *(.debug_abbrev) } .debug_loc 0 (): { *(.debug_loc) } .debug_ranges 0 (): { *(.debug_ranges) } .debug_str 0 (): { *(.debug_str) } .debug_frame 0 (): { *(.debug_frame) } .debug_macro 0 (): { *(.debug_macro) }実行時にロードしない、入力ファイルのセクションたち(?)。
実行時にロードするアドレスを0として指定している。(どういう意味がある?バイナリファイル内の配置(LMA)に関係する?) 3.6.3 Output Section Addressみる限り、LMAには関係しないはず。(TODO)
.trashcanセクション
.trashcan : { *(.*) }上記で指定していない入力ファイルのセクションを確認するために、trashcanセクションに集める(?)
}
}SECTIONコマンドの終了
ASSERTマクロ
ASSERT(SIZEOF(.trashcan) == 0, "Section(s) undefined in the linker script used.")明示的に指定していないセクションがあった場合(trashcanセクションが0サイズでない場合)、エラーを表示して処理を終了する。 TODO readlef結果
コメント