diff options
Diffstat (limited to 'arch/arm/kernel/vmlinux.lds.S')
| -rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 278 |
1 files changed, 70 insertions, 208 deletions
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index fa25e4e425f6..d592a203f9c6 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -1,46 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ -#include <asm-generic/vmlinux.lds.h> +#ifdef CONFIG_XIP_KERNEL +#include "vmlinux-xip.lds.S" +#else + +#include <linux/pgtable.h> +#include <asm/vmlinux.lds.h> #include <asm/cache.h> #include <asm/thread_info.h> -#include <asm/memory.h> #include <asm/page.h> - -#define PROC_INFO \ - . = ALIGN(4); \ - VMLINUX_SYMBOL(__proc_info_begin) = .; \ - *(.proc.info.init) \ - VMLINUX_SYMBOL(__proc_info_end) = .; - -#define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - VMLINUX_SYMBOL(__idmap_text_start) = .; \ - *(.idmap.text) \ - VMLINUX_SYMBOL(__idmap_text_end) = .; \ - . = ALIGN(32); \ - VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ - *(.hyp.idmap.text) \ - VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; - -#ifdef CONFIG_HOTPLUG_CPU -#define ARM_CPU_DISCARD(x) -#define ARM_CPU_KEEP(x) x -#else -#define ARM_CPU_DISCARD(x) x -#define ARM_CPU_KEEP(x) -#endif - -#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ - defined(CONFIG_GENERIC_BUG) -#define ARM_EXIT_KEEP(x) x -#define ARM_EXIT_DISCARD(x) -#else -#define ARM_EXIT_KEEP(x) -#define ARM_EXIT_DISCARD(x) x -#endif +#include <asm/mpu.h> OUTPUT_ARCH(arm) ENTRY(stext) @@ -63,92 +36,60 @@ SECTIONS * unwind sections get included. */ /DISCARD/ : { - *(.ARM.exidx.exit.text) - *(.ARM.extab.exit.text) - ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) - ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) - ARM_EXIT_DISCARD(EXIT_TEXT) - ARM_EXIT_DISCARD(EXIT_DATA) - EXIT_CALL -#ifndef CONFIG_MMU - *(.fixup) - *(__ex_table) -#endif + ARM_DISCARD #ifndef CONFIG_SMP_ON_UP *(.alt.smp.init) #endif - *(.discard) - *(.discard.*) +#ifndef CONFIG_ARM_UNWIND + *(.ARM.exidx) *(.ARM.exidx.*) + *(.ARM.extab) *(.ARM.extab.*) +#endif } -#ifdef CONFIG_XIP_KERNEL - . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); -#else - . = PAGE_OFFSET + TEXT_OFFSET; -#endif + . = KERNEL_OFFSET + TEXT_OFFSET; .head.text : { _text = .; HEAD_TEXT } + +#ifdef CONFIG_STRICT_KERNEL_RWX + . = ALIGN(1<<SECTION_SHIFT); +#endif + +#ifdef CONFIG_ARM_MPU + . = ALIGN(PMSAv8_MINALIGN); +#endif .text : { /* Real text segment */ _stext = .; /* Text and read-only data */ - __exception_text_start = .; - *(.exception.text) - __exception_text_end = .; - IRQENTRY_TEXT - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - IDMAP_TEXT -#ifdef CONFIG_MMU - *(.fixup) -#endif - *(.gnu.warning) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); - *(.got) /* Global offset table */ - ARM_CPU_KEEP(PROC_INFO) + ARM_TEXT } +#ifdef CONFIG_DEBUG_ALIGN_RODATA + . = ALIGN(1<<SECTION_SHIFT); +#endif + _etext = .; /* End of text section */ + RO_DATA(PAGE_SIZE) . = ALIGN(4); __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { __start___ex_table = .; -#ifdef CONFIG_MMU - *(__ex_table) -#endif + ARM_MMU_KEEP(*(__ex_table)) __stop___ex_table = .; } #ifdef CONFIG_ARM_UNWIND - /* - * Stack unwinding tables - */ - . = ALIGN(8); - .ARM.unwind_idx : { - __start_unwind_idx = .; - *(.ARM.exidx*) - __stop_unwind_idx = .; - } - .ARM.unwind_tab : { - __start_unwind_tab = .; - *(.ARM.extab*) - __stop_unwind_tab = .; - } + ARM_UNWIND_SECTIONS #endif - NOTES - - _etext = .; /* End of text and rodata section */ - -#ifndef CONFIG_XIP_KERNEL +#ifdef CONFIG_STRICT_KERNEL_RWX + . = ALIGN(1<<SECTION_SHIFT); +#else . = ALIGN(PAGE_SIZE); - __init_begin = .; #endif + __init_begin = .; + ARM_VECTORS INIT_TEXT_SECTION(8) .exit.text : { ARM_EXIT_KEEP(EXIT_TEXT) @@ -158,7 +99,7 @@ SECTIONS } .init.arch.info : { __arch_info_begin = .; - *(.arch.info.init) + KEEP(*(.arch.info.init)) __arch_info_end = .; } .init.tagtable : { @@ -175,144 +116,65 @@ SECTIONS #endif .init.pv_table : { __pv_table_begin = .; - *(.pv_table) + KEEP(*(.pv_table)) __pv_table_end = .; } - .init.data : { -#ifndef CONFIG_XIP_KERNEL - INIT_DATA -#endif - INIT_SETUP(16) - INIT_CALLS - CON_INITCALL - SECURITY_INITCALL - INIT_RAM_FS - } -#ifndef CONFIG_XIP_KERNEL + + INIT_DATA_SECTION(16) + .exit.data : { ARM_EXIT_KEEP(EXIT_DATA) } -#endif #ifdef CONFIG_SMP PERCPU_SECTION(L1_CACHE_BYTES) #endif -#ifdef CONFIG_XIP_KERNEL - __data_loc = ALIGN(4); /* location in binary */ - . = PAGE_OFFSET + TEXT_OFFSET; -#else - __init_end = .; - . = ALIGN(THREAD_SIZE); - __data_loc = .; +#ifdef CONFIG_HAVE_TCM + ARM_TCM #endif - .data : AT(__data_loc) { - _data = .; /* address in memory */ - _sdata = .; - - /* - * first, the init task union, aligned - * to an 8192 byte boundary. - */ - INIT_TASK_DATA(THREAD_SIZE) - -#ifdef CONFIG_XIP_KERNEL - . = ALIGN(PAGE_SIZE); - __init_begin = .; - INIT_DATA - ARM_EXIT_KEEP(EXIT_DATA) - . = ALIGN(PAGE_SIZE); - __init_end = .; +#ifdef CONFIG_STRICT_KERNEL_RWX + . = ALIGN(1<<SECTION_SHIFT); +#else + . = ALIGN(THREAD_ALIGN); #endif + __init_end = .; - NOSAVE_DATA - CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) - READ_MOSTLY_DATA(L1_CACHE_BYTES) - - /* - * and the usual data section - */ - DATA_DATA - CONSTRUCTORS - - _edata = .; - } - _edata_loc = __data_loc + SIZEOF(.data); - -#ifdef CONFIG_HAVE_TCM - /* - * We align everything to a page boundary so we can - * free it after init has commenced and TCM contents have - * been copied to its destination. - */ - .tcm_start : { - . = ALIGN(PAGE_SIZE); - __tcm_start = .; - __itcm_start = .; - } - - /* - * Link these to the ITCM RAM - * Put VMA to the TCM address and LMA to the common RAM - * and we'll upload the contents from RAM to TCM and free - * the used RAM after that. - */ - .text_itcm ITCM_OFFSET : AT(__itcm_start) - { - __sitcm_text = .; - *(.tcm.text) - *(.tcm.rodata) - . = ALIGN(4); - __eitcm_text = .; - } - - /* - * Reset the dot pointer, this is needed to create the - * relative __dtcm_start below (to be used as extern in code). - */ - . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm); - - .dtcm_start : { - __dtcm_start = .; - } - - /* TODO: add remainder of ITCM as well, that can be used for data! */ - .data_dtcm DTCM_OFFSET : AT(__dtcm_start) - { - . = ALIGN(4); - __sdtcm_data = .; - *(.tcm.data) - . = ALIGN(4); - __edtcm_data = .; - } - - /* Reset the dot pointer or the linker gets confused */ - . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm); - - /* End marker for freeing TCM copy in linked object */ - .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){ - . = ALIGN(PAGE_SIZE); - __tcm_end = .; - } -#endif + _sdata = .; + RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) + _edata = .; BSS_SECTION(0, 0, 0) +#ifdef CONFIG_ARM_MPU + . = ALIGN(PMSAv8_MINALIGN); +#endif _end = .; STABS_DEBUG - .comment 0 : { *(.comment) } + DWARF_DEBUG + ARM_DETAILS + + ARM_ASSERTS } +#ifdef CONFIG_STRICT_KERNEL_RWX +/* + * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will + * be the first section-aligned location after __start_rodata. Otherwise, + * it will be equal to __start_rodata. + */ +__start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT); +#endif + /* * These must never be empty * If you have to comment these two assert statements out, your * binutils is too old (for other reasons as well) */ ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") +#ifndef CONFIG_COMPILE_TEST ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") -/* - * The HYP init code can't be more than a page long. - * The above comment applies as well. - */ -ASSERT(((__hyp_idmap_text_end - __hyp_idmap_text_start) <= PAGE_SIZE), "HYP init code too big") +#endif + +#endif /* CONFIG_XIP_KERNEL */ |
