aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/boot
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-08-04 07:59:13 -0400
committerMichal Marek <mmarek@suse.cz>2010-08-04 07:59:13 -0400
commit772320e84588dcbe1600ffb83e5f328f2209ac2a (patch)
treea7de21b79340aeaa17c58126f6b801b82c77b53a /arch/s390/boot
parent1ce53adf13a54375d2a5c7cdbe341b2558389615 (diff)
parent9fe6206f400646a2322096b56c59891d530e8d51 (diff)
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts: arch/powerpc/Makefile
Diffstat (limited to 'arch/s390/boot')
-rw-r--r--arch/s390/boot/Makefile8
-rw-r--r--arch/s390/boot/compressed/Makefile63
-rw-r--r--arch/s390/boot/compressed/head31.S51
-rw-r--r--arch/s390/boot/compressed/head64.S48
-rw-r--r--arch/s390/boot/compressed/misc.c162
-rw-r--r--arch/s390/boot/compressed/vmlinux.lds.S55
-rw-r--r--arch/s390/boot/compressed/vmlinux.scr10
7 files changed, 397 insertions, 0 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 4d97eef36b8d..8800cf090694 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -9,10 +9,18 @@ COMPILE_VERSION := __linux_compile_version_id__`hostname | \
9EXTRA_CFLAGS := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. 9EXTRA_CFLAGS := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
10 10
11targets := image 11targets := image
12targets += bzImage
13subdir- := compressed
12 14
13$(obj)/image: vmlinux FORCE 15$(obj)/image: vmlinux FORCE
14 $(call if_changed,objcopy) 16 $(call if_changed,objcopy)
15 17
18$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
19 $(call if_changed,objcopy)
20
21$(obj)/compressed/vmlinux: FORCE
22 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
23
16install: $(CONFIGURE) $(obj)/image 24install: $(CONFIGURE) $(obj)/image
17 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ 25 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
18 System.map Kerntypes "$(INSTALL_PATH)" 26 System.map Kerntypes "$(INSTALL_PATH)"
diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile
new file mode 100644
index 000000000000..1c999f726a58
--- /dev/null
+++ b/arch/s390/boot/compressed/Makefile
@@ -0,0 +1,63 @@
1#
2# linux/arch/s390/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7BITS := $(if $(CONFIG_64BIT),64,31)
8
9targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
10 vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o sizes.h head$(BITS).o
11
12KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
13KBUILD_CFLAGS += $(cflags-y)
14KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
15KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
16
17GCOV_PROFILE := n
18
19OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
20OBJECTS += $(obj)/head$(BITS).o $(obj)/misc.o $(obj)/piggy.o
21
22LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
23$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
24 $(call if_changed,ld)
25 @:
26
27sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
28
29quiet_cmd_sizes = GEN $@
30 cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
31
32$(obj)/sizes.h: vmlinux
33 $(call if_changed,sizes)
34
35AFLAGS_head$(BITS).o += -I$(obj)
36$(obj)/head$(BITS).o: $(obj)/sizes.h
37
38CFLAGS_misc.o += -I$(obj)
39$(obj)/misc.o: $(obj)/sizes.h
40
41OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
42$(obj)/vmlinux.bin: vmlinux
43 $(call if_changed,objcopy)
44
45vmlinux.bin.all-y := $(obj)/vmlinux.bin
46
47suffix-$(CONFIG_KERNEL_GZIP) := gz
48suffix-$(CONFIG_KERNEL_BZIP2) := bz2
49suffix-$(CONFIG_KERNEL_LZMA) := lzma
50suffix-$(CONFIG_KERNEL_LZO) := lzo
51
52$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
53 $(call if_changed,gzip)
54$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
55 $(call if_changed,bzip2)
56$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
57 $(call if_changed,lzma)
58$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
59 $(call if_changed,lzo)
60
61LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
62$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
63 $(call if_changed,ld)
diff --git a/arch/s390/boot/compressed/head31.S b/arch/s390/boot/compressed/head31.S
new file mode 100644
index 000000000000..2a5523a32bcc
--- /dev/null
+++ b/arch/s390/boot/compressed/head31.S
@@ -0,0 +1,51 @@
1/*
2 * Startup glue code to uncompress the kernel
3 *
4 * Copyright IBM Corp. 2010
5 *
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#include <linux/init.h>
10#include <asm/asm-offsets.h>
11#include <asm/thread_info.h>
12#include <asm/page.h>
13#include "sizes.h"
14
15__HEAD
16 .globl startup_continue
17startup_continue:
18 basr %r13,0 # get base
19.LPG1:
20 # setup stack
21 l %r15,.Lstack-.LPG1(%r13)
22 ahi %r15,-96
23 l %r1,.Ldecompress-.LPG1(%r13)
24 basr %r14,%r1
25 # setup registers for memory mover & branch to target
26 lr %r4,%r2
27 l %r2,.Loffset-.LPG1(%r13)
28 la %r4,0(%r2,%r4)
29 l %r3,.Lmvsize-.LPG1(%r13)
30 lr %r5,%r3
31 # move the memory mover someplace safe
32 la %r1,0x200
33 mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
34 # decompress image is started at 0x11000
35 lr %r6,%r2
36 br %r1
37mover:
38 mvcle %r2,%r4,0
39 jo mover
40 br %r6
41mover_end:
42
43 .align 8
44.Lstack:
45 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
46.Ldecompress:
47 .long decompress_kernel
48.Loffset:
49 .long 0x11000
50.Lmvsize:
51 .long SZ__bss_start
diff --git a/arch/s390/boot/compressed/head64.S b/arch/s390/boot/compressed/head64.S
new file mode 100644
index 000000000000..2982cb140550
--- /dev/null
+++ b/arch/s390/boot/compressed/head64.S
@@ -0,0 +1,48 @@
1/*
2 * Startup glue code to uncompress the kernel
3 *
4 * Copyright IBM Corp. 2010
5 *
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#include <linux/init.h>
10#include <asm/asm-offsets.h>
11#include <asm/thread_info.h>
12#include <asm/page.h>
13#include "sizes.h"
14
15__HEAD
16 .globl startup_continue
17startup_continue:
18 basr %r13,0 # get base
19.LPG1:
20 # setup stack
21 lg %r15,.Lstack-.LPG1(%r13)
22 aghi %r15,-160
23 brasl %r14,decompress_kernel
24 # setup registers for memory mover & branch to target
25 lgr %r4,%r2
26 lg %r2,.Loffset-.LPG1(%r13)
27 la %r4,0(%r2,%r4)
28 lg %r3,.Lmvsize-.LPG1(%r13)
29 lgr %r5,%r3
30 # move the memory mover someplace safe
31 la %r1,0x200
32 mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
33 # decompress image is started at 0x11000
34 lgr %r6,%r2
35 br %r1
36mover:
37 mvcle %r2,%r4,0
38 jo mover
39 br %r6
40mover_end:
41
42 .align 8
43.Lstack:
44 .quad 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
45.Loffset:
46 .quad 0x11000
47.Lmvsize:
48 .quad SZ__bss_start
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
new file mode 100644
index 000000000000..0851eb1e919e
--- /dev/null
+++ b/arch/s390/boot/compressed/misc.c
@@ -0,0 +1,162 @@
1/*
2 * Definitions and wrapper functions for kernel decompressor
3 *
4 * Copyright IBM Corp. 2010
5 *
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 */
8
9#include <asm/uaccess.h>
10#include <asm/page.h>
11#include <asm/ipl.h>
12#include "sizes.h"
13
14/*
15 * gzip declarations
16 */
17#define STATIC static
18
19#undef memset
20#undef memcpy
21#undef memmove
22#define memzero(s, n) memset((s), 0, (n))
23
24/* Symbols defined by linker scripts */
25extern char input_data[];
26extern int input_len;
27extern char _text, _end;
28extern char _bss, _ebss;
29
30static void error(char *m);
31
32static unsigned long free_mem_ptr;
33static unsigned long free_mem_end_ptr;
34
35#ifdef CONFIG_HAVE_KERNEL_BZIP2
36#define HEAP_SIZE 0x400000
37#else
38#define HEAP_SIZE 0x10000
39#endif
40
41#ifdef CONFIG_KERNEL_GZIP
42#include "../../../../lib/decompress_inflate.c"
43#endif
44
45#ifdef CONFIG_KERNEL_BZIP2
46#include "../../../../lib/decompress_bunzip2.c"
47#endif
48
49#ifdef CONFIG_KERNEL_LZMA
50#include "../../../../lib/decompress_unlzma.c"
51#endif
52
53#ifdef CONFIG_KERNEL_LZO
54#include "../../../../lib/decompress_unlzo.c"
55#endif
56
57extern _sclp_print_early(const char *);
58
59int puts(const char *s)
60{
61 _sclp_print_early(s);
62 return 0;
63}
64
65void *memset(void *s, int c, size_t n)
66{
67 char *xs;
68
69 if (c == 0)
70 return __builtin_memset(s, 0, n);
71
72 xs = (char *) s;
73 if (n > 0)
74 do {
75 *xs++ = c;
76 } while (--n > 0);
77 return s;
78}
79
80void *memcpy(void *__dest, __const void *__src, size_t __n)
81{
82 return __builtin_memcpy(__dest, __src, __n);
83}
84
85void *memmove(void *__dest, __const void *__src, size_t __n)
86{
87 char *d;
88 const char *s;
89
90 if (__dest <= __src)
91 return __builtin_memcpy(__dest, __src, __n);
92 d = __dest + __n;
93 s = __src + __n;
94 while (__n--)
95 *--d = *--s;
96 return __dest;
97}
98
99static void error(char *x)
100{
101 unsigned long long psw = 0x000a0000deadbeefULL;
102
103 puts("\n\n");
104 puts(x);
105 puts("\n\n -- System halted");
106
107 asm volatile("lpsw %0" : : "Q" (psw));
108}
109
110/*
111 * Safe guard the ipl parameter block against a memory area that will be
112 * overwritten. The validity check for the ipl parameter block is complex
113 * (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
114 * the ipl parameter block intersects with the passed memory area we can
115 * safely assume that we can read from that memory. In that case just copy
116 * the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
117 * block.
118 */
119static void check_ipl_parmblock(void *start, unsigned long size)
120{
121 void *src, *dst;
122
123 src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
124 if (src + PAGE_SIZE <= start || src >= start + size)
125 return;
126 dst = (void *) IPL_PARMBLOCK_ORIGIN;
127 memmove(dst, src, PAGE_SIZE);
128 S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
129}
130
131unsigned long decompress_kernel(void)
132{
133 unsigned long output_addr;
134 unsigned char *output;
135
136 check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
137 memset(&_bss, 0, &_ebss - &_bss);
138 free_mem_ptr = (unsigned long)&_end;
139 free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
140 output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
141
142#ifdef CONFIG_BLK_DEV_INITRD
143 /*
144 * Move the initrd right behind the end of the decompressed
145 * kernel image.
146 */
147 if (INITRD_START && INITRD_SIZE &&
148 INITRD_START < (unsigned long) output + SZ__bss_start) {
149 check_ipl_parmblock(output + SZ__bss_start,
150 INITRD_START + INITRD_SIZE);
151 memmove(output + SZ__bss_start,
152 (void *) INITRD_START, INITRD_SIZE);
153 INITRD_START = (unsigned long) output + SZ__bss_start;
154 }
155#endif
156
157 puts("Uncompressing Linux... ");
158 decompress(input_data, input_len, NULL, NULL, output, NULL, error);
159 puts("Ok, booting the kernel.\n");
160 return (unsigned long) output;
161}
162
diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S
new file mode 100644
index 000000000000..d80f79d8dd9c
--- /dev/null
+++ b/arch/s390/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,55 @@
1#include <asm-generic/vmlinux.lds.h>
2
3#ifdef CONFIG_64BIT
4OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
5OUTPUT_ARCH(s390:64-bit)
6#else
7OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
8OUTPUT_ARCH(s390)
9#endif
10
11ENTRY(startup)
12
13SECTIONS
14{
15 /* Be careful parts of head_64.S assume startup_32 is at
16 * address 0.
17 */
18 . = 0;
19 .head.text : {
20 _head = . ;
21 HEAD_TEXT
22 _ehead = . ;
23 }
24 .rodata.compressed : {
25 *(.rodata.compressed)
26 }
27 .text : {
28 _text = .; /* Text */
29 *(.text)
30 *(.text.*)
31 _etext = . ;
32 }
33 .rodata : {
34 _rodata = . ;
35 *(.rodata) /* read-only data */
36 *(.rodata.*)
37 _erodata = . ;
38 }
39 .data : {
40 _data = . ;
41 *(.data)
42 *(.data.*)
43 _edata = . ;
44 }
45 . = ALIGN(256);
46 .bss : {
47 _bss = . ;
48 *(.bss)
49 *(.bss.*)
50 *(COMMON)
51 . = ALIGN(8); /* For convenience during zeroing */
52 _ebss = .;
53 }
54 _end = .;
55}
diff --git a/arch/s390/boot/compressed/vmlinux.scr b/arch/s390/boot/compressed/vmlinux.scr
new file mode 100644
index 000000000000..f02382ae5c48
--- /dev/null
+++ b/arch/s390/boot/compressed/vmlinux.scr
@@ -0,0 +1,10 @@
1SECTIONS
2{
3 .rodata.compressed : {
4 input_len = .;
5 LONG(input_data_end - input_data) input_data = .;
6 *(.data)
7 output_len = . - 4;
8 input_data_end = .;
9 }
10}