#ifdef CONFIG_PPC64
-#include <asm/page.h>
#define PROVIDE32(x) PROVIDE(__unused__##x)
#else
-#define PAGE_SIZE 4096
-#define KERNELBASE CONFIG_KERNEL_START
#define PROVIDE32(x) PROVIDE(x)
#endif
+#include <asm/page.h>
#include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
ENTRY(_stext)
+PHDRS {
+ kernel PT_LOAD FLAGS(7); /* RWX */
+ notes PT_NOTE FLAGS(0);
+ dummy PT_NOTE FLAGS(0);
+
+ /* binutils < 2.18 has a bug that makes it misbehave when taking an
+ ELF file with all segments at load address 0 as input. This
+ happens when running "strip" on vmlinux, because of the AT() magic
+ in this linker script. People using GCC >= 4.2 won't run into
+ this problem, because the "build-id" support will put some data
+ into the "notes" segment (at a non-zero load address).
+
+ To work around this, we force some data into both the "dummy"
+ segment and the kernel segment, so the dummy segment will get a
+ non-zero load address. It's not enough to always create the
+ "notes" segment, since if nothing gets assigned to it, its load
+ address will be zero. */
+}
+
#ifdef CONFIG_PPC64
OUTPUT_ARCH(powerpc:common64)
jiffies = jiffies_64;
#endif
SECTIONS
{
- /* Sections to be discarded. */
- /DISCARD/ : {
- *(.exitcall.exit)
- *(.exit.data)
- }
-
. = KERNELBASE;
/*
*/
/* Text and gots */
- .text : {
- *(.text .text.*)
+ .text : AT(ADDR(.text) - LOAD_OFFSET) {
+ ALIGN_FUNCTION();
+ HEAD_TEXT
+ _text = .;
+ /* careful! __ftr_alt_* sections need to be close to .text */
+ *(.text .fixup __ftr_alt_* .ref.text)
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
- *(.fixup)
+ IRQENTRY_TEXT
#ifdef CONFIG_PPC32
*(.got1)
__got2_end = .;
#endif /* CONFIG_PPC32 */
- . = ALIGN(PAGE_SIZE);
- _etext = .;
- PROVIDE32 (etext = .);
- }
+ } :kernel
+
+ . = ALIGN(PAGE_SIZE);
+ _etext = .;
+ PROVIDE32 (etext = .);
/* Read-only data */
RODATA
- /* Exception & bug tables */
- __ex_table : {
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
- }
+ EXCEPTION_TABLE(0)
- __bug_table : {
- __start___bug_table = .;
- *(__bug_table)
- __stop___bug_table = .;
- }
+ NOTES :kernel :notes
+
+ /* The dummy segment contents for the bug workaround mentioned above
+ near PHDRS. */
+ .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
+ LONG(0)
+ LONG(0)
+ LONG(0)
+ } :kernel :dummy
/*
* Init sections discarded at runtime
*/
. = ALIGN(PAGE_SIZE);
__init_begin = .;
-
- .init.text : {
- _sinittext = .;
- *(.init.text)
- _einittext = .;
- }
+ INIT_TEXT_SECTION(PAGE_SIZE) :kernel
/* .exit.text is discarded at runtime, not link time,
* to deal with references from __bug_table
*/
- .exit.text : { *(.exit.text) }
+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
+ EXIT_TEXT
+ }
- .init.data : {
- *(.init.data);
+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
+ INIT_DATA
__vtop_table_begin = .;
*(.vtop_fixup);
__vtop_table_end = .;
#endif
}
- . = ALIGN(16);
- .init.setup : {
- __setup_start = .;
- *(.init.setup)
- __setup_end = .;
+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+ INIT_SETUP(16)
}
- .initcall.init : {
- __initcall_start = .;
- INITCALLS
- __initcall_end = .;
- }
+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+ INIT_CALLS
+ }
- .con_initcall.init : {
- __con_initcall_start = .;
- *(.con_initcall.init)
- __con_initcall_end = .;
+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+ CON_INITCALL
}
SECURITY_INIT
. = ALIGN(8);
- __ftr_fixup : {
+ __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
__start___ftr_fixup = .;
*(__ftr_fixup)
__stop___ftr_fixup = .;
}
+ . = ALIGN(8);
+ __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
+ __start___mmu_ftr_fixup = .;
+ *(__mmu_ftr_fixup)
+ __stop___mmu_ftr_fixup = .;
+ }
+ . = ALIGN(8);
+ __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
+ __start___lwsync_fixup = .;
+ *(__lwsync_fixup)
+ __stop___lwsync_fixup = .;
+ }
#ifdef CONFIG_PPC64
. = ALIGN(8);
- __fw_ftr_fixup : {
+ __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
__start___fw_ftr_fixup = .;
*(__fw_ftr_fixup)
__stop___fw_ftr_fixup = .;
}
#endif
-
- . = ALIGN(PAGE_SIZE);
- .init.ramfs : {
- __initramfs_start = .;
- *(.init.ramfs)
- __initramfs_end = .;
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ INIT_RAM_FS
}
-#ifdef CONFIG_PPC32
- . = ALIGN(32);
-#else
- . = ALIGN(128);
-#endif
- .data.percpu : {
- __per_cpu_start = .;
- *(.data.percpu)
- __per_cpu_end = .;
- }
+ PERCPU(PAGE_SIZE)
. = ALIGN(8);
- .machine.desc : {
+ .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
__machine_desc_start = . ;
*(.machine.desc)
__machine_desc_end = . ;
}
+#ifdef CONFIG_RELOCATABLE
+ . = ALIGN(8);
+ .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) }
+ .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
+ .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
+ {
+ __dynamic_start = .;
+ *(.dynamic)
+ }
+ .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
+ .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
+ .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
+ {
+ __rela_dyn_start = .;
+ *(.rela*)
+ }
+#endif
/* freed after init ends here */
. = ALIGN(PAGE_SIZE);
_sdata = .;
#ifdef CONFIG_PPC32
- .data :
- {
- *(.data)
+ .data : AT(ADDR(.data) - LOAD_OFFSET) {
+ DATA_DATA
*(.sdata)
*(.got.plt) *(.got)
}
#else
- .data : {
- *(.data .data.rel* .toc1)
+ .data : AT(ADDR(.data) - LOAD_OFFSET) {
+ DATA_DATA
+ *(.data.rel*)
+ *(.toc1)
*(.branch_lt)
}
- .opd : {
+ .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
*(.opd)
}
- .got : {
+ .got : AT(ADDR(.got) - LOAD_OFFSET) {
__toc_start = .;
*(.got)
*(.toc)
}
#endif
- . = ALIGN(PAGE_SIZE);
- _edata = .;
- PROVIDE32 (edata = .);
-
/* The initial task and kernel stack */
-#ifdef CONFIG_PPC32
- . = ALIGN(8192);
-#else
- . = ALIGN(16384);
-#endif
- .data.init_task : {
- *(.data.init_task)
+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+ INIT_TASK_DATA(THREAD_SIZE)
}
- . = ALIGN(PAGE_SIZE);
- .data.page_aligned : {
- *(.data.page_aligned)
+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+ PAGE_ALIGNED_DATA(PAGE_SIZE)
}
- .data.cacheline_aligned : {
- *(.data.cacheline_aligned)
+ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+ CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
}
- . = ALIGN(PAGE_SIZE);
- __data_nosave : {
- __nosave_begin = .;
- *(.data.nosave)
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
+ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
+ READ_MOSTLY_DATA(L1_CACHE_BYTES)
}
+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+ NOSAVE_DATA
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ _edata = .;
+ PROVIDE32 (edata = .);
+
/*
* And finally the bss
*/
- .bss : {
- __bss_start = .;
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- *(COMMON)
- __bss_stop = .;
- }
+ BSS_SECTION(0, 0, 0)
. = ALIGN(PAGE_SIZE);
_end = . ;
PROVIDE32 (end = .);
+
+ /* Sections to be discarded. */
+ DISCARDS
}