2009-10-14 18:12:16 +08:00
/*
* Copyright 2001 MontaVista Software Inc .
2010-06-16 15:52:20 +08:00
* Author : Matt Porter < mporter @ mvista . com >
2009-10-14 18:12:16 +08:00
*
2010-01-04 17:16:51 +08:00
* Copyright ( C ) 2009 Lemote , Inc .
* Author : Wu Zhangjin < wuzhangjin @ gmail . com >
2009-10-14 18:12:16 +08:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*/
# include <linux/types.h>
# include <linux/kernel.h>
# include <asm/addrspace.h>
2010-06-16 15:52:20 +08:00
/*
* These two variables specify the free mem region
2009-10-14 18:12:16 +08:00
* that can be used for temporary malloc area
*/
unsigned long free_mem_ptr ;
unsigned long free_mem_end_ptr ;
/* The linker tells us where the image is. */
extern unsigned char __image_begin , __image_end ;
/* debug interfaces */
extern void puts ( const char * s ) ;
extern void puthex ( unsigned long long val ) ;
void error ( char * x )
{
puts ( " \n \n " ) ;
puts ( x ) ;
puts ( " \n \n -- System halted " ) ;
while ( 1 )
; /* Halt */
}
/* activate the code for pre-boot environment */
# define STATIC static
# ifdef CONFIG_KERNEL_GZIP
void * memcpy ( void * dest , const void * src , size_t n )
{
int i ;
const char * s = src ;
char * d = dest ;
for ( i = 0 ; i < n ; i + + )
d [ i ] = s [ i ] ;
return dest ;
}
# include "../../../../lib/decompress_inflate.c"
# endif
# ifdef CONFIG_KERNEL_BZIP2
void * memset ( void * s , int c , size_t n )
{
int i ;
char * ss = s ;
for ( i = 0 ; i < n ; i + + )
ss [ i ] = c ;
return s ;
}
# include "../../../../lib/decompress_bunzip2.c"
# endif
# ifdef CONFIG_KERNEL_LZMA
# include "../../../../lib/decompress_unlzma.c"
# endif
2010-01-15 20:34:46 +08:00
# ifdef CONFIG_KERNEL_LZO
# include "../../../../lib/decompress_unlzo.c"
# endif
2009-10-14 18:12:16 +08:00
void decompress_kernel ( unsigned long boot_heap_start )
{
2010-06-16 15:52:20 +08:00
unsigned long zimage_start , zimage_size ;
zimage_start = ( unsigned long ) ( & __image_begin ) ;
2009-10-14 18:12:16 +08:00
zimage_size = ( unsigned long ) ( & __image_end ) -
( unsigned long ) ( & __image_begin ) ;
puts ( " zimage at: " ) ;
2010-06-16 15:52:20 +08:00
puthex ( zimage_start ) ;
2009-10-14 18:12:16 +08:00
puts ( " " ) ;
2010-06-16 15:52:20 +08:00
puthex ( zimage_size + zimage_start ) ;
2009-10-14 18:12:16 +08:00
puts ( " \n " ) ;
2010-06-16 15:52:20 +08:00
/* This area are prepared for mallocing when decompressing */
2009-10-14 18:12:16 +08:00
free_mem_ptr = boot_heap_start ;
free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE ;
2010-06-16 15:52:20 +08:00
/* Display standard Linux/MIPS boot prompt */
2009-10-14 18:12:16 +08:00
puts ( " Uncompressing Linux at load address " ) ;
puthex ( VMLINUX_LOAD_ADDRESS_ULL ) ;
puts ( " \n " ) ;
2010-06-16 15:52:20 +08:00
2009-10-14 18:12:16 +08:00
/* Decompress the kernel with according algorithm */
2010-06-16 15:52:20 +08:00
decompress ( ( char * ) zimage_start , zimage_size , 0 , 0 ,
2009-10-14 18:12:16 +08:00
( void * ) VMLINUX_LOAD_ADDRESS_ULL , 0 , error ) ;
2010-06-16 15:52:20 +08:00
/* FIXME: should we flush cache here? */
2009-10-14 18:12:16 +08:00
puts ( " Now, booting the kernel... \n " ) ;
}