@ -100,6 +100,53 @@ mem_init_ret:
jmp g e t _ m e m _ s i z e
get_mem_size_ret :
/ *
* We a r e n o w i n ' F l a t P r o t e c t e d M o d e ' a n d w e k n o w h o w m u c h m e m o r y
* the b o a r d h a s . T h e ( t e m p o r a r y ) G l o b a l D e s c r i p t o r T a b l e i s n o t
* in a ' S a f e ' p l a c e ( i t i s e i t h e r i n F l a s h w h i c h c a n b e e r a s e d o r
* reprogrammed o r i n a f a i l - s a f e b o o t - s t r a p i m a g e w h i c h c o u l d b e
* over- w r i t t e n ) .
*
* Move t h e f i n a l g d t t o a s a f e p l a c e ( t o p o f R A M ) a n d l o a d i t .
* This i s n o t a t r i v i a l e x c e r c i s e - t h e l g d t i n s t r u c t i o n d o e s n o t
* have a r e g i s t e r o p e r a n d ( m e m o r y o n l y ) a n d w e m a y w e l l b e
* running f r o m F l a s h , s o s e l f m o d i f y i n g c o d e w i l l n o t w o r k h e r e .
* To o v e r c o m e t h i s , w e c o p y a s t u b i n t o u p p e r m e m o r y a l o n g w i t h
* the G D T .
* /
/* Reduce upper memory limit by (Stub + GDT Pointer + GDT) */
subl $ ( e n d _ g d t _ s e t u p - s t a r t _ g d t _ s e t u p ) , % e a x
/* Copy the GDT and Stub */
movl $ s t a r t _ g d t _ s e t u p , % e s i
movl % e a x , % e d i
movl $ ( e n d _ g d t _ s e t u p - s t a r t _ g d t _ s e t u p ) , % e c x
shrl $ 2 , % e c x
cld
rep m o v s l
/* write the lgdt 'parameter' */
subl $ ( j m p _ i n s t r - s t a r t _ g d t _ s e t u p - 4 ) , % e b p
addl % e a x , % e b p
movl $ ( g d t _ p t r - s t a r t _ g d t _ s e t u p ) , % e b x
addl % e a x , % e b x
movl % e b x , ( % e b p )
/* write the gdt address into the pointer */
movl $ ( g d t _ a d d r - s t a r t _ g d t _ s e t u p ) , % e b p
addl % e a x , % e b p
movl $ ( g d t - s t a r t _ g d t _ s e t u p ) , % e b x
addl % e a x , % e b x
movl % e b x , ( % e b p )
/* Save the return address */
movl $ l o a d _ g d t _ r e t , % e b p
/* Load the new (safe) Global Descriptor Table */
jmp * % e a x
load_gdt_ret :
/* Check we have enough memory for stack */
movl $ C O N F I G _ S Y S _ S T A C K _ S I Z E , % e c x
cmpl % e c x , % e a x
@ -174,3 +221,52 @@ die: hlt
blank_idt_ptr :
.word 0 /* limit */
.long 0 /* base */
.align 4
start_gdt_setup :
lgdt g d t _ p t r
jmp_instr :
jmp * % e b p
.align 4
gdt_ptr :
.word 0x30 /* limit (48 bytes = 6 GDT entries) */
gdt_addr :
.long gdt /* base */
/ * The G D T t a b l e . . .
*
* Selector T y p e
* 0 x0 0 N U L L
* 0 x0 8 U n u s e d
* 0 x1 0 3 2 b i t c o d e
* 0 x1 8 3 2 b i t d a t a / s t a c k
* 0 x2 0 1 6 b i t c o d e
* 0 x2 8 1 6 b i t d a t a / s t a c k
* /
.align 4
gdt :
.word 0 , 0 , 0 , 0 /* NULL */
.word 0 , 0 , 0 , 0 /* unused */
.word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */
.word 0 /* base address = 0 */
.word 0x9B00 /* code read/exec */
.word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */
.word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */
.word 0x0 /* base address = 0 */
.word 0x9300 /* data read/write */
.word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */
.word 0xFFFF /* 64kb */
.word 0 /* base address = 0 */
.word 0x9b00 /* data read/write */
.word 0x0010 /* granularity = 1 (+5th nibble of limit) */
.word 0xFFFF /* 64kb */
.word 0 /* base address = 0 */
.word 0x9300 /* data read/write */
.word 0x0010 /* granularity = 1 (+5th nibble of limit) */
end_gdt_setup :