2005-04-16 18:20:36 -04:00
|
|
|
/* ld script to make i386 Linux kernel
|
|
|
|
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
|
2006-12-06 20:14:03 -05:00
|
|
|
*
|
|
|
|
* Don't define absolute symbols until and unless you know that symbol
|
|
|
|
* value is should remain constant even if kernel image is relocated
|
|
|
|
* at run time. Absolute symbols are not relocated. If symbol value should
|
|
|
|
* change if kernel is relocated, make the symbol section relative and
|
|
|
|
* put it inside the section definition.
|
2005-04-16 18:20:36 -04:00
|
|
|
*/
|
|
|
|
|
2005-06-25 17:57:47 -04:00
|
|
|
#define LOAD_OFFSET __PAGE_OFFSET
|
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
#include <asm-generic/vmlinux.lds.h>
|
|
|
|
#include <asm/thread_info.h>
|
|
|
|
#include <asm/page.h>
|
2006-01-27 17:02:47 -05:00
|
|
|
#include <asm/cache.h>
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
|
|
|
OUTPUT_ARCH(i386)
|
2005-06-25 17:57:47 -04:00
|
|
|
ENTRY(phys_startup_32)
|
2005-04-16 18:20:36 -04:00
|
|
|
jiffies = jiffies_64;
|
2006-09-26 02:32:26 -04:00
|
|
|
|
|
|
|
PHDRS {
|
|
|
|
text PT_LOAD FLAGS(5); /* R_E */
|
|
|
|
data PT_LOAD FLAGS(7); /* RWE */
|
|
|
|
note PT_NOTE FLAGS(4); /* R__ */
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
SECTIONS
|
|
|
|
{
|
2005-06-25 17:57:49 -04:00
|
|
|
. = __KERNEL_START;
|
2005-06-25 17:57:47 -04:00
|
|
|
phys_startup_32 = startup_32 - LOAD_OFFSET;
|
2005-04-16 18:20:36 -04:00
|
|
|
/* read-only */
|
2005-06-25 17:57:47 -04:00
|
|
|
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
_text = .; /* Text and read-only data */
|
2005-04-16 18:20:36 -04:00
|
|
|
*(.text)
|
|
|
|
SCHED_TEXT
|
|
|
|
LOCK_TEXT
|
2005-09-06 18:19:27 -04:00
|
|
|
KPROBES_TEXT
|
2005-04-16 18:20:36 -04:00
|
|
|
*(.fixup)
|
|
|
|
*(.gnu.warning)
|
2006-12-06 20:14:03 -05:00
|
|
|
_etext = .; /* End of text section */
|
|
|
|
} :text = 0x9090
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
. = ALIGN(16); /* Exception table */
|
2006-12-06 20:14:03 -05:00
|
|
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
|
|
|
__start___ex_table = .;
|
|
|
|
*(__ex_table)
|
|
|
|
__stop___ex_table = .;
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
RODATA
|
|
|
|
|
2006-06-24 17:27:42 -04:00
|
|
|
. = ALIGN(4);
|
|
|
|
.tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__tracedata_start = .;
|
2006-06-24 17:27:42 -04:00
|
|
|
*(.tracedata)
|
2006-12-06 20:14:03 -05:00
|
|
|
__tracedata_end = .;
|
2006-06-24 17:27:42 -04:00
|
|
|
}
|
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
/* writeable */
|
2006-11-08 20:44:41 -05:00
|
|
|
. = ALIGN(4096);
|
2005-06-25 17:57:47 -04:00
|
|
|
.data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
|
2005-04-16 18:20:36 -04:00
|
|
|
*(.data)
|
|
|
|
CONSTRUCTORS
|
2006-09-26 02:32:26 -04:00
|
|
|
} :data
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
. = ALIGN(4096);
|
2006-12-06 20:14:03 -05:00
|
|
|
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
|
|
|
|
__nosave_begin = .;
|
|
|
|
*(.data.nosave)
|
|
|
|
. = ALIGN(4096);
|
|
|
|
__nosave_end = .;
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
. = ALIGN(4096);
|
2005-06-25 17:57:47 -04:00
|
|
|
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
|
|
|
*(.data.idt)
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
. = ALIGN(32);
|
2005-06-25 17:57:47 -04:00
|
|
|
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
|
|
|
|
*(.data.cacheline_aligned)
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
2005-07-07 20:56:59 -04:00
|
|
|
/* rarely changed data like cpu maps */
|
|
|
|
. = ALIGN(32);
|
2006-12-06 20:14:03 -05:00
|
|
|
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
|
|
|
|
*(.data.read_mostly)
|
|
|
|
_edata = .; /* End of data section */
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
2006-06-26 07:57:41 -04:00
|
|
|
#ifdef CONFIG_STACK_UNWIND
|
|
|
|
. = ALIGN(4);
|
|
|
|
.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {
|
|
|
|
__start_unwind = .;
|
|
|
|
*(.eh_frame)
|
|
|
|
__end_unwind = .;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
. = ALIGN(THREAD_SIZE); /* init_task */
|
2005-06-25 17:57:47 -04:00
|
|
|
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
|
|
|
*(.data.init_task)
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
|
2006-03-23 05:59:32 -05:00
|
|
|
/* might get freed after init */
|
|
|
|
. = ALIGN(4096);
|
|
|
|
.smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__smp_alt_begin = .;
|
|
|
|
__smp_alt_instructions = .;
|
2006-03-23 05:59:32 -05:00
|
|
|
*(.smp_altinstructions)
|
2006-12-06 20:14:03 -05:00
|
|
|
__smp_alt_instructions_end = .;
|
2006-03-23 05:59:32 -05:00
|
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
|
|
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__smp_locks = .;
|
2006-03-23 05:59:32 -05:00
|
|
|
*(.smp_locks)
|
2006-12-06 20:14:03 -05:00
|
|
|
__smp_locks_end = .;
|
2006-03-23 05:59:32 -05:00
|
|
|
}
|
|
|
|
.smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
|
|
|
|
*(.smp_altinstr_replacement)
|
2006-12-06 20:14:03 -05:00
|
|
|
__smp_alt_end = .;
|
2006-03-23 05:59:32 -05:00
|
|
|
}
|
2006-12-06 20:14:03 -05:00
|
|
|
/* will be freed after init
|
|
|
|
* Following ALIGN() is required to make sure no other data falls on the
|
|
|
|
* same page where __smp_alt_end is pointing as that page might be freed
|
|
|
|
* after boot. Always make sure that ALIGN() directive is present after
|
|
|
|
* the section which contains __smp_alt_end.
|
|
|
|
*/
|
2006-03-23 05:59:32 -05:00
|
|
|
. = ALIGN(4096);
|
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
/* will be freed after init */
|
|
|
|
. = ALIGN(4096); /* Init code and data */
|
2005-06-25 17:57:47 -04:00
|
|
|
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__init_begin = .;
|
2005-04-16 18:20:36 -04:00
|
|
|
_sinittext = .;
|
|
|
|
*(.init.text)
|
|
|
|
_einittext = .;
|
|
|
|
}
|
2005-06-25 17:57:47 -04:00
|
|
|
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
|
2005-04-16 18:20:36 -04:00
|
|
|
. = ALIGN(16);
|
2006-12-06 20:14:03 -05:00
|
|
|
.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
|
|
|
|
__setup_start = .;
|
|
|
|
*(.init.setup)
|
|
|
|
__setup_end = .;
|
|
|
|
}
|
2005-06-25 17:57:47 -04:00
|
|
|
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__initcall_start = .;
|
2006-10-27 14:41:44 -04:00
|
|
|
INITCALLS
|
2006-12-06 20:14:03 -05:00
|
|
|
__initcall_end = .;
|
2005-04-16 18:20:36 -04:00
|
|
|
}
|
2005-06-25 17:57:47 -04:00
|
|
|
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__con_initcall_start = .;
|
2005-06-25 17:57:47 -04:00
|
|
|
*(.con_initcall.init)
|
2006-12-06 20:14:03 -05:00
|
|
|
__con_initcall_end = .;
|
2005-06-25 17:57:47 -04:00
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
SECURITY_INIT
|
|
|
|
. = ALIGN(4);
|
2005-06-25 17:57:47 -04:00
|
|
|
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__alt_instructions = .;
|
2005-06-25 17:57:47 -04:00
|
|
|
*(.altinstructions)
|
2006-12-06 20:14:03 -05:00
|
|
|
__alt_instructions_end = .;
|
2005-06-25 17:57:47 -04:00
|
|
|
}
|
|
|
|
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
|
|
|
|
*(.altinstr_replacement)
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
/* .exit.text is discard at runtime, not link time, to deal with references
|
|
|
|
from .altinstructions and .eh_frame */
|
2005-06-25 17:57:47 -04:00
|
|
|
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
|
|
|
|
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
|
2005-04-16 18:20:36 -04:00
|
|
|
. = ALIGN(4096);
|
2006-12-06 20:14:03 -05:00
|
|
|
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
|
|
|
|
__initramfs_start = .;
|
|
|
|
*(.init.ramfs)
|
|
|
|
__initramfs_end = .;
|
|
|
|
}
|
2006-01-27 17:02:47 -05:00
|
|
|
. = ALIGN(L1_CACHE_BYTES);
|
2006-12-06 20:14:03 -05:00
|
|
|
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
|
|
|
|
__per_cpu_start = .;
|
|
|
|
*(.data.percpu)
|
|
|
|
__per_cpu_end = .;
|
|
|
|
}
|
2005-04-16 18:20:36 -04:00
|
|
|
. = ALIGN(4096);
|
|
|
|
/* freed after init ends here */
|
|
|
|
|
2005-06-25 17:57:47 -04:00
|
|
|
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
|
2006-12-06 20:14:03 -05:00
|
|
|
__init_end = .;
|
|
|
|
__bss_start = .; /* BSS */
|
|
|
|
*(.bss.page_aligned)
|
2005-04-16 18:20:36 -04:00
|
|
|
*(.bss)
|
2006-12-06 20:14:03 -05:00
|
|
|
. = ALIGN(4);
|
|
|
|
__bss_stop = .;
|
|
|
|
_end = . ;
|
|
|
|
/* This is where the kernel creates the early boot page tables */
|
|
|
|
. = ALIGN(4096);
|
|
|
|
pg0 = . ;
|
2005-04-16 18:20:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Sections to be discarded */
|
|
|
|
/DISCARD/ : {
|
|
|
|
*(.exitcall.exit)
|
|
|
|
}
|
|
|
|
|
2005-09-10 13:44:54 -04:00
|
|
|
STABS_DEBUG
|
|
|
|
|
|
|
|
DWARF_DEBUG
|
2006-09-26 02:32:26 -04:00
|
|
|
|
|
|
|
NOTES
|
2005-04-16 18:20:36 -04:00
|
|
|
}
|