2005-04-17 06:20:36 +08: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 03:05:35 +08:00
|
|
|
#include <linux/compiler.h> /* for inline */
|
2011-09-14 09:42:55 +08:00
|
|
|
#include <linux/types.h>
|
2010-01-09 06:42:43 +08:00
|
|
|
#include <linux/linkage.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-03-28 17:24:33 +08:00
|
|
|
static void putstr(const char *ptr);
|
2010-03-11 02:10:28 +08:00
|
|
|
extern void error(char *x);
|
2006-03-28 17:24:33 +08:00
|
|
|
|
ARM: initial multiplatform support
This lets us build a multiplatform kernel for experimental purposes.
However, it will not be useful for any real work, because it relies
on a number of useful things to be disabled for now:
* SMP support must be turned off because of conflicting symbols.
Marc Zyngier has proposed a solution by adding a new SOC
operations structure to hold indirect function pointers
for these, but that work is currently stalled
* We turn on SPARSE_IRQ unconditionally, which is not supported
on most platforms. Each of them is currently in a different
state, but most are being worked on.
* A common clock framework is in place since v3.4 but not yet
being used. Work on this is on its way.
* DEBUG_LL for early debugging is currently disabled.
* THUMB2_KERNEL does not work with allyesconfig because the
kernel gets too big
[Rob Herring]: Rebased to not be dependent on the mass mach header rename.
As a result, omap2plus, imx, mxs and ux500 are not converted. Highbank,
picoxcell, mvebu, and socfpga are converted.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Acked-by: Jamie Iles <jamie@jamieiles.com>
Cc: Dinh Nguyen <dinguyen@altera.com>
2012-09-07 02:41:12 +08:00
|
|
|
#ifdef CONFIG_ARCH_MULTIPLATFORM
|
|
|
|
static inline void putc(int c) {}
|
|
|
|
static inline void flush(void) {}
|
|
|
|
static inline void arch_decomp_setup(void) {}
|
|
|
|
#else
|
2008-08-05 23:14:15 +08:00
|
|
|
#include <mach/uncompress.h>
|
ARM: initial multiplatform support
This lets us build a multiplatform kernel for experimental purposes.
However, it will not be useful for any real work, because it relies
on a number of useful things to be disabled for now:
* SMP support must be turned off because of conflicting symbols.
Marc Zyngier has proposed a solution by adding a new SOC
operations structure to hold indirect function pointers
for these, but that work is currently stalled
* We turn on SPARSE_IRQ unconditionally, which is not supported
on most platforms. Each of them is currently in a different
state, but most are being worked on.
* A common clock framework is in place since v3.4 but not yet
being used. Work on this is on its way.
* DEBUG_LL for early debugging is currently disabled.
* THUMB2_KERNEL does not work with allyesconfig because the
kernel gets too big
[Rob Herring]: Rebased to not be dependent on the mass mach header rename.
As a result, omap2plus, imx, mxs and ux500 are not converted. Highbank,
picoxcell, mvebu, and socfpga are converted.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Acked-by: Jamie Iles <jamie@jamieiles.com>
Cc: Dinh Nguyen <dinguyen@altera.com>
2012-09-07 02:41:12 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-03-28 17:24:33 +08:00
|
|
|
#ifdef CONFIG_DEBUG_ICEDCC
|
2006-09-20 20:03:34 +08:00
|
|
|
|
2011-03-24 05:46:15 +08:00
|
|
|
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
|
2006-09-20 20:03:34 +08: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 23:40:07 +08:00
|
|
|
|
|
|
|
|
2009-02-25 11:20:40 +08: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 20:03:34 +08:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-03-28 17:34:05 +08:00
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
2006-05-03 03:40:56 +08:00
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
|
2006-03-28 17:34:05 +08:00
|
|
|
} while (status & 2);
|
|
|
|
|
2006-05-03 03:40:56 +08:00
|
|
|
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
|
2006-03-28 17:34:05 +08:00
|
|
|
}
|
|
|
|
|
2006-09-20 20:03:34 +08:00
|
|
|
#endif
|
|
|
|
|
2006-03-28 17:24:33 +08:00
|
|
|
#define putc(ch) icedcc_putc(ch)
|
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-03-28 17:24:33 +08:00
|
|
|
static void putstr(const char *ptr)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2006-03-28 17:24:33 +08:00
|
|
|
char c;
|
|
|
|
|
|
|
|
while ((c = *ptr++) != '\0') {
|
|
|
|
if (c == '\n')
|
|
|
|
putc('\r');
|
|
|
|
putc(c);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2006-03-28 17:24:33 +08:00
|
|
|
|
|
|
|
flush();
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-04-20 04:13:23 +08:00
|
|
|
* gzip declarations
|
2005-04-17 06:20:36 +08: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 20:14:40 +08:00
|
|
|
unsigned char *output_data;
|
2005-04-17 06:20:36 +08: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 20:14:40 +08:00
|
|
|
unsigned long free_mem_ptr;
|
|
|
|
unsigned long free_mem_end_ptr;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2005-11-09 06:43:05 +08: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 20:14:40 +08:00
|
|
|
void error(char *x)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2005-11-09 06:43:05 +08:00
|
|
|
arch_error(x);
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
putstr("\n\n");
|
|
|
|
putstr(x);
|
|
|
|
putstr("\n\n -- System halted");
|
|
|
|
|
|
|
|
while(1); /* Halt */
|
|
|
|
}
|
|
|
|
|
2010-01-09 06:42:43 +08:00
|
|
|
asmlinkage void __div0(void)
|
|
|
|
{
|
|
|
|
error("Attempting division by 0!");
|
|
|
|
}
|
|
|
|
|
2011-04-22 09:59:49 +08: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 20:14:40 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-04-20 04:13:23 +08:00
|
|
|
void
|
2010-01-09 06:42:43 +08: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 06:20:36 +08:00
|
|
|
{
|
2011-04-22 09:59:49 +08:00
|
|
|
int ret;
|
2010-01-09 06:42:43 +08:00
|
|
|
|
|
|
|
output_data = (unsigned char *)output_start;
|
2005-04-17 06:20:36 +08:00
|
|
|
free_mem_ptr = free_mem_ptr_p;
|
2008-07-25 16:45:44 +08:00
|
|
|
free_mem_end_ptr = free_mem_ptr_end_p;
|
2005-04-17 06:20:36 +08:00
|
|
|
__machine_arch_type = arch_id;
|
|
|
|
|
|
|
|
arch_decomp_setup();
|
|
|
|
|
|
|
|
putstr("Uncompressing Linux...");
|
2011-04-22 09:59:49 +08: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 06:20:36 +08:00
|
|
|
}
|