2007-10-11 13:12:11 +04:00
/ * ld s c r i p t t o m a k e i 3 8 6 L i n u x k e r n e l
* Written b y M a r t i n M a r e s < m j @atrey.karlin.mff.cuni.cz>;
*
* Don' t d e f i n e a b s o l u t e s y m b o l s u n t i l a n d u n l e s s y o u k n o w t h a t s y m b o l
* value i s s h o u l d r e m a i n c o n s t a n t e v e n i f k e r n e l i m a g e i s r e l o c a t e d
* at r u n t i m e . A b s o l u t e s y m b o l s a r e n o t r e l o c a t e d . I f s y m b o l v a l u e s h o u l d
* change i f k e r n e l i s r e l o c a t e d , m a k e t h e s y m b o l s e c t i o n r e l a t i v e a n d
* put i t i n s i d e t h e s e c t i o n d e f i n i t i o n .
* /
# define L O A D _ O F F S E T _ _ P A G E _ O F F S E T
# include < a s m - g e n e r i c / v m l i n u x . l d s . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / p a g e . h >
# include < a s m / c a c h e . h >
# include < a s m / b o o t . h >
OUTPUT_ F O R M A T ( " e l f32 - i 3 8 6 " , " e l f32 - i 3 8 6 " , " e l f32 - i 3 8 6 " )
OUTPUT_ A R C H ( i 3 8 6 )
ENTRY( p h y s _ s t a r t u p _ 3 2 )
jiffies = j i f f i e s _ 6 4 ;
PHDRS {
text P T _ L O A D F L A G S ( 5 ) ; /* R_E */
data P T _ L O A D F L A G S ( 7 ) ; /* RWE */
note P T _ N O T E F L A G S ( 0 ) ; /* ___ */
}
SECTIONS
{
. = LOAD_ O F F S E T + L O A D _ P H Y S I C A L _ A D D R ;
phys_ s t a r t u p _ 3 2 = s t a r t u p _ 3 2 - L O A D _ O F F S E T ;
.text .head : AT( A D D R ( . t e x t . h e a d ) - L O A D _ O F F S E T ) {
_ text = . ; /* Text and read-only data */
* ( .text .head )
} : text = 0 x90 9 0
/* read-only */
.text : AT( A D D R ( . t e x t ) - L O A D _ O F F S E T ) {
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 15:32:50 +03:00
. = ALIGN( 4 0 9 6 ) ; /* not really needed, already page aligned */
* ( .text .page_aligned )
2007-10-11 13:12:11 +04:00
TEXT_ T E X T
SCHED_ T E X T
LOCK_ T E X T
KPROBES_ T E X T
* ( .fixup )
* ( .gnu .warning )
_ etext = . ; /* End of text section */
} : text = 0 x90 9 0
. = ALIGN( 1 6 ) ; /* Exception table */
_ _ ex_ t a b l e : A T ( A D D R ( _ _ e x _ t a b l e ) - L O A D _ O F F S E T ) {
_ _ start_ _ _ e x _ t a b l e = . ;
* ( _ _ ex_ t a b l e )
_ _ stop_ _ _ e x _ t a b l e = . ;
}
NOTES : t e x t : n o t e
BUG_ T A B L E : t e x t
. = ALIGN( 4 ) ;
.tracedata : AT( A D D R ( . t r a c e d a t a ) - L O A D _ O F F S E T ) {
_ _ tracedata_ s t a r t = . ;
* ( .tracedata )
_ _ tracedata_ e n d = . ;
}
RODATA
/* writeable */
. = ALIGN( 4 0 9 6 ) ;
.data : AT( A D D R ( . d a t a ) - L O A D _ O F F S E T ) { / * D a t a * /
DATA_ D A T A
CONSTRUCTORS
} : data
. = ALIGN( 4 0 9 6 ) ;
.data_nosave : AT( A D D R ( . d a t a _ n o s a v e ) - L O A D _ O F F S E T ) {
_ _ nosave_ b e g i n = . ;
* ( .data .nosave )
. = ALIGN( 4 0 9 6 ) ;
_ _ nosave_ e n d = . ;
}
. = ALIGN( 4 0 9 6 ) ;
.data .page_aligned : AT( A D D R ( . d a t a . p a g e _ a l i g n e d ) - L O A D _ O F F S E T ) {
* ( .data .page_aligned )
* ( .data .idt )
}
. = ALIGN( 3 2 ) ;
.data .cacheline_aligned : AT( A D D R ( . d a t a . c a c h e l i n e _ a l i g n e d ) - L O A D _ O F F S E T ) {
* ( .data .cacheline_aligned )
}
/* rarely changed data like cpu maps */
. = ALIGN( 3 2 ) ;
.data .read_mostly : AT( A D D R ( . d a t a . r e a d _ m o s t l y ) - L O A D _ O F F S E T ) {
* ( .data .read_mostly )
_ edata = . ; /* End of data section */
}
. = ALIGN( T H R E A D _ S I Z E ) ; /* init_task */
.data .init_task : AT( A D D R ( . d a t a . i n i t _ t a s k ) - L O A D _ O F F S E T ) {
* ( .data .init_task )
}
/* might get freed after init */
. = ALIGN( 4 0 9 6 ) ;
.smp_locks : AT( A D D R ( . s m p _ l o c k s ) - L O A D _ O F F S E T ) {
_ _ smp_ l o c k s = . ;
* ( .smp_locks )
_ _ smp_ l o c k s _ e n d = . ;
}
/ * will b e f r e e d a f t e r i n i t
* Following A L I G N ( ) i s r e q u i r e d t o m a k e s u r e n o o t h e r d a t a f a l l s o n t h e
* same p a g e w h e r e _ _ s m p _ a l t _ e n d i s p o i n t i n g a s t h a t p a g e m i g h t b e f r e e d
* after b o o t . A l w a y s m a k e s u r e t h a t A L I G N ( ) d i r e c t i v e i s p r e s e n t a f t e r
* the s e c t i o n w h i c h c o n t a i n s _ _ s m p _ a l t _ e n d .
* /
. = ALIGN( 4 0 9 6 ) ;
/* will be freed after init */
. = ALIGN( 4 0 9 6 ) ; /* Init code and data */
.init .text : AT( A D D R ( . i n i t . t e x t ) - L O A D _ O F F S E T ) {
_ _ init_ b e g i n = . ;
_ sinittext = . ;
2008-01-20 16:15:03 +03:00
INIT_ T E X T
2007-10-11 13:12:11 +04:00
_ einittext = . ;
}
2008-01-20 16:15:03 +03:00
.init .data : AT( A D D R ( . i n i t . d a t a ) - L O A D _ O F F S E T ) {
INIT_ D A T A
}
2007-10-11 13:12:11 +04:00
. = ALIGN( 1 6 ) ;
.init .setup : AT( A D D R ( . i n i t . s e t u p ) - L O A D _ O F F S E T ) {
_ _ setup_ s t a r t = . ;
* ( .init .setup )
_ _ setup_ e n d = . ;
}
.initcall .init : AT( A D D R ( . i n i t c a l l . i n i t ) - L O A D _ O F F S E T ) {
_ _ initcall_ s t a r t = . ;
INITCALLS
_ _ initcall_ e n d = . ;
}
.con_initcall .init : AT( A D D R ( . c o n _ i n i t c a l l . i n i t ) - L O A D _ O F F S E T ) {
_ _ con_ i n i t c a l l _ s t a r t = . ;
* ( .con_initcall .init )
_ _ con_ i n i t c a l l _ e n d = . ;
}
SECURITY_ I N I T
. = ALIGN( 4 ) ;
.altinstructions : AT( A D D R ( . a l t i n s t r u c t i o n s ) - L O A D _ O F F S E T ) {
_ _ alt_ i n s t r u c t i o n s = . ;
* ( .altinstructions )
_ _ alt_ i n s t r u c t i o n s _ e n d = . ;
}
.altinstr_replacement : AT( A D D R ( . a l t i n s t r _ r e p l a c e m e n t ) - L O A D _ O F F S E T ) {
* ( .altinstr_replacement )
}
. = ALIGN( 4 ) ;
.parainstructions : AT( A D D R ( . p a r a i n s t r u c t i o n s ) - L O A D _ O F F S E T ) {
_ _ parainstructions = . ;
* ( .parainstructions )
_ _ parainstructions_ e n d = . ;
}
/ * .exit .text is discard a t r u n t i m e , n o t l i n k t i m e , t o d e a l w i t h r e f e r e n c e s
from . a l t i n s t r u c t i o n s a n d . e h _ f r a m e * /
2008-01-20 16:15:03 +03:00
.exit .text : AT( A D D R ( . e x i t . t e x t ) - L O A D _ O F F S E T ) {
EXIT_ T E X T
}
.exit .data : AT( A D D R ( . e x i t . d a t a ) - L O A D _ O F F S E T ) {
EXIT_ D A T A
}
2007-10-11 13:12:11 +04:00
# if d e f i n e d ( C O N F I G _ B L K _ D E V _ I N I T R D )
. = ALIGN( 4 0 9 6 ) ;
.init .ramfs : AT( A D D R ( . i n i t . r a m f s ) - L O A D _ O F F S E T ) {
_ _ initramfs_ s t a r t = . ;
* ( .init .ramfs )
_ _ initramfs_ e n d = . ;
}
# endif
. = ALIGN( 4 0 9 6 ) ;
.data .percpu : AT( A D D R ( . d a t a . p e r c p u ) - L O A D _ O F F S E T ) {
_ _ per_ c p u _ s t a r t = . ;
* ( .data .percpu )
* ( .data .percpu .shared_aligned )
_ _ per_ c p u _ e n d = . ;
}
. = ALIGN( 4 0 9 6 ) ;
/* freed after init ends here */
.bss : AT( A D D R ( . b s s ) - L O A D _ O F F S E T ) {
_ _ init_ e n d = . ;
_ _ bss_ s t a r t = . ; /* BSS */
* ( .bss .page_aligned )
* ( .bss )
. = ALIGN( 4 ) ;
_ _ bss_ s t o p = . ;
_ end = . ;
/* This is where the kernel creates the early boot page tables */
. = ALIGN( 4 0 9 6 ) ;
pg0 = . ;
}
/* Sections to be discarded */
/ DISCARD/ : {
* ( .exitcall .exit )
}
STABS_ D E B U G
DWARF_ D E B U G
}