2007-10-11 02:12:11 -07:00
|
|
|
/* ld script to make i386 Linux kernel
|
|
|
|
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define LOAD_OFFSET __PAGE_OFFSET
|
|
|
|
|
|
|
|
#include <asm-generic/vmlinux.lds.h>
|
|
|
|
#include <asm/thread_info.h>
|
|
|
|
#include <asm/page.h>
|
|
|
|
#include <asm/cache.h>
|
|
|
|
#include <asm/boot.h>
|
|
|
|
|
|
|
|
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
|
|
|
OUTPUT_ARCH(i386)
|
|
|
|
ENTRY(phys_startup_32)
|
|
|
|
jiffies = jiffies_64;
|
|
|
|
|
|
|
|
PHDRS {
|
|
|
|
text PT_LOAD FLAGS(5); /* R_E */
|
|
|
|
data PT_LOAD FLAGS(7); /* RWE */
|
|
|
|
note PT_NOTE FLAGS(0); /* ___ */
|
|
|
|
}
|
|
|
|
SECTIONS
|
|
|
|
{
|
|
|
|
. = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
|
|
|
|
phys_startup_32 = startup_32 - LOAD_OFFSET;
|
|
|
|
|
|
|
|
.text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
|
|
|
|
_text = .; /* Text and read-only data */
|
|
|
|
*(.text.head)
|
|
|
|
} :text = 0x9090
|
|
|
|
|
|
|
|
/* read-only */
|
|
|
|
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
|
x86: make arch/x86/kernel/acpi/wakeup_32.S use a separate
While examining vmlinux namelist on i386 (nm -v vmlinux) I noticed :
c01021d0 t es7000_rename_gsi
c010221a T es7000_start_cpu
<Big Hole>
c0103000 T thread_saved_pc
and
c0113218 T acpi_restore_state_mem
c0113219 T acpi_save_state_mem
<Big Hole>
c0114000 t wakeup_code
This is because arch/x86/kernel/acpi/wakeup_32.S forces a .text alignment
of 4096 bytes. (I have no idea if it is really needed, since
arch/x86/kernel/acpi/wakeup_64.S uses a 16 bytes alignment *only*)
So arch/x86/kernel/built-in.o also has this alignment
arch/x86/kernel/built-in.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00018c94 00000000 00000000 00001000 2**12
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
But as arch/x86/kernel/acpi/wakeup_32.o is not the first object linked
into arch/x86/kernel/built-in.o, linker had to build several holes to meet
alignement requirements, because of .o nestings in the kbuild process.
This can be solved by using a special section, .text.page_aligned, so that
no holes are needed.
# size vmlinux.before vmlinux.after
text data bss dec hex filename
4619942 422838 458752 5501532 53f25c vmlinux.before
4610534 422838 458752 5492124 53cd9c vmlinux.after
This saves 9408 bytes
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2008-01-30 05:32:50 -07:00
|
|
|
*(.text.page_aligned)
|
2007-10-11 02:12:11 -07:00
|
|
|
TEXT_TEXT
|
|
|
|
SCHED_TEXT
|
|
|
|
LOCK_TEXT
|
|
|
|
KPROBES_TEXT
|
|
|
|
*(.fixup)
|
|
|
|
*(.gnu.warning)
|
|
|
|
_etext = .; /* End of text section */
|
|
|
|
} :text = 0x9090
|
|
|
|
|
2008-05-12 06:44:41 -07:00
|
|
|
NOTES :text :note
|
|
|
|
|
2007-10-11 02:12:11 -07:00
|
|
|
. = ALIGN(16); /* Exception table */
|
|
|
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
|
|
|
__start___ex_table = .;
|
|
|
|
*(__ex_table)
|
|
|
|
__stop___ex_table = .;
|
2008-05-12 06:44:41 -07:00
|
|
|
} :text = 0x9090
|
2007-10-11 02:12:11 -07:00
|
|
|
|
|
|
|
RODATA
|
|
|
|
|
|
|
|
/* writeable */
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
|
|
|
|
DATA_DATA
|
|
|
|
CONSTRUCTORS
|
|
|
|
} :data
|
|
|
|
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
|
|
|
|
__nosave_begin = .;
|
|
|
|
*(.data.nosave)
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
__nosave_end = .;
|
|
|
|
}
|
|
|
|
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
|
|
|
*(.data.page_aligned)
|
|
|
|
*(.data.idt)
|
|
|
|
}
|
|
|
|
|
|
|
|
. = ALIGN(32);
|
|
|
|
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
|
|
|
|
*(.data.cacheline_aligned)
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rarely changed data like cpu maps */
|
|
|
|
. = ALIGN(32);
|
|
|
|
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
|
|
|
|
*(.data.read_mostly)
|
|
|
|
_edata = .; /* End of data section */
|
|
|
|
}
|
|
|
|
|
|
|
|
. = ALIGN(THREAD_SIZE); /* init_task */
|
|
|
|
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
|
|
|
*(.data.init_task)
|
|
|
|
}
|
|
|
|
|
|
|
|
/* might get freed after init */
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
|
|
|
|
__smp_locks = .;
|
|
|
|
*(.smp_locks)
|
|
|
|
__smp_locks_end = .;
|
|
|
|
}
|
|
|
|
/* 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.
|
|
|
|
*/
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
|
|
|
|
/* will be freed after init */
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
2007-10-11 02:12:11 -07:00
|
|
|
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
|
|
|
|
__init_begin = .;
|
|
|
|
_sinittext = .;
|
2008-01-20 06:15:03 -07:00
|
|
|
INIT_TEXT
|
2007-10-11 02:12:11 -07:00
|
|
|
_einittext = .;
|
|
|
|
}
|
2008-01-20 06:15:03 -07:00
|
|
|
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
|
|
|
|
INIT_DATA
|
|
|
|
}
|
2007-10-11 02:12:11 -07:00
|
|
|
. = ALIGN(16);
|
|
|
|
.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
|
|
|
|
__setup_start = .;
|
|
|
|
*(.init.setup)
|
|
|
|
__setup_end = .;
|
|
|
|
}
|
|
|
|
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
|
|
|
|
__initcall_start = .;
|
|
|
|
INITCALLS
|
|
|
|
__initcall_end = .;
|
|
|
|
}
|
|
|
|
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
|
|
|
|
__con_initcall_start = .;
|
|
|
|
*(.con_initcall.init)
|
|
|
|
__con_initcall_end = .;
|
|
|
|
}
|
x86: use ELF section to list CPU vendor specific code
Replace the hardcoded list of initialization functions for each CPU
vendor by a list in an ELF section, which is read at initialization in
arch/x86/kernel/cpu/cpu.c to fill the cpu_devs[] array. The ELF
section, named .x86cpuvendor.init, is reclaimed after boot, and
contains entries of type "struct cpu_vendor_dev" which associates a
vendor number with a pointer to a "struct cpu_dev" structure.
This first modification allows to remove all the VENDOR_init_cpu()
functions.
This patch also removes the hardcoded calls to early_init_amd() and
early_init_intel(). Instead, we add a "c_early_init" member to the
cpu_dev structure, which is then called if not NULL by the generic CPU
initialization code. Unfortunately, in early_cpu_detect(), this_cpu is
not yet set, so we have to use the cpu_devs[] array directly.
This patch is part of the Linux Tiny project, and is needed for
further patch that will allow to disable compilation of unused CPU
support code.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2008-02-15 04:00:23 -07:00
|
|
|
.x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) {
|
|
|
|
__x86cpuvendor_start = .;
|
|
|
|
*(.x86cpuvendor.init)
|
|
|
|
__x86cpuvendor_end = .;
|
|
|
|
}
|
2007-10-11 02:12:11 -07:00
|
|
|
SECURITY_INIT
|
|
|
|
. = ALIGN(4);
|
|
|
|
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
|
|
|
|
__alt_instructions = .;
|
|
|
|
*(.altinstructions)
|
|
|
|
__alt_instructions_end = .;
|
|
|
|
}
|
|
|
|
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
|
|
|
|
*(.altinstr_replacement)
|
|
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
|
|
.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
|
|
|
|
__parainstructions = .;
|
|
|
|
*(.parainstructions)
|
|
|
|
__parainstructions_end = .;
|
|
|
|
}
|
|
|
|
/* .exit.text is discard at runtime, not link time, to deal with references
|
|
|
|
from .altinstructions and .eh_frame */
|
2008-01-20 06:15:03 -07:00
|
|
|
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
|
|
|
|
EXIT_TEXT
|
|
|
|
}
|
|
|
|
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
|
|
|
|
EXIT_DATA
|
|
|
|
}
|
2007-10-11 02:12:11 -07:00
|
|
|
#if defined(CONFIG_BLK_DEV_INITRD)
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
|
|
|
|
__initramfs_start = .;
|
|
|
|
*(.init.ramfs)
|
|
|
|
__initramfs_end = .;
|
|
|
|
}
|
|
|
|
#endif
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
|
|
|
|
__per_cpu_start = .;
|
|
|
|
*(.data.percpu)
|
|
|
|
*(.data.percpu.shared_aligned)
|
|
|
|
__per_cpu_end = .;
|
|
|
|
}
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
/* freed after init ends here */
|
2008-02-17 08:17:17 -07:00
|
|
|
|
2007-10-11 02:12:11 -07:00
|
|
|
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
|
|
|
|
__init_end = .;
|
|
|
|
__bss_start = .; /* BSS */
|
|
|
|
*(.bss.page_aligned)
|
|
|
|
*(.bss)
|
|
|
|
. = ALIGN(4);
|
|
|
|
__bss_stop = .;
|
|
|
|
_end = . ;
|
|
|
|
/* This is where the kernel creates the early boot page tables */
|
2008-02-17 08:17:17 -07:00
|
|
|
. = ALIGN(PAGE_SIZE);
|
2007-10-11 02:12:11 -07:00
|
|
|
pg0 = . ;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sections to be discarded */
|
|
|
|
/DISCARD/ : {
|
|
|
|
*(.exitcall.exit)
|
|
|
|
}
|
|
|
|
|
|
|
|
STABS_DEBUG
|
|
|
|
|
|
|
|
DWARF_DEBUG
|
|
|
|
}
|
2008-08-15 00:40:23 -07:00
|
|
|
|
|
|
|
#ifdef CONFIG_KEXEC
|
|
|
|
/* Link time checks */
|
|
|
|
#include <asm/kexec.h>
|
|
|
|
|
|
|
|
ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
|
|
|
|
"kexec control code size is too big")
|
|
|
|
#endif
|