2005-06-26 01:57:56 +04:00
/ *
* relocate_ k e r n e l . S - p u t t h e k e r n e l i m a g e i n p l a c e t o b o o t
* Copyright ( C ) 2 0 0 2 - 2 0 0 4 E r i c B i e d e r m a n < e b i e d e r m @xmission.com>
*
* This s o u r c e c o d e i s l i c e n s e d u n d e r t h e G N U G e n e r a l P u b l i c L i c e n s e ,
* Version 2 . S e e t h e f i l e C O P Y I N G f o r m o r e d e t a i l s .
* /
# include < l i n u x / l i n k a g e . h >
2006-09-26 12:52:38 +04:00
# include < a s m / p a g e . h >
# include < a s m / k e x e c . h >
2008-03-23 00:00:08 +03:00
# include < a s m / p r o c e s s o r - f l a g s . h >
2008-03-23 00:00:09 +03:00
# include < a s m / p g t a b l e . h >
2006-09-26 12:52:38 +04:00
/ *
* Must b e r e l o c a t a b l e P I C c o d e c a l l a b l e a s a C f u n c t i o n
* /
# define P T R ( x ) ( x < < 2 )
2008-03-23 00:00:09 +03:00
# define P A G E _ A T T R ( _ P A G E _ P R E S E N T | _ P A G E _ R W | _ P A G E _ A C C E S S E D | _ P A G E _ D I R T Y )
# define P A E _ P G D _ A T T R ( _ P A G E _ P R E S E N T )
2006-09-26 12:52:38 +04:00
.text
2008-03-21 23:12:14 +03:00
.align PAGE_SIZE
2006-09-26 12:52:38 +04:00
.globl relocate_kernel
relocate_kernel :
movl 8 ( % e s p ) , % e b p / * l i s t o f p a g e s * /
# ifdef C O N F I G _ X 8 6 _ P A E
/* map the control page at its virtual address */
movl P T R ( V A _ P G D ) ( % e b p ) , % e d i
movl P T R ( V A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x c00 0 0 0 0 0 , % e a x
shrl $ 2 7 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P M D _ 0 ) ( % e b p ) , % e d x
orl $ P A E _ P G D _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P M D _ 0 ) ( % e b p ) , % e d i
movl P T R ( V A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x3 f e 0 0 0 0 0 , % e a x
shrl $ 1 8 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P T E _ 0 ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P T E _ 0 ) ( % e b p ) , % e d i
movl P T R ( V A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x00 1 f f00 0 , % e a x
shrl $ 9 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
/* identity map the control page at its physical address */
movl P T R ( V A _ P G D ) ( % e b p ) , % e d i
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x c00 0 0 0 0 0 , % e a x
shrl $ 2 7 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P M D _ 1 ) ( % e b p ) , % e d x
orl $ P A E _ P G D _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P M D _ 1 ) ( % e b p ) , % e d i
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x3 f e 0 0 0 0 0 , % e a x
shrl $ 1 8 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P T E _ 1 ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P T E _ 1 ) ( % e b p ) , % e d i
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x00 1 f f00 0 , % e a x
shrl $ 9 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
# else
/* map the control page at its virtual address */
movl P T R ( V A _ P G D ) ( % e b p ) , % e d i
movl P T R ( V A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x f f c00 0 0 0 , % e a x
shrl $ 2 0 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P T E _ 0 ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P T E _ 0 ) ( % e b p ) , % e d i
movl P T R ( V A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x00 3 f f00 0 , % e a x
shrl $ 1 0 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
/* identity map the control page at its physical address */
movl P T R ( V A _ P G D ) ( % e b p ) , % e d i
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x f f c00 0 0 0 , % e a x
shrl $ 2 0 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ P T E _ 1 ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
movl P T R ( V A _ P T E _ 1 ) ( % e b p ) , % e d i
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e a x
andl $ 0 x00 3 f f00 0 , % e a x
shrl $ 1 0 , % e a x
addl % e d i , % e a x
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e d x
orl $ P A G E _ A T T R , % e d x
movl % e d x , ( % e a x )
# endif
2005-06-26 01:57:56 +04:00
relocate_new_kernel :
/* read the arguments and say goodbye to the stack */
movl 4 ( % e s p ) , % e b x / * p a g e _ l i s t * /
2006-09-26 12:52:38 +04:00
movl 8 ( % e s p ) , % e b p / * l i s t o f p a g e s * /
2005-06-26 01:57:56 +04:00
movl 1 2 ( % e s p ) , % e d x / * s t a r t a d d r e s s * /
movl 1 6 ( % e s p ) , % e c x / * c p u _ h a s _ p a e * /
/* zero out flags, and disable interrupts */
pushl $ 0
popfl
2006-09-26 12:52:38 +04:00
/* get physical address of control page now */
/* this is impossible after page table switch */
movl P T R ( P A _ C O N T R O L _ P A G E ) ( % e b p ) , % e d i
2005-06-26 01:57:56 +04:00
2006-09-26 12:52:38 +04:00
/* switch to new set of page tables */
movl P T R ( P A _ P G D ) ( % e b p ) , % e a x
movl % e a x , % c r3
/* setup a new stack at the end of the physical control page */
2008-03-23 00:00:07 +03:00
lea P A G E _ S I Z E ( % e d i ) , % e s p
2006-09-26 12:52:38 +04:00
/* jump to identity mapped page */
movl % e d i , % e a x
addl $ ( i d e n t i t y _ m a p p e d - r e l o c a t e _ k e r n e l ) , % e a x
pushl % e a x
ret
identity_mapped :
/* store the start address on the stack */
pushl % e d x
2005-06-26 01:57:56 +04:00
/ * Set c r0 t o a k n o w n s t a t e :
2008-03-23 00:00:08 +03:00
* - Paging d i s a b l e d
* - Alignment c h e c k d i s a b l e d
* - Write p r o t e c t d i s a b l e d
* - No t a s k s w i t c h
* - Don' t d o F P s o f t w a r e e m u l a t i o n .
* - Proctected m o d e e n a b l e d
2005-06-26 01:57:56 +04:00
* /
movl % c r0 , % e a x
2008-03-23 00:00:08 +03:00
andl $ ~ ( X 8 6 _ C R 0 _ P G | X 8 6 _ C R 0 _ A M | X 8 6 _ C R 0 _ W P | X 8 6 _ C R 0 _ T S | X 8 6 _ C R 0 _ E M ) , % e a x
orl $ ( X 8 6 _ C R 0 _ P E ) , % e a x
2005-06-26 01:57:56 +04:00
movl % e a x , % c r0
/* clear cr4 if applicable */
testl % e c x , % e c x
jz 1 f
/ * Set c r4 t o a k n o w n s t a t e :
* Setting e v e r y t h i n g t o z e r o s e e m s s a f e .
* /
2008-03-23 00:00:06 +03:00
xorl % e a x , % e a x
2005-06-26 01:57:56 +04:00
movl % e a x , % c r4
jmp 1 f
1 :
/* Flush the TLB (needed?) */
xorl % e a x , % e a x
movl % e a x , % c r3
/* Do the copies */
movl % e b x , % e c x
jmp 1 f
0 : /* top, read another word from the indirection page */
movl ( % e b x ) , % e c x
addl $ 4 , % e b x
1 :
testl $ 0 x1 , % e c x / * i s i t a d e s t i n a t i o n p a g e * /
jz 2 f
movl % e c x , % e d i
andl $ 0 x f f f f f00 0 , % e d i
jmp 0 b
2 :
testl $ 0 x2 , % e c x / * i s i t a n i n d i r e c t i o n p a g e * /
jz 2 f
movl % e c x , % e b x
andl $ 0 x f f f f f00 0 , % e b x
jmp 0 b
2 :
testl $ 0 x4 , % e c x / * i s i t t h e d o n e i n d i c a t o r * /
jz 2 f
jmp 3 f
2 :
testl $ 0 x8 , % e c x / * i s i t t h e s o u r c e i n d i c a t o r * /
jz 0 b / * I g n o r e i t o t h e r w i s e * /
movl % e c x , % e s i / * F o r e v e r y s o u r c e p a g e d o a c o p y * /
andl $ 0 x f f f f f00 0 , % e s i
movl $ 1 0 2 4 , % e c x
rep ; movsl
jmp 0 b
3 :
/ * To b e c e r t a i n o f a v o i d i n g p r o b l e m s w i t h s e l f - m o d i f y i n g c o d e
* I n e e d t o e x e c u t e a s e r i a l i z i n g i n s t r u c t i o n h e r e .
* So I f l u s h t h e T L B , i t ' s h a n d y , a n d n o t p r o c e s s o r d e p e n d e n t .
* /
xorl % e a x , % e a x
movl % e a x , % c r3
/* set all of the registers to known values */
/* leave %esp alone */
xorl % e a x , % e a x
xorl % e b x , % e b x
xorl % e c x , % e c x
xorl % e d x , % e d x
xorl % e s i , % e s i
xorl % e d i , % e d i
xorl % e b p , % e b p
ret