2005-04-17 05:20:36 +07:00
|
|
|
/*
|
|
|
|
* misc.c
|
|
|
|
*
|
|
|
|
* This is a collection of several routines from gzip-1.0.3
|
|
|
|
* adapted for Linux.
|
|
|
|
*
|
|
|
|
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
|
|
|
|
*
|
|
|
|
* Modified for ARM Linux by Russell King
|
|
|
|
*
|
|
|
|
* Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
|
|
|
|
* For this code to run directly from Flash, all constant variables must
|
|
|
|
* be marked with 'const' and all other variables initialized at run-time
|
|
|
|
* only. This way all non constant variables will end up in the bss segment,
|
|
|
|
* which should point to addresses in RAM and cleared to 0 on start.
|
|
|
|
* This allows for a much quicker boot time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
unsigned int __machine_arch_type;
|
|
|
|
|
2009-04-01 02:05:35 +07:00
|
|
|
#include <linux/compiler.h> /* for inline */
|
2011-09-14 08:42:55 +07:00
|
|
|
#include <linux/types.h>
|
2010-01-09 05:42:43 +07:00
|
|
|
#include <linux/linkage.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-03-28 16:24:33 +07:00
|
|
|
static void putstr(const char *ptr);
|
2010-03-11 01:10:28 +07:00
|
|
|
extern void error(char *x);
|
2006-03-28 16:24:33 +07:00
|
|
|
|
2013-03-14 14:47:27 +07:00
|
|
|
#include CONFIG_UNCOMPRESS_INCLUDE
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-03-28 16:24:33 +07:00
|
|
|
#ifdef CONFIG_DEBUG_ICEDCC
|
2006-09-20 19:03:34 +07:00
|
|
|
|
2011-03-24 04:46:15 +07:00
|
|
|
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
|
2006-09-20 19:03:34 +07:00
|
|
|
|
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
|
|
|
|
} while (status & (1 << 29));
|
|
|
|
|
|
|
|
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
|
|
|
|
}
|
2010-01-19 22:40:07 +07:00
|
|
|
|
|
|
|
|
2009-02-25 10:20:40 +07:00
|
|
|
#elif defined(CONFIG_CPU_XSCALE)
|
|
|
|
|
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
|
|
|
|
} while (status & (1 << 28));
|
|
|
|
|
|
|
|
asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
|
|
|
|
}
|
2006-09-20 19:03:34 +07:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-03-28 16:34:05 +07:00
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
2006-05-03 02:40:56 +07:00
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
|
2006-03-28 16:34:05 +07:00
|
|
|
} while (status & 2);
|
|
|
|
|
2006-05-03 02:40:56 +07:00
|
|
|
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
|
2006-03-28 16:34:05 +07:00
|
|
|
}
|
|
|
|
|
2006-09-20 19:03:34 +07:00
|
|
|
#endif
|
|
|
|
|
2006-03-28 16:24:33 +07:00
|
|
|
#define putc(ch) icedcc_putc(ch)
|
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-03-28 16:24:33 +07:00
|
|
|
static void putstr(const char *ptr)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-03-28 16:24:33 +07:00
|
|
|
char c;
|
|
|
|
|
|
|
|
while ((c = *ptr++) != '\0') {
|
|
|
|
if (c == '\n')
|
|
|
|
putc('\r');
|
|
|
|
putc(c);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2006-03-28 16:24:33 +07:00
|
|
|
|
|
|
|
flush();
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-04-20 03:13:23 +07:00
|
|
|
* gzip declarations
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
extern char input_data[];
|
|
|
|
extern char input_data_end[];
|
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 19:14:40 +07:00
|
|
|
unsigned char *output_data;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 19:14:40 +07:00
|
|
|
unsigned long free_mem_ptr;
|
|
|
|
unsigned long free_mem_end_ptr;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2005-11-09 05:43:05 +07:00
|
|
|
#ifndef arch_error
|
|
|
|
#define arch_error(x)
|
|
|
|
#endif
|
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 19:14:40 +07:00
|
|
|
void error(char *x)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2005-11-09 05:43:05 +07:00
|
|
|
arch_error(x);
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
putstr("\n\n");
|
|
|
|
putstr(x);
|
|
|
|
putstr("\n\n -- System halted");
|
|
|
|
|
|
|
|
while(1); /* Halt */
|
|
|
|
}
|
|
|
|
|
2010-01-09 05:42:43 +07:00
|
|
|
asmlinkage void __div0(void)
|
|
|
|
{
|
|
|
|
error("Attempting division by 0!");
|
|
|
|
}
|
|
|
|
|
2011-04-22 08:59:49 +07:00
|
|
|
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 19:14:40 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2011-04-20 03:13:23 +07:00
|
|
|
void
|
2010-01-09 05:42:43 +07:00
|
|
|
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
|
|
|
unsigned long free_mem_ptr_end_p,
|
|
|
|
int arch_id)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2011-04-22 08:59:49 +07:00
|
|
|
int ret;
|
2010-01-09 05:42:43 +07:00
|
|
|
|
|
|
|
output_data = (unsigned char *)output_start;
|
2005-04-17 05:20:36 +07:00
|
|
|
free_mem_ptr = free_mem_ptr_p;
|
2008-07-25 15:45:44 +07:00
|
|
|
free_mem_end_ptr = free_mem_ptr_end_p;
|
2005-04-17 05:20:36 +07:00
|
|
|
__machine_arch_type = arch_id;
|
|
|
|
|
|
|
|
arch_decomp_setup();
|
|
|
|
|
|
|
|
putstr("Uncompressing Linux...");
|
2011-04-22 08:59:49 +07:00
|
|
|
ret = do_decompress(input_data, input_data_end - input_data,
|
|
|
|
output_data, error);
|
|
|
|
if (ret)
|
|
|
|
error("decompressor returned an error");
|
|
|
|
else
|
|
|
|
putstr(" done, booting the kernel.\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|