aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/boot
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/boot')
-rw-r--r--arch/mips/boot/.gitignore3
-rw-r--r--arch/mips/boot/Makefile68
-rw-r--r--arch/mips/boot/addinitrd.c131
-rw-r--r--arch/mips/boot/compressed/Makefile120
-rw-r--r--arch/mips/boot/compressed/calc_vmlinuz_load_addr.c57
-rw-r--r--arch/mips/boot/compressed/dbg.c36
-rw-r--r--arch/mips/boot/compressed/decompress.c99
-rw-r--r--arch/mips/boot/compressed/dummy.c4
-rw-r--r--arch/mips/boot/compressed/head.S56
-rw-r--r--arch/mips/boot/compressed/ld.script53
-rw-r--r--arch/mips/boot/compressed/string.c28
-rw-r--r--arch/mips/boot/compressed/uart-16550.c63
-rw-r--r--arch/mips/boot/compressed/uart-alchemy.c6
l---------arch/mips/boot/dts/include/dt-bindings1
-rw-r--r--arch/mips/boot/ecoff.h63
-rw-r--r--arch/mips/boot/elf2ecoff.c12
16 files changed, 601 insertions, 199 deletions
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
index ba63401c6e1..a73d6e2c4f6 100644
--- a/arch/mips/boot/.gitignore
+++ b/arch/mips/boot/.gitignore
@@ -1,4 +1,7 @@
mkboot
elf2ecoff
+vmlinux.*
zImage
zImage.tmp
+calc_vmlinuz_load_addr
+uImage
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index 2a209d74f0b..1466c002609 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -11,39 +11,47 @@
# Some DECstations need all possible sections of an ECOFF executable
#
ifdef CONFIG_MACH_DECSTATION
- E2EFLAGS = -a
-else
- E2EFLAGS =
+ e2eflag := -a
endif
#
# Drop some uninteresting sections in the kernel.
# This is only relevant for ELF kernels but doesn't hurt a.out
#
-drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options
-strip-flags = $(addprefix --remove-section=,$(drop-sections))
-
-VMLINUX = vmlinux
-
-all: vmlinux.ecoff vmlinux.srec addinitrd
-
-vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
- $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
-
-$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
- $(HOSTCC) -o $@ $^
-
-vmlinux.bin: $(VMLINUX)
- $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
-
-vmlinux.srec: $(VMLINUX)
- $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
-
-$(obj)/addinitrd: $(obj)/addinitrd.c
- $(HOSTCC) -o $@ $^
-
-clean-files += addinitrd \
- elf2ecoff \
- vmlinux.bin \
- vmlinux.ecoff \
- vmlinux.srec
+drop-sections := .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags := $(addprefix --remove-section=,$(drop-sections))
+
+hostprogs-y := elf2ecoff
+
+targets := vmlinux.ecoff
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $(obj)/elf2ecoff $(VMLINUX) $@ $(e2eflag)
+$(obj)/vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) FORCE
+ $(call if_changed,ecoff)
+
+targets += vmlinux.bin
+quiet_cmd_bin = OBJCOPY $@
+ cmd_bin = $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.bin: $(VMLINUX) FORCE
+ $(call if_changed,bin)
+
+targets += vmlinux.srec
+quiet_cmd_srec = OBJCOPY $@
+ cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.srec: $(VMLINUX) FORCE
+ $(call if_changed,srec)
+
+UIMAGE_LOADADDR = $(VMLINUX_LOAD_ADDRESS)
+UIMAGE_ENTRYADDR = $(VMLINUX_ENTRY_ADDRESS)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+targets += uImage.gz
+$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,uimage,gzip)
+
+targets += uImage
+$(obj)/uImage: $(obj)/uImage.gz FORCE
+ @ln -sf $(notdir $<) $@
+ @echo ' Image $@ is ready'
diff --git a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c
deleted file mode 100644
index b5b3febc10c..00000000000
--- a/arch/mips/boot/addinitrd.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * addinitrd - program to add a initrd image to an ecoff kernel
- *
- * (C) 1999 Thomas Bogendoerfer
- * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
- * further cleanup: Maciej W. Rozycki
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <netinet/in.h>
-
-#include "ecoff.h"
-
-#define MIPS_PAGE_SIZE 4096
-#define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1)
-
-#define swab16(x) \
- ((unsigned short)( \
- (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
- (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
-
-#define swab32(x) \
- ((unsigned int)( \
- (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
- (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
- (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
- (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
-
-#define SWAB(a) (swab ? swab32(a) : (a))
-
-void die(char *s)
-{
- perror(s);
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- int fd_vmlinux, fd_initrd, fd_outfile;
- FILHDR efile;
- AOUTHDR eaout;
- SCNHDR esecs[3];
- struct stat st;
- char buf[1024];
- unsigned long loadaddr;
- unsigned long initrd_header[2];
- int i, cnt;
- int swab = 0;
-
- if (argc != 4) {
- printf("Usage: %s <vmlinux> <initrd> <outfile>\n", argv[0]);
- exit(1);
- }
-
- if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0)
- die("open vmlinux");
- if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
- die("read file header");
- if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
- die("read aout header");
- if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
- die("read section headers");
- /*
- * check whether the file is good for us
- */
- /* TBD */
-
- /*
- * check, if we have to swab words
- */
- if (ntohs(0xaa55) == 0xaa55) {
- if (efile.f_magic == swab16(MIPSELMAGIC))
- swab = 1;
- } else {
- if (efile.f_magic == swab16(MIPSEBMAGIC))
- swab = 1;
- }
-
- /* make sure we have an empty data segment for the initrd */
- if (eaout.dsize || esecs[1].s_size) {
- fprintf(stderr, "Data segment not empty. Giving up!\n");
- exit(1);
- }
- if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
- die("open initrd");
- if (fstat (fd_initrd, &st) < 0)
- die("fstat initrd");
- loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
- + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
- if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
- loadaddr += MIPS_PAGE_SIZE;
- initrd_header[0] = SWAB(0x494E5244);
- initrd_header[1] = SWAB(st.st_size);
- eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
- eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
-
- if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
- die("open outfile");
- if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
- die("write file header");
- if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
- die("write aout header");
- if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
- die("write section headers");
- /* skip padding */
- if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
- die("lseek vmlinux");
- if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
- die("lseek outfile");
- /* copy text segment */
- cnt = SWAB(eaout.tsize);
- while (cnt) {
- if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
- die("read vmlinux");
- if (write (fd_outfile, buf, i) != i)
- die("write vmlinux");
- cnt -= i;
- }
- if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
- die("write initrd header");
- while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
- if (write (fd_outfile, buf, i) != i)
- die("write initrd");
- close(fd_vmlinux);
- close(fd_initrd);
- return 0;
-}
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
new file mode 100644
index 00000000000..61af6b6ab13
--- /dev/null
+++ b/arch/mips/boot/compressed/Makefile
@@ -0,0 +1,120 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.
+#
+# Adapted for MIPS Pete Popov, Dan Malek
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
+# Author: Wu Zhangjin <wuzhangjin@gmail.com>
+#
+
+# set the default size of the mallocing area for decompressing
+BOOT_HEAP_SIZE := 0x400000
+
+# Disable Function Tracer
+KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
+
+KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS))
+
+KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
+
+KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
+ -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
+
+targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
+
+# decompressor objects (linked with vmlinuz)
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/dbg.o
+
+ifdef CONFIG_DEBUG_ZBOOT
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o
+endif
+
+ifdef CONFIG_KERNEL_XZ
+vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
+endif
+
+targets += vmlinux.bin
+OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
+$(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
+ $(call if_changed,objcopy)
+
+tool_$(CONFIG_KERNEL_GZIP) = gzip
+tool_$(CONFIG_KERNEL_BZIP2) = bzip2
+tool_$(CONFIG_KERNEL_LZ4) = lz4
+tool_$(CONFIG_KERNEL_LZMA) = lzma
+tool_$(CONFIG_KERNEL_LZO) = lzo
+tool_$(CONFIG_KERNEL_XZ) = xzkern
+
+targets += vmlinux.bin.z
+$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,$(tool_y))
+
+targets += piggy.o
+OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
+ --set-section-flags=.image=contents,alloc,load,readonly,data
+$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
+ $(call if_changed,objcopy)
+
+# Calculate the load address of the compressed kernel image
+hostprogs-y := calc_vmlinuz_load_addr
+
+ifeq ($(CONFIG_MACH_JZ4740),y)
+VMLINUZ_LOAD_ADDRESS := 0x80600000
+else
+VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
+ $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
+endif
+
+vmlinuzobjs-y += $(obj)/piggy.o
+
+quiet_cmd_zld = LD $@
+ cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
+quiet_cmd_strip = STRIP $@
+ cmd_strip = $(STRIP) -s $@
+vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/calc_vmlinuz_load_addr
+ $(call cmd,zld)
+ $(call cmd,strip)
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_MACH_DECSTATION
+ e2eflag := -a
+endif
+
+# elf2ecoff can only handle 32bit image
+hostprogs-y += ../elf2ecoff
+
+ifdef CONFIG_32BIT
+ VMLINUZ = vmlinuz
+else
+ VMLINUZ = vmlinuz.32
+endif
+
+quiet_cmd_32 = OBJCOPY $@
+ cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+vmlinuz.32: vmlinuz
+ $(call cmd,32)
+
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $< $(VMLINUZ) $@ $(e2eflag)
+vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
+ $(call cmd,ecoff)
+
+OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
+vmlinuz.bin: vmlinuz
+ $(call cmd,objcopy)
+
+OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
+vmlinuz.srec: vmlinuz
+ $(call cmd,objcopy)
+
+clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec}
diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
new file mode 100644
index 00000000000..37fe58c19a9
--- /dev/null
+++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhangjin@gmail.com>
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+ unsigned long long vmlinux_size, vmlinux_load_addr, vmlinuz_load_addr;
+ struct stat sb;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <pathname> <vmlinux_load_addr>\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (stat(argv[1], &sb) == -1) {
+ perror("stat");
+ return EXIT_FAILURE;
+ }
+
+ /* Convert hex characters to dec number */
+ errno = 0;
+ if (sscanf(argv[2], "%llx", &vmlinux_load_addr) != 1) {
+ if (errno != 0)
+ perror("sscanf");
+ else
+ fprintf(stderr, "No matching characters\n");
+
+ return EXIT_FAILURE;
+ }
+
+ vmlinux_size = (uint64_t)sb.st_size;
+ vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
+
+ /*
+ * Align with 16 bytes: "greater than that used for any standard data
+ * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition).
+ */
+
+ vmlinuz_load_addr += (16 - vmlinux_size % 16);
+
+ printf("0x%llx\n", vmlinuz_load_addr);
+
+ return EXIT_SUCCESS;
+}
diff --git a/arch/mips/boot/compressed/dbg.c b/arch/mips/boot/compressed/dbg.c
new file mode 100644
index 00000000000..06c6a5bd175
--- /dev/null
+++ b/arch/mips/boot/compressed/dbg.c
@@ -0,0 +1,36 @@
+/*
+ * MIPS-specific debug support for pre-boot environment
+ *
+ * NOTE: putc() is board specific, if your board have a 16550 compatible uart,
+ * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
+ * need to implement your own putc().
+ */
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+void __weak putc(char c)
+{
+}
+
+void puts(const char *s)
+{
+ char c;
+ while ((c = *s++) != '\0') {
+ putc(c);
+ if (c == '\n')
+ putc('\r');
+ }
+}
+
+void puthex(unsigned long long val)
+{
+
+ unsigned char buf[10];
+ int i;
+ for (i = 7; i >= 0; i--) {
+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
+ val >>= 4;
+ }
+ buf[8] = '\0';
+ puts(buf);
+}
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
new file mode 100644
index 00000000000..c00c4ddf451
--- /dev/null
+++ b/arch/mips/boot/compressed/decompress.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * 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>
+
+/*
+ * These two variables specify the free mem region
+ * 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
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+#ifdef CONFIG_KERNEL_XZ
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
+void decompress_kernel(unsigned long boot_heap_start)
+{
+ unsigned long zimage_start, zimage_size;
+
+ zimage_start = (unsigned long)(&__image_begin);
+ zimage_size = (unsigned long)(&__image_end) -
+ (unsigned long)(&__image_begin);
+
+ puts("zimage at: ");
+ puthex(zimage_start);
+ puts(" ");
+ puthex(zimage_size + zimage_start);
+ puts("\n");
+
+ /* This area are prepared for mallocing when decompressing */
+ free_mem_ptr = boot_heap_start;
+ free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
+
+ /* Display standard Linux/MIPS boot prompt */
+ puts("Uncompressing Linux at load address ");
+ puthex(VMLINUX_LOAD_ADDRESS_ULL);
+ puts("\n");
+
+ /* Decompress the kernel with according algorithm */
+ decompress((char *)zimage_start, zimage_size, 0, 0,
+ (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
+
+ /* FIXME: should we flush cache here? */
+ puts("Now, booting the kernel...\n");
+}
diff --git a/arch/mips/boot/compressed/dummy.c b/arch/mips/boot/compressed/dummy.c
new file mode 100644
index 00000000000..31dbf45bf99
--- /dev/null
+++ b/arch/mips/boot/compressed/dummy.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S
new file mode 100644
index 00000000000..409cb483a9f
--- /dev/null
+++ b/arch/mips/boot/compressed/head.S
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+ .set noreorder
+ .cprestore
+ LEAF(start)
+start:
+ /* Save boot rom start args */
+ move s0, a0
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ /* Clear BSS */
+ PTR_LA a0, _edata
+ PTR_LA a2, _end
+1: sw zero, 0(a0)
+ bne a2, a0, 1b
+ addiu a0, a0, 4
+
+ PTR_LA a0, (.heap) /* heap address */
+ PTR_LA sp, (.stack + 8192) /* stack address */
+
+ PTR_LA ra, 2f
+ PTR_LA k0, decompress_kernel
+ jr k0
+ nop
+2:
+ move a0, s0
+ move a1, s1
+ move a2, s2
+ move a3, s3
+ PTR_LI k0, KERNEL_ENTRY
+ jr k0
+ nop
+3:
+ b 3b
+ nop
+ END(start)
+
+ .comm .heap,BOOT_HEAP_SIZE,4
+ .comm .stack,4096*2,4
diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script
new file mode 100644
index 00000000000..5a33409c7f6
--- /dev/null
+++ b/arch/mips/boot/compressed/ld.script
@@ -0,0 +1,53 @@
+/*
+ * ld.script for compressed kernel support of MIPS
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzhanjing@gmail.com>
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhanjing@gmail.com>
+ */
+
+OUTPUT_ARCH(mips)
+ENTRY(start)
+PHDRS {
+ text PT_LOAD FLAGS(7); /* RWX */
+}
+SECTIONS
+{
+ /* Text and read-only data */
+ /* . = VMLINUZ_LOAD_ADDRESS; */
+ .text : {
+ *(.text)
+ *(.rodata)
+ }: text
+ /* End of text section */
+
+ /* Writable data */
+ .data : {
+ *(.data)
+ /* Put the compressed image here */
+ __image_begin = .;
+ *(.image)
+ __image_end = .;
+ CONSTRUCTORS
+ }
+ . = ALIGN(16);
+ _edata = .;
+ /* End of data section */
+
+ /* BSS */
+ .bss : {
+ *(.bss)
+ }
+ . = ALIGN(16);
+ _end = .;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.MIPS.options)
+ *(.options)
+ *(.pdr)
+ *(.reginfo)
+ *(.comment)
+ *(.note)
+ }
+}
diff --git a/arch/mips/boot/compressed/string.c b/arch/mips/boot/compressed/string.c
new file mode 100644
index 00000000000..9de9885acd0
--- /dev/null
+++ b/arch/mips/boot/compressed/string.c
@@ -0,0 +1,28 @@
+/*
+ * arch/mips/boot/compressed/string.c
+ *
+ * Very small subset of simple string routines
+ */
+
+#include <linux/types.h>
+
+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;
+}
+
+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;
+}
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
new file mode 100644
index 00000000000..237494b7a21
--- /dev/null
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -0,0 +1,63 @@
+/*
+ * 16550 compatible uart based serial debug support for zboot
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <asm/addrspace.h>
+
+#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
+#define UART_BASE 0x1fd003f8
+#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
+#endif
+
+#ifdef CONFIG_AR7
+#include <ar7.h>
+#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
+#endif
+
+#ifdef CONFIG_MACH_JZ4740
+#include <asm/mach-jz4740/base.h>
+#define PORT(offset) (CKSEG1ADDR(JZ4740_UART0_BASE_ADDR) + (4 * offset))
+#endif
+
+#ifdef CONFIG_CPU_XLR
+#define UART0_BASE 0x1EF14000
+#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
+#define IOTYPE unsigned int
+#endif
+
+#ifdef CONFIG_CPU_XLP
+#define UART0_BASE 0x18030100
+#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
+#define IOTYPE unsigned int
+#endif
+
+#ifndef IOTYPE
+#define IOTYPE char
+#endif
+
+#ifndef PORT
+#error please define the serial port address for your own machine
+#endif
+
+static inline unsigned int serial_in(int offset)
+{
+ return *((volatile IOTYPE *)PORT(offset)) & 0xFF;
+}
+
+static inline void serial_out(int offset, int value)
+{
+ *((volatile IOTYPE *)PORT(offset)) = value & 0xFF;
+}
+
+void putc(char c)
+{
+ int timeout = 1000000;
+
+ while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
+ ;
+
+ serial_out(UART_TX, c);
+}
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c
new file mode 100644
index 00000000000..4bee55b93f6
--- /dev/null
+++ b/arch/mips/boot/compressed/uart-alchemy.c
@@ -0,0 +1,6 @@
+#include <asm/mach-au1x00/au1000.h>
+
+void putc(char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/boot/dts/include/dt-bindings b/arch/mips/boot/dts/include/dt-bindings
new file mode 120000
index 00000000000..08c00e4972f
--- /dev/null
+++ b/arch/mips/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings \ No newline at end of file
diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h
index 8c3eed2877f..7a75ce2c1bc 100644
--- a/arch/mips/boot/ecoff.h
+++ b/arch/mips/boot/ecoff.h
@@ -2,48 +2,47 @@
* Some ECOFF definitions.
*/
typedef struct filehdr {
- unsigned short f_magic; /* magic number */
- unsigned short f_nscns; /* number of sections */
- long f_timdat; /* time & date stamp */
- long f_symptr; /* file pointer to symbolic header */
- long f_nsyms; /* sizeof(symbolic hdr) */
- unsigned short f_opthdr; /* sizeof(optional hdr) */
- unsigned short f_flags; /* flags */
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symbolic header */
+ long f_nsyms; /* sizeof(symbolic hdr) */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
} FILHDR;
-#define FILHSZ sizeof(FILHDR)
+#define FILHSZ sizeof(FILHDR)
-#define OMAGIC 0407
#define MIPSEBMAGIC 0x160
#define MIPSELMAGIC 0x162
typedef struct scnhdr {
- char s_name[8]; /* section name */
- long s_paddr; /* physical address, aliased s_nlib */
- long s_vaddr; /* virtual address */
- long s_size; /* section size */
- long s_scnptr; /* file ptr to raw data for section */
- long s_relptr; /* file ptr to relocation */
- long s_lnnoptr; /* file ptr to gp histogram */
- unsigned short s_nreloc; /* number of relocation entries */
- unsigned short s_nlnno; /* number of gp histogram entries */
- long s_flags; /* flags */
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address, aliased s_nlib */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* file ptr to raw data for section */
+ long s_relptr; /* file ptr to relocation */
+ long s_lnnoptr; /* file ptr to gp histogram */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of gp histogram entries */
+ long s_flags; /* flags */
} SCNHDR;
#define SCNHSZ sizeof(SCNHDR)
#define SCNROUND ((long)16)
typedef struct aouthdr {
- short magic; /* see above */
- short vstamp; /* version stamp */
- long tsize; /* text size in bytes, padded to DW bdry*/
- long dsize; /* initialized data " " */
- long bsize; /* uninitialized data " " */
- long entry; /* entry pt. */
- long text_start; /* base of text used for this file */
- long data_start; /* base of data used for this file */
- long bss_start; /* base of bss used for this file */
- long gprmask; /* general purpose register mask */
- long cprmask[4]; /* co-processor register masks */
- long gp_value; /* the gp value used for this object */
+ short magic; /* see above */
+ short vstamp; /* version stamp */
+ long tsize; /* text size in bytes, padded to DW bdry*/
+ long dsize; /* initialized data " " */
+ long bsize; /* uninitialized data " " */
+ long entry; /* entry pt. */
+ long text_start; /* base of text used for this file */
+ long data_start; /* base of data used for this file */
+ long bss_start; /* base of bss used for this file */
+ long gprmask; /* general purpose register mask */
+ long cprmask[4]; /* co-processor register masks */
+ long gp_value; /* the gp value used for this object */
} AOUTHDR;
#define AOUTHSZ sizeof(AOUTHDR)
@@ -51,7 +50,7 @@ typedef struct aouthdr {
#define NMAGIC 0410
#define ZMAGIC 0413
#define SMAGIC 0411
-#define LIBMAGIC 0443
+#define LIBMAGIC 0443
#define N_TXTOFF(f, a) \
((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
index c5a7f308c40..8585078ae50 100644
--- a/arch/mips/boot/elf2ecoff.c
+++ b/arch/mips/boot/elf2ecoff.c
@@ -29,7 +29,7 @@
/* elf2ecoff.c
This program converts an elf executable to an ECOFF executable.
- No symbol table is retained. This is useful primarily in building
+ No symbol table is retained. This is useful primarily in building
net-bootable kernels for machines (e.g., DECstation and Alpha) which
only support the ECOFF object file format. */
@@ -59,8 +59,8 @@ struct sect {
};
int *symTypeTable;
-int must_convert_endian = 0;
-int format_bigendian = 0;
+int must_convert_endian;
+int format_bigendian;
static void copy(int out, int in, off_t offset, off_t size)
{
@@ -341,7 +341,7 @@ int main(int argc, char *argv[])
/* Figure out if we can cram the program header into an ECOFF
header... Basically, we can't handle anything but loadable
- segments, but we can ignore some kinds of segments. We can't
+ segments, but we can ignore some kinds of segments. We can't
handle holes in the address space. Segments may be out of order,
so we sort them first. */
@@ -514,7 +514,7 @@ int main(int argc, char *argv[])
for (i = 0; i < nosecs; i++) {
printf
- ("Section %d: %s phys %lx size %lx file offset %lx\n",
+ ("Section %d: %s phys %lx size %lx file offset %lx\n",
i, esecs[i].s_name, esecs[i].s_paddr,
esecs[i].s_size, esecs[i].s_scnptr);
}
@@ -551,7 +551,7 @@ int main(int argc, char *argv[])
}
/*
- * Copy the loadable sections. Zero-fill any gaps less than 64k;
+ * Copy the loadable sections. Zero-fill any gaps less than 64k;
* complain about any zero-filling, and die if we're asked to zero-fill
* more than 64k.
*/