2009-04-29 09:47:18 +02:00
/ *
* ld s c r i p t f o r t h e x86 k e r n e l
*
* Historic 3 2 - b i t v e r s i o n w r i t t e n b y M a r t i n M a r e s < m j @atrey.karlin.mff.cuni.cz>
*
2009-04-29 10:58:38 +02:00
* Modernisation, u n i f i c a t i o n a n d o t h e r c h a n g e s a n d f i x e s :
* Copyright ( C ) 2 0 0 7 - 2 0 0 9 S a m R a v n b o r g < s a m @ravnborg.org>
2009-04-29 09:47:18 +02:00
*
*
* 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 .
* /
# ifdef C O N F I G _ X 8 6 _ 3 2
# define L O A D _ O F F S E T _ _ P A G E _ O F F S E T
# else
# define L O A D _ O F F S E T _ _ S T A R T _ K E R N E L _ m a p
# endif
# 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 / a s m - o f f s e t 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 _ t y p e s . h >
# include < a s m / c a c h e . h >
# include < a s m / b o o t . h >
# undef i 3 8 6 / * i n c a s e t h e p r e p r o c e s s o r i s a 3 2 b i t o n e * /
OUTPUT_ F O R M A T ( C O N F I G _ O U T P U T _ F O R M A T , C O N F I G _ O U T P U T _ F O R M A T , C O N F I G _ O U T P U T _ F O R M A T )
# ifdef C O N F I G _ X 8 6 _ 3 2
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 ;
# else
OUTPUT_ A R C H ( i 3 8 6 : x86 - 6 4 )
ENTRY( p h y s _ s t a r t u p _ 6 4 )
jiffies_ 6 4 = j i f f i e s ;
# endif
2009-04-29 09:47:19 +02:00
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 */
# ifdef C O N F I G _ X 8 6 _ 6 4
user P T _ L O A D F L A G S ( 7 ) ; /* RWE */
data. i n i t P T _ L O A D F L A G S ( 7 ) ; /* RWE */
# ifdef C O N F I G _ S M P
percpu P T _ L O A D F L A G S ( 7 ) ; /* RWE */
# endif
data. i n i t 2 P T _ L O A D F L A G S ( 7 ) ; /* RWE */
# endif
note P T _ N O T E F L A G S ( 0 ) ; /* ___ */
}
2009-04-29 09:47:18 +02:00
2009-04-29 09:47:20 +02:00
SECTIONS
{
# ifdef C O N F I G _ X 8 6 _ 3 2
. = 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 ;
# else
. = _ _ START_ K E R N E L ;
phys_ s t a r t u p _ 6 4 = s t a r t u p _ 6 4 - L O A D _ O F F S E T ;
# endif
2009-04-29 09:47:21 +02:00
/* Text and read-only data */
/* bootstrapping code */
.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 .head )
} : text = 0 x90 9 0
/* The rest of the text */
.text : AT( A D D R ( . t e x t ) - L O A D _ O F F S E T ) {
# ifdef C O N F I G _ X 8 6 _ 3 2
/* not really needed, already page aligned */
. = ALIGN( P A G E _ S I Z E ) ;
* ( .text .page_aligned )
# endif
. = ALIGN( 8 ) ;
_ stext = . ;
TEXT_ T E X T
SCHED_ T E X T
LOCK_ T E X T
KPROBES_ T E X T
IRQENTRY_ T E X T
* ( .fixup )
* ( .gnu .warning )
/* End of text section */
_ etext = . ;
} : text = 0 x90 9 0
NOTES : t e x t : n o t e
2009-04-29 09:47:22 +02:00
/* Exception table */
. = ALIGN( 1 6 ) ;
_ _ 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 = . ;
} : text = 0 x90 9 0
RODATA
2009-04-29 09:47:23 +02:00
/* Data */
. = ALIGN( P A G E _ S I Z E ) ;
.data : AT( A D D R ( . d a t a ) - L O A D _ O F F S E T ) {
2009-05-11 13:22:00 +01:00
/* Start of data section */
_ sdata = . ;
2009-04-29 09:47:23 +02:00
DATA_ D A T A
CONSTRUCTORS
} : data
# ifdef C O N F I G _ X 8 6 _ 3 2
/* 32 bit has nosave before _edata */
. = ALIGN( P A G E _ S I Z E ) ;
.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( P A G E _ S I Z E ) ;
_ _ nosave_ e n d = . ;
}
# endif
. = ALIGN( P A G E _ S I Z E ) ;
.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 )
}
# ifdef C O N F I G _ X 8 6 _ 3 2
. = ALIGN( 3 2 ) ;
# else
. = ALIGN( P A G E _ S I Z E ) ;
. = ALIGN( C O N F I G _ X 8 6 _ L 1 _ C A C H E _ B Y T E S ) ;
# endif
.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 */
# ifdef C O N F I G _ X 8 6 _ 3 2
. = ALIGN( 3 2 ) ;
# else
. = ALIGN( C O N F I G _ X 8 6 _ I N T E R N O D E _ C A C H E _ B Y T E S ) ;
# endif
.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 )
/* End of data section */
_ edata = . ;
}
2009-04-29 09:47:24 +02:00
# ifdef C O N F I G _ X 8 6 _ 6 4
# define V S Y S C A L L _ A D D R ( - 1 0 * 1 0 2 4 * 1 0 2 4 )
# define V S Y S C A L L _ P H Y S _ A D D R ( ( L O A D A D D R ( . d a t a . r e a d _ m o s t l y ) + \
SIZEOF( . d a t a . r e a d _ m o s t l y ) + 4 0 9 5 ) & ~ ( 4 0 9 5 ) )
# define V S Y S C A L L _ V I R T _ A D D R ( ( A D D R ( . d a t a . r e a d _ m o s t l y ) + \
SIZEOF( . d a t a . r e a d _ m o s t l y ) + 4 0 9 5 ) & ~ ( 4 0 9 5 ) )
# define V L O A D _ O F F S E T ( V S Y S C A L L _ A D D R - V S Y S C A L L _ P H Y S _ A D D R )
# define V L O A D ( x ) ( A D D R ( x ) - V L O A D _ O F F S E T )
# define V V I R T _ O F F S E T ( V S Y S C A L L _ A D D R - V S Y S C A L L _ V I R T _ A D D R )
# define V V I R T ( x ) ( A D D R ( x ) - V V I R T _ O F F S E T )
. = VSYSCALL_ A D D R ;
.vsyscall_0 : AT( V S Y S C A L L _ P H Y S _ A D D R ) {
* ( .vsyscall_0 )
} : user
_ _ vsyscall_ 0 = V S Y S C A L L _ V I R T _ A D D R ;
. = ALIGN( C O N F I G _ X 8 6 _ L 1 _ C A C H E _ B Y T E S ) ;
.vsyscall_fn : AT( V L O A D ( . v s y s c a l l _ f n ) ) {
* ( .vsyscall_fn )
}
. = ALIGN( C O N F I G _ X 8 6 _ L 1 _ C A C H E _ B Y T E S ) ;
.vsyscall_gtod_data : AT( V L O A D ( . v s y s c a l l _ g t o d _ d a t a ) ) {
* ( .vsyscall_gtod_data )
}
vsyscall_ g t o d _ d a t a = V V I R T ( . v s y s c a l l _ g t o d _ d a t a ) ;
.vsyscall_clock : AT( V L O A D ( . v s y s c a l l _ c l o c k ) ) {
* ( .vsyscall_clock )
}
vsyscall_ c l o c k = V V I R T ( . v s y s c a l l _ c l o c k ) ;
.vsyscall_1 ADDR( . v s y s c a l l _ 0 ) + 1 0 2 4 : A T ( V L O A D ( . v s y s c a l l _ 1 ) ) {
* ( .vsyscall_1 )
}
.vsyscall_2 ADDR( . v s y s c a l l _ 0 ) + 2 0 4 8 : A T ( V L O A D ( . v s y s c a l l _ 2 ) ) {
* ( .vsyscall_2 )
}
.vgetcpu_mode : AT( V L O A D ( . v g e t c p u _ m o d e ) ) {
* ( .vgetcpu_mode )
}
vgetcpu_ m o d e = V V I R T ( . v g e t c p u _ m o d e ) ;
. = ALIGN( C O N F I G _ X 8 6 _ L 1 _ C A C H E _ B Y T E S ) ;
.jiffies : AT( V L O A D ( . j i f f i e s ) ) {
* ( .jiffies )
}
jiffies = V V I R T ( . j i f f i e s ) ;
.vsyscall_3 ADDR( . v s y s c a l l _ 0 ) + 3 0 7 2 : A T ( V L O A D ( . v s y s c a l l _ 3 ) ) {
* ( .vsyscall_3 )
}
. = VSYSCALL_ V I R T _ A D D R + P A G E _ S I Z E ;
# undef V S Y S C A L L _ A D D R
# undef V S Y S C A L L _ P H Y S _ A D D R
# undef V S Y S C A L L _ V I R T _ A D D R
# undef V L O A D _ O F F S E T
# undef V L O A D
# undef V V I R T _ O F F S E T
# undef V V I R T
# endif / * C O N F I G _ X 8 6 _ 6 4 * /
2009-04-29 09:47:21 +02:00
2009-04-29 09:47:25 +02:00
/* init_task */
. = ALIGN( T H R E A D _ S I Z E ) ;
.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 )
}
# ifdef C O N F I G _ X 8 6 _ 6 4
: data. i n i t
# endif
/ *
* smp_ l o c k s m i g h t b e f r e e d a f t e r i n i t
* start/ e n d m u s t b e p a g e a l i g n e d
* /
. = ALIGN( P A G E _ S I Z E ) ;
.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 = . ;
. = ALIGN( P A G E _ S I Z E ) ;
}
/* Init code and data - will be freed after init */
. = ALIGN( P A G E _ S I Z E ) ;
.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 ) {
2009-04-29 12:56:58 +02:00
_ _ init_ b e g i n = . ; /* paired with __init_end */
2009-04-29 09:47:25 +02:00
_ sinittext = . ;
INIT_ T E X T
_ einittext = . ;
}
.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
}
. = 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 = . ;
}
.x86_cpu_dev .init : AT( A D D R ( . x86 _ c p u _ d e v . i n i t ) - L O A D _ O F F S E T ) {
_ _ x8 6 _ c p u _ d e v _ s t a r t = . ;
* ( .x86_cpu_dev .init )
_ _ x8 6 _ c p u _ d e v _ e n d = . ;
}
SECURITY_ I N I T
2009-04-29 09:47:26 +02:00
. = ALIGN( 8 ) ;
.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 = . ;
}
. = ALIGN( 8 ) ;
.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 )
}
2009-04-29 09:47:27 +02:00
/ *
* .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
* references f r o m . 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
* /
.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
}
# ifdef C O N F I G _ B L K _ D E V _ I N I T R D
. = ALIGN( P A G E _ S I Z E ) ;
.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
2009-04-29 09:47:25 +02:00
2009-04-29 09:47:28 +02:00
# if d e f i n e d ( C O N F I G _ X 8 6 _ 6 4 ) & & d e f i n e d ( C O N F I G _ S M P )
/ *
* percpu o f f s e t s a r e z e r o - b a s e d o n S M P . P E R C P U _ V A D D R ( ) c h a n g e s t h e
* output P H D R , s o t h e n e x t o u t p u t s e c t i o n - _ _ d a t a _ n o s a v e - s h o u l d
* start a n o t h e r s e c t i o n d a t a . i n i t 2 . A l s o , p d a s h o u l d b e a t t h e h e a d o f
* percpu a r e a . P r e a l l o c a t e i t a n d d e f i n e t h e p e r c p u o f f s e t s y m b o l
* so t h a t i t c a n b e a c c e s s e d a s a p e r c p u v a r i a b l e .
* /
. = ALIGN( P A G E _ S I Z E ) ;
PERCPU_ V A D D R ( 0 , : p e r c p u )
# else
PERCPU( P A G E _ S I Z E )
# endif
. = ALIGN( P A G E _ S I Z E ) ;
2009-04-29 12:56:58 +02:00
2009-04-29 09:47:28 +02:00
/* freed after init ends here */
2009-04-29 12:56:58 +02:00
.init .end : AT( A D D R ( . i n i t . e n d ) - L O A D _ O F F S E T ) {
_ _ init_ e n d = . ;
}
2009-04-29 09:47:28 +02:00
# ifdef C O N F I G _ X 8 6 _ 6 4
.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 ) {
. = ALIGN( P A G E _ S I Z E ) ;
_ _ nosave_ b e g i n = . ;
* ( .data .nosave )
. = ALIGN( P A G E _ S I Z E ) ;
_ _ nosave_ e n d = . ;
} : data. i n i t 2
/* use another section data.init2, see PERCPU_VADDR() above */
# endif
2009-04-29 09:47:29 +02:00
/* BSS */
. = ALIGN( P A G E _ S I Z E ) ;
.bss : AT( A D D R ( . b s s ) - L O A D _ O F F S E T ) {
_ _ bss_ s t a r t = . ;
* ( .bss .page_aligned )
* ( .bss )
. = ALIGN( 4 ) ;
_ _ bss_ s t o p = . ;
}
2009-04-29 09:47:28 +02:00
2009-04-29 09:47:29 +02:00
. = ALIGN( P A G E _ S I Z E ) ;
.brk : AT( A D D R ( . b r k ) - L O A D _ O F F S E T ) {
_ _ brk_ b a s e = . ;
. + = 6 4 * 1 0 2 4 ; /* 64k alignment slop space */
* ( .brk_reservation ) /* areas brk users have reserved */
_ _ brk_ l i m i t = . ;
}
.end : AT( A D D R ( . e n d ) - L O A D _ O F F S E T ) {
_ end = . ;
}
/* Sections to be discarded */
/ DISCARD/ : {
* ( .exitcall .exit )
* ( .eh_frame )
* ( .discard )
}
2009-04-29 09:47:18 +02:00
2009-04-29 09:47:20 +02:00
STABS_ D E B U G
DWARF_ D E B U G
}
2009-04-29 09:47:18 +02:00
# ifdef C O N F I G _ X 8 6 _ 3 2
2009-08-03 14:44:54 -07:00
. = ASSERT( ( _ e n d - L O A D _ O F F S E T < = K E R N E L _ I M A G E _ S I Z E ) ,
" kernel i m a g e b i g g e r t h a n K E R N E L _ I M A G E _ S I Z E " ) ;
2009-04-29 09:47:18 +02:00
# else
/ *
* Per- c p u s y m b o l s w h i c h n e e d t o b e o f f s e t f r o m _ _ p e r _ c p u _ l o a d
* for t h e b o o t p r o c e s s o r .
* /
# define I N I T _ P E R _ C P U ( x ) i n i t _ p e r _ c p u _ _ ## x = p e r _ c p u _ _ # # x + _ _ p e r _ c p u _ l o a d
INIT_ P E R _ C P U ( g d t _ p a g e ) ;
INIT_ P E R _ C P U ( i r q _ s t a c k _ u n i o n ) ;
/ *
* Build- t i m e c h e c k o n t h e i m a g e s i z e :
* /
2009-08-03 14:44:54 -07:00
. = ASSERT( ( _ e n d - _ t e x t < = K E R N E L _ I M A G E _ S I Z E ) ,
" kernel i m a g e b i g g e r t h a n K E R N E L _ I M A G E _ S I Z E " ) ;
2009-04-29 09:47:18 +02:00
# ifdef C O N F I G _ S M P
2009-08-03 14:44:54 -07:00
. = ASSERT( ( p e r _ c p u _ _ i r q _ s t a c k _ u n i o n = = 0 ) ,
" irq_ s t a c k _ u n i o n i s n o t a t s t a r t o f p e r - c p u a r e a " ) ;
2009-04-29 09:47:18 +02:00
# endif
# endif / * C O N F I G _ X 8 6 _ 3 2 * /
# ifdef C O N F I G _ K E X E C
# include < a s m / k e x e c . h >
2009-08-03 14:44:54 -07:00
. = ASSERT( k e x e c _ c o n t r o l _ c o d e _ s i z e < = K E X E C _ C O N T R O L _ C O D E _ M A X _ S I Z E ,
" kexec c o n t r o l c o d e s i z e i s t o o b i g " ) ;
2009-04-29 09:47:18 +02:00
# endif