diff options
Diffstat (limited to 'target/linux/xburst/files-2.6.32/arch/mips/boot/compressed')
5 files changed, 524 insertions, 0 deletions
diff --git a/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/Makefile b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/Makefile new file mode 100644 index 0000000..90f36e6 --- /dev/null +++ b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/Makefile @@ -0,0 +1,42 @@ +# +# linux/arch/mips/boot/compressed/Makefile +# +# create a compressed zImage from the original vmlinux +# + +targets := zImage vmlinuz vmlinux.bin.gz head.o misc.o piggy.o dummy.o + +OBJS := $(obj)/head.o $(obj)/misc.o + +LD_ARGS := -T $(obj)/ld.script -Ttext 0x80600000 -Bstatic +OBJCOPY_ARGS := -O elf32-tradlittlemips + +ENTRY := $(obj)/../tools/entry +FILESIZE := $(obj)/../tools/filesize + +drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + + +$(obj)/vmlinux.bin.gz: vmlinux + rm -f $(obj)/vmlinux.bin.gz + $(OBJCOPY) -O binary $(strip-flags) vmlinux $(obj)/vmlinux.bin + gzip -v9f $(obj)/vmlinux.bin + +$(obj)/head.o: $(obj)/head.S $(obj)/vmlinux.bin.gz vmlinux + $(CC) $(KBUILD_AFLAGS) \ + -DIMAGESIZE=$(shell sh $(FILESIZE) $(obj)/vmlinux.bin.gz) \ + -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) vmlinux ) \ + -DLOADADDR=$(loadaddr) \ + -c -o $(obj)/head.o $< + +$(obj)/vmlinuz: $(OBJS) $(obj)/ld.script $(obj)/vmlinux.bin.gz $(obj)/dummy.o + $(OBJCOPY) \ + --add-section=.image=$(obj)/vmlinux.bin.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/dummy.o $(obj)/piggy.o + $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/piggy.o + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap + +zImage: $(obj)/vmlinuz + $(OBJCOPY) -O binary $(obj)/vmlinuz $(obj)/zImage diff --git a/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/dummy.c b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/dummy.c new file mode 100644 index 0000000..31dbf45 --- /dev/null +++ b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/head.S b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/head.S new file mode 100644 index 0000000..d9700eb --- /dev/null +++ b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/head.S @@ -0,0 +1,85 @@ +/* + * linux/arch/mips/boot/compressed/head.S + * + * Copyright (C) 2005-2008 Ingenic Semiconductor Inc. + */ + +#include <asm/asm.h> +#include <asm/cacheops.h> +#include <asm/cachectl.h> +#include <asm/regdef.h> + +#define IndexInvalidate_I 0x00 +#define IndexWriteBack_D 0x01 + + .set noreorder + LEAF(startup) +startup: + move s0, a0 /* Save the boot loader transfered args */ + move s1, a1 + move s2, a2 + move s3, a3 + + la a0, _edata + la a1, _end +1: sw zero, 0(a0) /* Clear BSS section */ + bne a1, a0, 1b + addu a0, 4 + + la sp, (.stack + 8192) + + la a0, __image_begin + la a1, IMAGESIZE + la a2, LOADADDR + la ra, 1f + la k0, decompress_kernel + jr k0 + nop +1: + + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + li k0, KERNEL_ENTRY + jr k0 + nop +2: + b 32 + END(startup) + + + LEAF(flushcaches) + la t0, 1f + la t1, 0xa0000000 + or t0, t0, t1 + jr t0 + nop +1: + li k0, 0x80000000 # start address + li k1, 0x80004000 # end address (16KB I-Cache) + subu k1, 128 + +2: + .set mips3 + cache IndexWriteBack_D, 0(k0) + cache IndexWriteBack_D, 32(k0) + cache IndexWriteBack_D, 64(k0) + cache IndexWriteBack_D, 96(k0) + cache IndexInvalidate_I, 0(k0) + cache IndexInvalidate_I, 32(k0) + cache IndexInvalidate_I, 64(k0) + cache IndexInvalidate_I, 96(k0) + .set mips0 + + bne k0, k1, 2b + addu k0, k0, 128 + la t0, 3f + jr t0 + nop +3: + jr ra + nop + END(flushcaches) + + .comm .stack,4096*2,4 diff --git a/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/ld.script b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/ld.script new file mode 100644 index 0000000..fcf8ba0 --- /dev/null +++ b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/ld.script @@ -0,0 +1,151 @@ +OUTPUT_ARCH(mips) +ENTRY(startup) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __ramdisk_begin = .; + *(.initrd) + __ramdisk_end = .; + . = ALIGN(4096); + + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff --git a/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/misc.c b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/misc.c new file mode 100644 index 0000000..2309fee --- /dev/null +++ b/target/linux/xburst/files-2.6.32/arch/mips/boot/compressed/misc.c @@ -0,0 +1,242 @@ +/* + * linux/arch/mips/boot/compressed/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 + * + * Adapted for JZSOC by Peter Wei, 2008 + * + */ + +#define size_t int +#define NULL 0 + +/* + * gzip declarations + */ + +#define OF(args) args +#define STATIC static + +#undef memset +#undef memcpy +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +void* memset(void* s, int c, size_t n); +void* memcpy(void* __dest, __const void* __src, size_t __n); + +extern void flushcaches(void); /* defined in head.S */ + +char *input_data; +int input_len; + +static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; + + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +static void puts(const char *str) +{ +} + +extern unsigned char _end[]; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#define HEAP_SIZE 0x10000 + +#include "../../../../lib/inflate.c" + +static void *malloc(int size) +{ + void *p; + + if (size <0) error("Malloc error\n"); + if (free_mem_ptr == 0) error("Memory error\n"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *)free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_end_ptr) + error("\nOut of memory\n"); + + return p; +} + +static void free(void *where) +{ /* Don't care */ +} + +static void gzip_mark(void **ptr) +{ + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + free_mem_ptr = (long) *ptr; +} + +void* memset(void* s, int c, size_t n) +{ + int i; + char *ss = (char*)s; + + for (i=0;i<n;i++) ss[i] = c; + return s; +} + +void* memcpy(void* __dest, __const void* __src, size_t __n) +{ + 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; +} + +/* =========================================================================== + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +static int fill_inbuf(void) +{ + if (insize != 0) { + error("ran out of input data\n"); + } + + inbuf = input_data; + insize = input_len; + inptr = 1; + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +static void flush_window(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; +} + +static void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +void decompress_kernel(unsigned int imageaddr, unsigned int imagesize, unsigned int loadaddr) +{ + input_data = (char *)imageaddr; + input_len = imagesize; + output_ptr = 0; + output_data = (uch *)loadaddr; + free_mem_ptr = (unsigned long)_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + + makecrc(); + puts("Uncompressing Linux..."); + gunzip(); + flushcaches(); + puts("Ok, booting the kernel."); +} |