arch/x86: complete 64-bit linker script

The previous linker script was barebones and non-standard. It is
replaced with a script conforms to the rest of the Zephyr arches,
utilizing include/linker headers and standard macros.

link-tool-gcc.h is updated to account for the "i386:x86-64" arch and
the generation of 64-bit ELF binaries.

Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
Charles E. Youse 2019-07-22 12:25:07 -07:00 committed by Andrew Boie
commit 3cf1bff71c
3 changed files with 78 additions and 58 deletions

View file

@ -3,70 +3,75 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define DEVICE_INIT_LEVEL(level) \ #define _LINKER
__device_##level##_start = .; \ #define _ASMLANGUAGE
KEEP(*(SORT(.init_##level[0-9]))); \
KEEP(*(SORT(.init_##level[1-9][0-9]))); #include <linker/linker-defs.h>
#include <linker/linker-tool.h>
#define ROMABLE_REGION RAM
#define RAMABLE_REGION RAM
ENTRY(CONFIG_KERNEL_ENTRY) ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS SECTIONS
{ {
/* /*
* The "locore" must be in the 64K of RAM, so that 16-bit code (with * The "locore" must be in the 64K of RAM, so that 16-bit code (with
* segment registers == 0x0000) and 32/64-bit code agree on addresses. * segment registers == 0x0000) and 32/64-bit code agree on addresses.
* ... there is no 16-bit code yet, but there will be when we add SMP. * ... there is no 16-bit code yet, but there will be when we add SMP.
*/ */
.locore 0x8000 : ALIGN(16) .locore 0x8000 : ALIGN(16)
{ {
*(.locore) *(.locore)
*(.locore.*) *(.locore.*)
} }
/* /*
* The parts of the system that don't benefit from being in the locore * The rest of the system is loaded in "normal" memory (typically
* start at the 1MB mark, otherwise the system size would be artificially * placed above 1MB to avoid the by memory hole at 0x90000-0xFFFFF).
* clamped by the ISA memory hole/ROM space at 0x90000-0xFFFFF. */
*/
.text 0x100000 : ALIGN(16) SECTION_PROLOGUE(_TEXT_SECTION_NAME,,ALIGN(16))
{ {
*(.text) *(.text)
*(.text.*) *(.text.*)
} GROUP_LINK_IN(ROMABLE_REGION)
#include <linker/common-rom.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(16))
{
_image_rodata_start = .;
*(.rodata)
*(.rodata.*) *(.rodata.*)
. = ALIGN(8); #include <snippets-rodata.ld>
__devconfig_start = .;
*(.devconfig.*)
KEEP(*(SORT_BY_NAME(.devconfig*)))
__devconfig_end = .;
}
.data : ALIGN(16) #ifdef CONFIG_CUSTOM_RODATA_LD
#include <custom-rodata.ld>
#endif /* CONFIG_CUSTOM_RODATA_LD */
_image_rodata_end = .;
_image_rodata_size = _image_rodata_end - _image_rodata_start;
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(_DATA_SECTION_NAME,,ALIGN(16))
{ {
*(.data*) *(.data)
*(.data.*)
#include <snippets-rwdata.ld>
#ifdef CONFIG_CUSTOM_RWDATA_LD
#include <custom-rwdata.ld>
#endif /* CONFIG_CUSTOM_RWDATA_LD */
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
. = ALIGN(8); #include <snippets-ram-sections.ld>
__device_init_start = .; #include <linker/common-ram.ld>
DEVICE_INIT_LEVEL(PRE_KERNEL_1)
DEVICE_INIT_LEVEL(PRE_KERNEL_2)
DEVICE_INIT_LEVEL(POST_KERNEL)
DEVICE_INIT_LEVEL(APPLICATION)
__device_init_end = .;
. = ALIGN(8); SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD), ALIGN(16))
__static_thread_data_list_start = .;
KEEP(*(SORT_BY_NAME(.__static_thread_data.static.*)))
__static_thread_data_list_end = .;
. = ALIGN(8);
_k_mem_pool_list_start = .;
KEEP(*(._k_mem_pool_static.*))
_k_mem_pool_list_end = .;
}
.bss : ALIGN(16)
{ {
__bss_start = .; __bss_start = .;
*(.bss) *(.bss)
@ -74,23 +79,37 @@ SECTIONS
*(COMMON) *(COMMON)
. = ALIGN(8); /* so __bss_num_qwords is exact */ . = ALIGN(8); /* so __bss_num_qwords is exact */
__bss_end = .; __bss_end = .;
} } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
__bss_num_qwords = (__bss_end - __bss_start) >> 3; __bss_num_qwords = (__bss_end - __bss_start) >> 3;
.noinit (NOLOAD) : ALIGN(16) SECTION_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD), ALIGN(16))
{ {
*(.noinit)
*(.noinit.*) *(.noinit.*)
} #include <snippets-noinit.ld>
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
/DISCARD/ : #include <snippets-sections.ld>
#ifdef CONFIG_CUSTOM_SECTIONS_LD
#include <custom-sections.ld>
#endif /* CONFIG_CUSTOM_SECTIONS_LD */
. = ALIGN(8);
_end = .;
/DISCARD/ :
{ {
*(.comment*) *(.comment*)
*(.debug*) *(.debug*)
*(.got*) *(.got)
*(.igot.*) *(.got.plt)
*(.igot)
*(.igot.plt)
*(.iplt) *(.iplt)
*(.plt)
*(.note.GNU-stack) *(.note.GNU-stack)
*(.rel.*)
*(.rela.*) *(.rela.*)
} }
} }

View file

@ -25,8 +25,13 @@
#elif defined(CONFIG_ARC) #elif defined(CONFIG_ARC)
OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc")
#elif defined(CONFIG_X86) #elif defined(CONFIG_X86)
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") #if defined (CONFIG_X86_LONGMODE)
OUTPUT_ARCH("i386") OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH("i386:x86-64")
#else
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH("i386")
#endif
#elif defined(CONFIG_NIOS2) #elif defined(CONFIG_NIOS2)
OUTPUT_FORMAT("elf32-littlenios2", "elf32-bignios2", "elf32-littlenios2") OUTPUT_FORMAT("elf32-littlenios2", "elf32-bignios2", "elf32-littlenios2")
#elif defined(CONFIG_RISCV) #elif defined(CONFIG_RISCV)

View file

@ -8,12 +8,6 @@
#include <autoconf.h> #include <autoconf.h>
#include <generated_dts_board.h> #include <generated_dts_board.h>
#ifdef CONFIG_X86_LONGMODE
#include <arch/x86/intel64/linker.ld>
#else /* IA32 */
#define PHYS_LOAD_ADDR DT_PHYS_RAM_ADDR #define PHYS_LOAD_ADDR DT_PHYS_RAM_ADDR
#define PHYS_RAM_ADDR DT_PHYS_RAM_ADDR #define PHYS_RAM_ADDR DT_PHYS_RAM_ADDR
@ -30,6 +24,8 @@ MEMORY
IDT_LIST : ORIGIN = 2K, LENGTH = 2K IDT_LIST : ORIGIN = 2K, LENGTH = 2K
} }
#ifdef CONFIG_X86_LONGMODE
#include <arch/x86/intel64/linker.ld>
#else
#include <arch/x86/ia32/linker.ld> #include <arch/x86/ia32/linker.ld>
#endif /* CONFIG_X86_LONGMODE */ #endif /* CONFIG_X86_LONGMODE */