Commit 70fac51feaf2ca50c84e102e2a2699eb19ef24bd
1 parent
96cf5185a9
Exists in
master
and in
7 other branches
unicore32 additional architecture files: boot process
This patch implements booting process, including uncompression process. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Showing 7 changed files with 546 additions and 0 deletions Side-by-side Diff
arch/unicore32/boot/Makefile
1 | +# | |
2 | +# arch/unicore32/boot/Makefile | |
3 | +# | |
4 | +# This file is included by the global makefile so that you can add your own | |
5 | +# architecture-specific flags and dependencies. | |
6 | +# | |
7 | +# This file is subject to the terms and conditions of the GNU General Public | |
8 | +# License. See the file "COPYING" in the main directory of this archive | |
9 | +# for more details. | |
10 | +# | |
11 | +# Copyright (C) 2001~2010 GUAN Xue-tao | |
12 | +# | |
13 | + | |
14 | +MKIMAGE := $(srctree)/scripts/mkuboot.sh | |
15 | + | |
16 | +targets := Image zImage uImage | |
17 | + | |
18 | +$(obj)/Image: vmlinux FORCE | |
19 | + $(call if_changed,objcopy) | |
20 | + @echo ' Kernel: $@ is ready' | |
21 | + | |
22 | +$(obj)/compressed/vmlinux: $(obj)/Image FORCE | |
23 | + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ | |
24 | + | |
25 | +$(obj)/zImage: $(obj)/compressed/vmlinux FORCE | |
26 | + $(call if_changed,objcopy) | |
27 | + @echo ' Kernel: $@ is ready' | |
28 | + | |
29 | +quiet_cmd_uimage = UIMAGE $@ | |
30 | + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A unicore -O linux -T kernel \ | |
31 | + -C none -a $(LOADADDR) -e $(STARTADDR) \ | |
32 | + -n 'Linux-$(KERNELRELEASE)' -d $< $@ | |
33 | + | |
34 | +$(obj)/uImage: LOADADDR=0x0 | |
35 | + | |
36 | +$(obj)/uImage: STARTADDR=$(LOADADDR) | |
37 | + | |
38 | +$(obj)/uImage: $(obj)/zImage FORCE | |
39 | + $(call if_changed,uimage) | |
40 | + @echo ' Image $@ is ready' | |
41 | + | |
42 | +PHONY += initrd FORCE | |
43 | +initrd: | |
44 | + @test "$(INITRD)" != "" || \ | |
45 | + (echo You must specify INITRD; exit -1) | |
46 | + | |
47 | +subdir- := compressed |
arch/unicore32/boot/compressed/Makefile
1 | +# | |
2 | +# linux/arch/unicore32/boot/compressed/Makefile | |
3 | +# | |
4 | +# create a compressed vmlinuz image from the original vmlinux | |
5 | +# | |
6 | +# This file is subject to the terms and conditions of the GNU General Public | |
7 | +# License. See the file "COPYING" in the main directory of this archive | |
8 | +# for more details. | |
9 | +# | |
10 | +# Copyright (C) 2001~2010 GUAN Xue-tao | |
11 | +# | |
12 | + | |
13 | +EXTRA_CFLAGS := -fpic -fno-builtin | |
14 | +EXTRA_AFLAGS := -Wa,-march=all | |
15 | + | |
16 | +OBJS := misc.o | |
17 | + | |
18 | +# font.c and font.o | |
19 | +CFLAGS_font.o := -Dstatic= | |
20 | +$(obj)/font.c: $(srctree)/drivers/video/console/font_8x8.c | |
21 | + $(call cmd,shipped) | |
22 | + | |
23 | +# piggy.S and piggy.o | |
24 | +suffix_$(CONFIG_KERNEL_GZIP) := gzip | |
25 | +suffix_$(CONFIG_KERNEL_BZIP2) := bz2 | |
26 | +suffix_$(CONFIG_KERNEL_LZO) := lzo | |
27 | +suffix_$(CONFIG_KERNEL_LZMA) := lzma | |
28 | + | |
29 | +$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE | |
30 | + $(call if_changed,$(suffix_y)) | |
31 | + | |
32 | +SEDFLAGS_piggy = s/DECOMP_SUFFIX/$(suffix_y)/ | |
33 | +$(obj)/piggy.S: $(obj)/piggy.S.in | |
34 | + @sed "$(SEDFLAGS_piggy)" < $< > $@ | |
35 | + | |
36 | +$(obj)/piggy.o: $(obj)/piggy.$(suffix_y) $(obj)/piggy.S FORCE | |
37 | + | |
38 | +targets := vmlinux vmlinux.lds font.o font.c head.o misc.o \ | |
39 | + piggy.$(suffix_y) piggy.o piggy.S \ | |
40 | + | |
41 | +# Make sure files are removed during clean | |
42 | +extra-y += piggy.gzip piggy.bz2 piggy.lzo piggy.lzma | |
43 | + | |
44 | +# ? | |
45 | +LDFLAGS_vmlinux += -p | |
46 | +# Report unresolved symbol references | |
47 | +LDFLAGS_vmlinux += --no-undefined | |
48 | +# Delete all temporary local symbols | |
49 | +LDFLAGS_vmlinux += -X | |
50 | +# Next argument is a linker script | |
51 | +LDFLAGS_vmlinux += -T | |
52 | + | |
53 | +# For uidivmod | |
54 | +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head.o $(obj)/piggy.o \ | |
55 | + $(obj)/misc.o FORCE | |
56 | + $(call if_changed,ld) | |
57 | + @: | |
58 | + | |
59 | +# We now have a PIC decompressor implementation. Decompressors running | |
60 | +# from RAM should not define ZTEXTADDR. Decompressors running directly | |
61 | +# from ROM or Flash must define ZTEXTADDR (preferably via the config) | |
62 | +ZTEXTADDR := 0 | |
63 | +ZBSSADDR := ALIGN(4) | |
64 | + | |
65 | +SEDFLAGS_lds = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ | |
66 | +$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/unicore32/boot/Makefile $(KCONFIG_CONFIG) | |
67 | + @sed "$(SEDFLAGS_lds)" < $< > $@ |
arch/unicore32/boot/compressed/head.S
1 | +/* | |
2 | + * linux/arch/unicore32/boot/compressed/head.S | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | +#include <linux/linkage.h> | |
13 | +#include <mach/memory.h> | |
14 | + | |
15 | +#define csub cmpsub | |
16 | +#define cand cmpand | |
17 | +#define nop8 nop; nop; nop; nop; nop; nop; nop; nop | |
18 | + | |
19 | + .section ".start", #alloc, #execinstr | |
20 | + .text | |
21 | +start: | |
22 | + .type start,#function | |
23 | + | |
24 | + /* Initialize ASR, PRIV mode and INTR off */ | |
25 | + mov r0, #0xD3 | |
26 | + mov.a asr, r0 | |
27 | + | |
28 | + adr r0, LC0 | |
29 | + ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+ | |
30 | + ldw sp, [r0+], #28 | |
31 | + sub.a r0, r0, r1 @ calculate the delta offset | |
32 | + | |
33 | + /* | |
34 | + * if delta is zero, we are running at the address | |
35 | + * we were linked at. | |
36 | + */ | |
37 | + beq not_relocated | |
38 | + | |
39 | + /* | |
40 | + * We're running at a different address. We need to fix | |
41 | + * up various pointers: | |
42 | + * r5 - zImage base address (_start) | |
43 | + * r7 - GOT start | |
44 | + * r8 - GOT end | |
45 | + */ | |
46 | + add r5, r5, r0 | |
47 | + add r7, r7, r0 | |
48 | + add r8, r8, r0 | |
49 | + | |
50 | + /* | |
51 | + * we need to fix up pointers into the BSS region. | |
52 | + * r2 - BSS start | |
53 | + * r3 - BSS end | |
54 | + * sp - stack pointer | |
55 | + */ | |
56 | + add r2, r2, r0 | |
57 | + add r3, r3, r0 | |
58 | + add sp, sp, r0 | |
59 | + | |
60 | + /* | |
61 | + * Relocate all entries in the GOT table. | |
62 | + * This fixes up the C references. | |
63 | + * r7 - GOT start | |
64 | + * r8 - GOT end | |
65 | + */ | |
66 | +1001: ldw r1, [r7+], #0 | |
67 | + add r1, r1, r0 | |
68 | + stw.w r1, [r7]+, #4 | |
69 | + csub.a r7, r8 | |
70 | + bub 1001b | |
71 | + | |
72 | +not_relocated: | |
73 | + /* | |
74 | + * Clear BSS region. | |
75 | + * r2 - BSS start | |
76 | + * r3 - BSS end | |
77 | + */ | |
78 | + mov r0, #0 | |
79 | +1002: stw.w r0, [r2]+, #4 | |
80 | + csub.a r2, r3 | |
81 | + bub 1002b | |
82 | + | |
83 | + /* | |
84 | + * Turn on the cache. | |
85 | + */ | |
86 | + mov r0, #0 | |
87 | + movc p0.c5, r0, #28 @ cache invalidate all | |
88 | + nop8 | |
89 | + movc p0.c6, r0, #6 @ tlb invalidate all | |
90 | + nop8 | |
91 | + | |
92 | + mov r0, #0x1c @ en icache and wb dcache | |
93 | + movc p0.c1, r0, #0 | |
94 | + nop8 | |
95 | + | |
96 | + /* | |
97 | + * Set up some pointers, for starting decompressing. | |
98 | + */ | |
99 | + | |
100 | + mov r1, sp @ malloc space above stack | |
101 | + add r2, sp, #0x10000 @ 64k max | |
102 | + | |
103 | + /* | |
104 | + * Check to see if we will overwrite ourselves. | |
105 | + * r4 = final kernel address | |
106 | + * r5 = start of this image | |
107 | + * r6 = size of decompressed image | |
108 | + * r2 = end of malloc space (and therefore this image) | |
109 | + * We basically want: | |
110 | + * r4 >= r2 -> OK | |
111 | + * r4 + image length <= r5 -> OK | |
112 | + */ | |
113 | + ldw r4, =KERNEL_IMAGE_START | |
114 | + csub.a r4, r2 | |
115 | + bea wont_overwrite | |
116 | + add r0, r4, r6 | |
117 | + csub.a r0, r5 | |
118 | + beb wont_overwrite | |
119 | + | |
120 | + /* | |
121 | + * If overwrite, just print error message | |
122 | + */ | |
123 | + b __error_overwrite | |
124 | + | |
125 | + /* | |
126 | + * We're not in danger of overwriting ourselves. | |
127 | + * Do this the simple way. | |
128 | + */ | |
129 | +wont_overwrite: | |
130 | + /* | |
131 | + * decompress_kernel: | |
132 | + * r0: output_start | |
133 | + * r1: free_mem_ptr_p | |
134 | + * r2: free_mem_ptr_end_p | |
135 | + */ | |
136 | + mov r0, r4 | |
137 | + b.l decompress_kernel @ C functions | |
138 | + | |
139 | + /* | |
140 | + * Clean and flush the cache to maintain consistency. | |
141 | + */ | |
142 | + mov r0, #0 | |
143 | + movc p0.c5, r0, #14 @ flush dcache | |
144 | + nop8 | |
145 | + movc p0.c5, r0, #20 @ icache invalidate all | |
146 | + nop8 | |
147 | + | |
148 | + /* | |
149 | + * Turn off the Cache and MMU. | |
150 | + */ | |
151 | + mov r0, #0 @ disable i/d cache and MMU | |
152 | + movc p0.c1, r0, #0 | |
153 | + nop8 | |
154 | + | |
155 | + mov r0, #0 @ must be zero | |
156 | + ldw r4, =KERNEL_IMAGE_START | |
157 | + mov pc, r4 @ call kernel | |
158 | + | |
159 | + | |
160 | + .align 2 | |
161 | + .type LC0, #object | |
162 | +LC0: .word LC0 @ r1 | |
163 | + .word __bss_start @ r2 | |
164 | + .word _end @ r3 | |
165 | + .word _start @ r5 | |
166 | + .word _image_size @ r6 | |
167 | + .word _got_start @ r7 | |
168 | + .word _got_end @ r8 | |
169 | + .word decompress_stack_end @ sp | |
170 | + .size LC0, . - LC0 | |
171 | + | |
172 | +print_string: | |
173 | +#ifdef CONFIG_DEBUG_OCD | |
174 | +2001: ldb.w r1, [r0]+, #1 | |
175 | + csub.a r1, #0 | |
176 | + bne 2002f | |
177 | + mov pc, lr | |
178 | +2002: | |
179 | + movc r2, p1.c0, #0 | |
180 | + cand.a r2, #2 | |
181 | + bne 2002b | |
182 | + movc p1.c1, r1, #1 | |
183 | + csub.a r1, #'\n' | |
184 | + cmoveq r1, #'\r' | |
185 | + beq 2002b | |
186 | + b 2001b | |
187 | +#else | |
188 | + mov pc, lr | |
189 | +#endif | |
190 | + | |
191 | +__error_overwrite: | |
192 | + adr r0, str_error | |
193 | + b.l print_string | |
194 | +2001: nop8 | |
195 | + b 2001b | |
196 | +str_error: .asciz "\nError: Kernel address OVERWRITE\n" | |
197 | + .align | |
198 | + | |
199 | + .ltorg | |
200 | + | |
201 | + .align 4 | |
202 | + .section ".stack", "aw", %nobits | |
203 | +decompress_stack: .space 4096 | |
204 | +decompress_stack_end: |
arch/unicore32/boot/compressed/misc.c
1 | +/* | |
2 | + * linux/arch/unicore32/boot/compressed/misc.c | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | + | |
13 | +#include <asm/unaligned.h> | |
14 | +#include <mach/uncompress.h> | |
15 | + | |
16 | +/* | |
17 | + * gzip delarations | |
18 | + */ | |
19 | +unsigned char *output_data; | |
20 | +unsigned long output_ptr; | |
21 | + | |
22 | +unsigned int free_mem_ptr; | |
23 | +unsigned int free_mem_end_ptr; | |
24 | + | |
25 | +#define STATIC static | |
26 | +#define STATIC_RW_DATA /* non-static please */ | |
27 | + | |
28 | +/* | |
29 | + * arch-dependent implementations | |
30 | + */ | |
31 | +#ifndef ARCH_HAVE_DECOMP_ERROR | |
32 | +#define arch_decomp_error(x) | |
33 | +#endif | |
34 | + | |
35 | +#ifndef ARCH_HAVE_DECOMP_SETUP | |
36 | +#define arch_decomp_setup() | |
37 | +#endif | |
38 | + | |
39 | +#ifndef ARCH_HAVE_DECOMP_PUTS | |
40 | +#define arch_decomp_puts(p) | |
41 | +#endif | |
42 | + | |
43 | +void *memcpy(void *dest, const void *src, size_t n) | |
44 | +{ | |
45 | + int i = 0; | |
46 | + unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src; | |
47 | + | |
48 | + for (i = n >> 3; i > 0; i--) { | |
49 | + *d++ = *s++; | |
50 | + *d++ = *s++; | |
51 | + *d++ = *s++; | |
52 | + *d++ = *s++; | |
53 | + *d++ = *s++; | |
54 | + *d++ = *s++; | |
55 | + *d++ = *s++; | |
56 | + *d++ = *s++; | |
57 | + } | |
58 | + | |
59 | + if (n & 1 << 2) { | |
60 | + *d++ = *s++; | |
61 | + *d++ = *s++; | |
62 | + *d++ = *s++; | |
63 | + *d++ = *s++; | |
64 | + } | |
65 | + | |
66 | + if (n & 1 << 1) { | |
67 | + *d++ = *s++; | |
68 | + *d++ = *s++; | |
69 | + } | |
70 | + | |
71 | + if (n & 1) | |
72 | + *d++ = *s++; | |
73 | + | |
74 | + return dest; | |
75 | +} | |
76 | + | |
77 | +void error(char *x) | |
78 | +{ | |
79 | + arch_decomp_puts("\n\n"); | |
80 | + arch_decomp_puts(x); | |
81 | + arch_decomp_puts("\n\n -- System halted"); | |
82 | + | |
83 | + arch_decomp_error(x); | |
84 | + | |
85 | + for (;;) | |
86 | + ; /* Halt */ | |
87 | +} | |
88 | + | |
89 | +/* Heap size should be adjusted for different decompress method */ | |
90 | +#ifdef CONFIG_KERNEL_GZIP | |
91 | +#include "../../../../lib/decompress_inflate.c" | |
92 | +#endif | |
93 | + | |
94 | +#ifdef CONFIG_KERNEL_BZIP2 | |
95 | +#include "../../../../lib/decompress_bunzip2.c" | |
96 | +#endif | |
97 | + | |
98 | +#ifdef CONFIG_KERNEL_LZO | |
99 | +#include "../../../../lib/decompress_unlzo.c" | |
100 | +#endif | |
101 | + | |
102 | +#ifdef CONFIG_KERNEL_LZMA | |
103 | +#include "../../../../lib/decompress_unlzma.c" | |
104 | +#endif | |
105 | + | |
106 | +unsigned long decompress_kernel(unsigned long output_start, | |
107 | + unsigned long free_mem_ptr_p, | |
108 | + unsigned long free_mem_ptr_end_p) | |
109 | +{ | |
110 | + unsigned char *tmp; | |
111 | + | |
112 | + output_data = (unsigned char *)output_start; | |
113 | + free_mem_ptr = free_mem_ptr_p; | |
114 | + free_mem_end_ptr = free_mem_ptr_end_p; | |
115 | + | |
116 | + arch_decomp_setup(); | |
117 | + | |
118 | + tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); | |
119 | + output_ptr = get_unaligned_le32(tmp); | |
120 | + | |
121 | + arch_decomp_puts("Uncompressing Linux..."); | |
122 | + decompress(input_data, input_data_end - input_data, NULL, NULL, | |
123 | + output_data, NULL, error); | |
124 | + arch_decomp_puts(" done, booting the kernel.\n"); | |
125 | + return output_ptr; | |
126 | +} |
arch/unicore32/boot/compressed/piggy.S.in
arch/unicore32/boot/compressed/vmlinux.lds.in
1 | +/* | |
2 | + * linux/arch/unicore/boot/compressed/vmlinux.lds.in | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | +OUTPUT_ARCH(unicore32) | |
13 | +ENTRY(_start) | |
14 | +SECTIONS | |
15 | +{ | |
16 | + /DISCARD/ : { | |
17 | + /* | |
18 | + * Discard any r/w data - this produces a link error if we have any, | |
19 | + * which is required for PIC decompression. Local data generates | |
20 | + * GOTOFF relocations, which prevents it being relocated independently | |
21 | + * of the text/got segments. | |
22 | + */ | |
23 | + *(.data) | |
24 | + } | |
25 | + | |
26 | + . = TEXT_START; | |
27 | + _text = .; | |
28 | + | |
29 | + .text : { | |
30 | + _start = .; | |
31 | + *(.start) | |
32 | + *(.text) | |
33 | + *(.text.*) | |
34 | + *(.fixup) | |
35 | + *(.gnu.warning) | |
36 | + *(.rodata) | |
37 | + *(.rodata.*) | |
38 | + *(.piggydata) | |
39 | + . = ALIGN(4); | |
40 | + } | |
41 | + | |
42 | + _etext = .; | |
43 | + | |
44 | + /* Assume size of decompressed image is 4x the compressed image */ | |
45 | + _image_size = (_etext - _text) * 4; | |
46 | + | |
47 | + _got_start = .; | |
48 | + .got : { *(.got) } | |
49 | + _got_end = .; | |
50 | + .got.plt : { *(.got.plt) } | |
51 | + _edata = .; | |
52 | + | |
53 | + . = BSS_START; | |
54 | + __bss_start = .; | |
55 | + .bss : { *(.bss) } | |
56 | + _end = .; | |
57 | + | |
58 | + .stack : { *(.stack) } | |
59 | + .comment 0 : { *(.comment) } | |
60 | +} |
arch/unicore32/include/mach/uncompress.h
1 | +/* | |
2 | + * linux/arch/unicore32/include/mach/uncompress.h | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | + | |
13 | +#ifndef __MACH_PUV3_UNCOMPRESS_H__ | |
14 | +#define __MACH_PUV3_UNCOMPRESS_H__ | |
15 | + | |
16 | +#include "hardware.h" | |
17 | +#include "ocd.h" | |
18 | + | |
19 | +extern char input_data[]; | |
20 | +extern char input_data_end[]; | |
21 | + | |
22 | +static void arch_decomp_puts(const char *ptr) | |
23 | +{ | |
24 | + char c; | |
25 | + | |
26 | + while ((c = *ptr++) != '\0') { | |
27 | + if (c == '\n') | |
28 | + putc('\r'); | |
29 | + putc(c); | |
30 | + } | |
31 | +} | |
32 | +#define ARCH_HAVE_DECOMP_PUTS | |
33 | + | |
34 | +#endif /* __MACH_PUV3_UNCOMPRESS_H__ */ |