2005-04-16 22:20:36 +00: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;
|
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
#define _LINUX_STRING_H_
|
|
|
|
|
2009-03-31 19:05:35 +00:00
|
|
|
#include <linux/compiler.h> /* for inline */
|
|
|
|
#include <linux/types.h> /* for size_t */
|
|
|
|
#include <linux/stddef.h> /* for NULL */
|
2010-01-08 22:42:43 +00:00
|
|
|
#include <linux/linkage.h>
|
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 12:14:40 +00:00
|
|
|
#include <asm/string.h>
|
2010-01-08 22:42:43 +00:00
|
|
|
|
|
|
|
#include <asm/unaligned.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
static void putstr(const char *ptr);
|
2010-03-10 18:10:28 +00:00
|
|
|
extern void error(char *x);
|
2006-03-28 09:24:33 +00:00
|
|
|
|
2008-08-05 15:14:15 +00:00
|
|
|
#include <mach/uncompress.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
#ifdef CONFIG_DEBUG_ICEDCC
|
2006-09-20 12:03:34 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_CPU_V6
|
|
|
|
|
|
|
|
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 15:40:07 +00:00
|
|
|
|
|
|
|
#elif defined(CONFIG_CPU_V7)
|
|
|
|
|
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
asm(
|
|
|
|
"wait: mrc p14, 0, pc, c0, c1, 0 \n\
|
|
|
|
bcs wait \n\
|
|
|
|
mcr p14, 0, %0, c0, c5, 0 "
|
|
|
|
: : "r" (ch));
|
|
|
|
}
|
|
|
|
|
2009-02-25 03:20:40 +00: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 12:03:34 +00:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-03-28 09:34:05 +00:00
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
2006-05-02 19:40:56 +00:00
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
|
2006-03-28 09:34:05 +00:00
|
|
|
} while (status & 2);
|
|
|
|
|
2006-05-02 19:40:56 +00:00
|
|
|
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
|
2006-03-28 09:34:05 +00:00
|
|
|
}
|
|
|
|
|
2006-09-20 12:03:34 +00:00
|
|
|
#endif
|
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
#define putc(ch) icedcc_putc(ch)
|
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
static void putstr(const char *ptr)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2006-03-28 09:24:33 +00:00
|
|
|
char c;
|
|
|
|
|
|
|
|
while ((c = *ptr++) != '\0') {
|
|
|
|
if (c == '\n')
|
|
|
|
putc('\r');
|
|
|
|
putc(c);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2006-03-28 09:24:33 +00:00
|
|
|
|
|
|
|
flush();
|
2005-04-16 22:20:36 +00: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 12:14:40 +00:00
|
|
|
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
|
|
|
|
|
|
|
for (i = __n >> 3; i > 0; i--) {
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (__n & 1 << 2) {
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (__n & 1 << 1) {
|
|
|
|
*d++ = *s++;
|
|
|
|
*d++ = *s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (__n & 1)
|
|
|
|
*d++ = *s++;
|
|
|
|
|
|
|
|
return __dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gzip delarations
|
|
|
|
*/
|
|
|
|
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 12:14:40 +00:00
|
|
|
unsigned char *output_data;
|
|
|
|
unsigned long output_ptr;
|
2005-04-16 22:20:36 +00: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 12:14:40 +00:00
|
|
|
unsigned long free_mem_ptr;
|
|
|
|
unsigned long free_mem_end_ptr;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-11-08 22:43:05 +00: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 12:14:40 +00:00
|
|
|
void error(char *x)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2005-11-08 22:43:05 +00:00
|
|
|
arch_error(x);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
putstr("\n\n");
|
|
|
|
putstr(x);
|
|
|
|
putstr("\n\n -- System halted");
|
|
|
|
|
|
|
|
while(1); /* Halt */
|
|
|
|
}
|
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
asmlinkage void __div0(void)
|
|
|
|
{
|
|
|
|
error("Attempting division by 0!");
|
|
|
|
}
|
|
|
|
|
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 12:14:40 +00:00
|
|
|
extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
unsigned long
|
|
|
|
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
|
|
|
unsigned long free_mem_ptr_end_p,
|
|
|
|
int arch_id)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2010-01-08 22:42:43 +00:00
|
|
|
unsigned char *tmp;
|
|
|
|
|
|
|
|
output_data = (unsigned char *)output_start;
|
2005-04-16 22:20:36 +00:00
|
|
|
free_mem_ptr = free_mem_ptr_p;
|
2008-07-25 08:45:44 +00:00
|
|
|
free_mem_end_ptr = free_mem_ptr_end_p;
|
2005-04-16 22:20:36 +00:00
|
|
|
__machine_arch_type = arch_id;
|
|
|
|
|
|
|
|
arch_decomp_setup();
|
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
|
|
|
|
output_ptr = get_unaligned_le32(tmp);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
putstr("Uncompressing Linux...");
|
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 12:14:40 +00:00
|
|
|
do_decompress(input_data, input_data_end - input_data,
|
|
|
|
output_data, error);
|
2005-04-16 22:20:36 +00:00
|
|
|
putstr(" done, booting the kernel.\n");
|
|
|
|
return output_ptr;
|
|
|
|
}
|