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-10-14 14:46:56 -07: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 _ D E B U G _ R O D A T A )
2009-10-19 06:12:04 -07:00
/ *
* On 6 4 - b i t , a l i g n R O D A T A t o 2 M B s o t h a t e v e n w i t h C O N F I G _ D E B U G _ R O D A T A
* we r e t a i n l a r g e p a g e m a p p i n g s f o r b o u n d a r i e s s p a n n i n g k e r n e l t e x t , r o d a t a
* and d a t a s e c t i o n s .
*
* However, k e r n e l i d e n t i t y m a p p i n g s w i l l h a v e d i f f e r e n t R W X p e r m i s s i o n s
* to t h e p a g e s m a p p i n g t o t e x t a n d t o t h e p a g e s p a d d i n g ( w h i c h a r e f r e e d ) t h e
* text s e c t i o n . H e n c e k e r n e l i d e n t i t y m a p p i n g s w i l l b e b r o k e n t o s m a l l e r
* pages. F o r 6 4 - b i t , k e r n e l t e x t a n d k e r n e l i d e n t i t y m a p p i n g s a r e d i f f e r e n t ,
* so w e c a n e n a b l e p r o t e c t i o n c h e c k s t h a t c o m e w i t h C O N F I G _ D E B U G _ R O D A T A ,
* as w e l l a s r e t a i n 2 M B l a r g e p a g e m a p p i n g s f o r k e r n e l t e x t .
* /
2009-10-14 14:46:56 -07:00
# define X 6 4 _ A L I G N _ D E B U G _ R O D A T A _ B E G I N . = A L I G N ( H P A G E _ S I Z E ) ;
# define X 6 4 _ A L I G N _ D E B U G _ R O D A T A _ E N D \
. = ALIGN( H P A G E _ S I Z E ) ; \
_ _ end_ r o d a t a _ h p a g e _ a l i g n = . ;
# else
# define X 6 4 _ A L I G N _ D E B U G _ R O D A T A _ B E G I N
# define X 6 4 _ A L I G N _ D E B U G _ R O D A T A _ E N D
# 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
2009-09-04 09:18:07 +01:00
user P T _ L O A D F L A G S ( 5 ) ; /* R_E */
2009-04-29 09:47:19 +02:00
# ifdef C O N F I G _ S M P
2009-09-04 09:18:07 +01:00
percpu P T _ L O A D F L A G S ( 6 ) ; /* RW_ */
2009-04-29 09:47:19 +02:00
# endif
2009-08-25 14:50:53 +01:00
init P T _ L O A D F L A G S ( 7 ) ; /* RWE */
2009-04-29 09:47:19 +02:00
# 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 */
.text : AT( A D D R ( . t e x t ) - L O A D _ O F F S E T ) {
2009-09-16 16:44:28 -04:00
_ text = . ;
/* bootstrapping code */
HEAD_ T E X T
2009-04-29 09:47:21 +02:00
# ifdef C O N F I G _ X 8 6 _ 3 2
. = ALIGN( P A G E _ S I Z E ) ;
2010-02-20 01:03:49 +01:00
* ( .text . .page_aligned )
2009-04-29 09:47:21 +02:00
# 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-09-16 16:44:30 -04:00
EXCEPTION_ T A B L E ( 1 6 ) : t e x t = 0 x90 9 0
2009-04-29 09:47:22 +02:00
2009-10-14 14:46:56 -07:00
X6 4 _ A L I G N _ D E B U G _ R O D A T A _ B E G I N
2009-08-25 14:50:53 +01:00
RO_ D A T A ( P A G E _ S I Z E )
2009-10-14 14:46:56 -07:00
X6 4 _ A L I G N _ D E B U G _ R O D A T A _ E N D
2009-04-29 09:47:22 +02:00
2009-04-29 09:47:23 +02:00
/* Data */
.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-08-25 14:50:53 +01:00
/* init_task */
INIT_ T A S K _ D A T A ( T H R E A D _ S I Z E )
2009-04-29 09:47:23 +02:00
# ifdef C O N F I G _ X 8 6 _ 3 2
2009-08-25 14:50:53 +01:00
/* 32 bit has nosave before _edata */
NOSAVE_ D A T A
2009-04-29 09:47:23 +02:00
# endif
2009-08-25 14:50:53 +01:00
PAGE_ A L I G N E D _ D A T A ( P A G E _ S I Z E )
2009-04-29 09:47:23 +02:00
2009-11-13 11:54:40 +00:00
CACHELINE_ A L I G N E D _ D A T A ( L 1 _ C A C H E _ B Y T E S )
2009-04-29 09:47:23 +02:00
2009-08-25 14:50:53 +01:00
DATA_ D A T A
CONSTRUCTORS
/* rarely changed data like cpu maps */
2009-11-13 11:54:40 +00:00
READ_ M O S T L Y _ D A T A ( I N T E R N O D E _ C A C H E _ B Y T E S )
2009-04-29 09:47:23 +02:00
/* End of data section */
_ edata = . ;
2009-08-25 14:50:53 +01:00
} : data
2009-04-29 09:47:23 +02:00
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 )
2009-09-16 16:44:26 -04:00
# 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 _ 0 + L O A D _ O F F S E T )
2009-04-29 09:47:24 +02:00
# define V L O A D ( x ) ( A D D R ( x ) - V L O A D _ O F F S E T )
2009-09-16 16:44:26 -04:00
# 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 _ 0 )
2009-04-29 09:47:24 +02:00
# define V V I R T ( x ) ( A D D R ( x ) - V V I R T _ O F F S E T )
2009-09-16 16:44:26 -04:00
. = ALIGN( 4 0 9 6 ) ;
_ _ vsyscall_ 0 = . ;
2009-04-29 09:47:24 +02:00
. = VSYSCALL_ A D D R ;
2009-09-16 16:44:26 -04:00
.vsyscall_0 : AT( V L O A D ( . v s y s c a l l _ 0 ) ) {
2009-04-29 09:47:24 +02:00
* ( .vsyscall_0 )
} : user
2009-11-13 11:54:40 +00:00
. = ALIGN( L 1 _ C A C H E _ B Y T E S ) ;
2009-04-29 09:47:24 +02:00
.vsyscall_fn : AT( V L O A D ( . v s y s c a l l _ f n ) ) {
* ( .vsyscall_fn )
}
2009-11-13 11:54:40 +00:00
. = ALIGN( L 1 _ C A C H E _ B Y T E S ) ;
2009-04-29 09:47:24 +02:00
.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 ) ;
2009-11-13 11:54:40 +00:00
. = ALIGN( L 1 _ C A C H E _ B Y T E S ) ;
2009-04-29 09:47:24 +02:00
.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 )
}
2009-09-16 16:44:26 -04:00
. = _ _ vsyscall_ 0 + P A G E _ S I Z E ;
2009-04-29 09:47:24 +02:00
# undef V S Y S C A L L _ 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-08-25 14:50:53 +01:00
/* Init code and data - will be freed after init */
. = ALIGN( P A G E _ S I Z E ) ;
.init .begin : AT( A D D R ( . i n i t . b e g i n ) - L O A D _ O F F S E T ) {
_ _ init_ b e g i n = . ; /* paired with __init_end */
2009-04-29 09:47:25 +02:00
}
2009-08-25 14:50:53 +01: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 )
2009-04-29 09:47:25 +02:00
/ *
2009-08-25 14:50:53 +01:00
* 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 - . i n i t . t e x t - s h o u l d
* start a n o t h e r s e g m e n t - i n i t .
2009-04-29 09:47:25 +02:00
* /
2009-08-25 14:50:53 +01:00
PERCPU_ V A D D R ( 0 , : p e r c p u )
# endif
2009-04-29 09:47:25 +02:00
2009-09-16 16:44:30 -04:00
INIT_ T E X T _ S E C T I O N ( P A G E _ S I Z E )
2009-08-25 14:50:53 +01:00
# ifdef C O N F I G _ X 8 6 _ 6 4
: init
# endif
2009-04-29 09:47:25 +02:00
2009-09-16 16:44:30 -04:00
INIT_ D A T A _ S E C T I O N ( 1 6 )
2009-04-29 09:47:25 +02:00
.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 = . ;
}
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
}
2009-08-25 14:50:53 +01: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 )
2009-04-29 09:47:28 +02:00
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
2009-08-25 14:50:53 +01:00
/ *
* 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 )
. = ALIGN( P A G E _ S I Z E ) ;
2010-03-28 19:42:54 -07:00
_ _ smp_ l o c k s _ e n d = . ;
2009-08-25 14:50:53 +01:00
}
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 ) {
2009-08-25 14:50:53 +01:00
NOSAVE_ D A T A
}
2009-04-29 09:47:28 +02:00
# 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 = . ;
2010-02-20 01:03:38 +01:00
* ( .bss . .page_aligned )
2009-04-29 09:47:29 +02:00
* ( .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 = . ;
}
2009-12-14 13:55:20 -08:00
_ end = . ;
2009-04-29 09:47:29 +02:00
2009-04-29 09:47:20 +02:00
STABS_ D E B U G
DWARF_ D E B U G
linker script: unify usage of discard definition
Discarded sections in different archs share some commonality but have
considerable differences. This led to linker script for each arch
implementing its own /DISCARD/ definition, which makes maintaining
tedious and adding new entries error-prone.
This patch makes all linker scripts to move discard definitions to the
end of the linker script and use the common DISCARDS macro. As ld
uses the first matching section definition, archs can include default
discarded sections by including them earlier in the linker script.
ia64 is notable because it first throws away some ia64 specific
subsections and then include the rest of the sections into the final
image, so those sections must be discarded before the inclusion.
defconfig compile tested for x86, x86-64, powerpc, powerpc64, ia64,
alpha, sparc, sparc64 and s390. Michal Simek tested microblaze.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Tested-by: Michal Simek <monstr@monstr.eu>
Cc: linux-arch@vger.kernel.org
Cc: Michal Simek <monstr@monstr.eu>
Cc: microblaze-uclinux@itee.uq.edu.au
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Tony Luck <tony.luck@intel.com>
2009-07-09 11:27:40 +09:00
/* Sections to be discarded */
DISCARDS
/ DISCARD/ : { * ( . e h _ f r a m e ) }
2009-04-29 09:47:20 +02:00
}
2009-04-29 09:47:18 +02:00
# ifdef C O N F I G _ X 8 6 _ 3 2
2009-10-16 07:18:46 +02:00
/ *
* The A S S E R T ( ) s i n k t o . i s i n t e n t i o n a l , f o r b i n u t i l s 2 . 1 4 c o m p a t i b i l i t y :
* /
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 .
* /
2009-10-29 22:34:15 +09:00
# define I N I T _ P E R _ C P U ( x ) i n i t _ p e r _ c p u _ _ ## x = x + _ _ p e r _ c p u _ l o a d
2009-04-29 09:47:18 +02:00
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-10-29 22:34:15 +09:00
. = ASSERT( ( i r q _ s t a c k _ u n i o n = = 0 ) ,
2009-08-03 14:44:54 -07:00
" 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