aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-15 21:38:21 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-15 21:52:21 -0500
commit94b212c29f685ca54b5689a8e89ac7671c43d651 (patch)
tree356266520a5ba530b2a5b77b68e90e87a2402ecb
parent7486a38f683d49e6f8b2b9050ff06778b151a40c (diff)
powerpc: Move ppc64 boot wrapper code over to arch/powerpc
This also extends the code to handle 32-bit ELF vmlinux files as well as 64-bit ones. This is sufficient for booting on new-world 32-bit powermacs (i.e. all recent machines). Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/Makefile25
-rw-r--r--arch/powerpc/boot/Makefile (renamed from arch/ppc64/boot/Makefile)5
-rw-r--r--arch/powerpc/boot/README (renamed from arch/ppc64/boot/README)0
-rw-r--r--arch/powerpc/boot/addRamDisk.c (renamed from arch/ppc64/boot/addRamDisk.c)0
-rw-r--r--arch/powerpc/boot/addnote.c (renamed from arch/ppc64/boot/addnote.c)0
-rw-r--r--arch/powerpc/boot/crt0.S (renamed from arch/ppc64/boot/crt0.S)0
-rw-r--r--arch/powerpc/boot/div64.S (renamed from arch/ppc64/boot/div64.S)0
-rw-r--r--arch/powerpc/boot/elf.h (renamed from arch/ppc64/boot/elf.h)0
-rw-r--r--arch/powerpc/boot/install.sh (renamed from arch/ppc64/boot/install.sh)0
-rw-r--r--arch/powerpc/boot/main.c (renamed from arch/ppc64/boot/main.c)122
-rw-r--r--arch/powerpc/boot/page.h (renamed from arch/ppc64/boot/page.h)0
-rw-r--r--arch/powerpc/boot/ppc_asm.h (renamed from arch/ppc64/boot/ppc_asm.h)0
-rw-r--r--arch/powerpc/boot/prom.c (renamed from arch/ppc64/boot/prom.c)0
-rw-r--r--arch/powerpc/boot/prom.h (renamed from arch/ppc64/boot/prom.h)0
-rw-r--r--arch/powerpc/boot/stdio.h (renamed from arch/ppc64/boot/stdio.h)0
-rw-r--r--arch/powerpc/boot/string.S (renamed from arch/ppc64/boot/string.S)0
-rw-r--r--arch/powerpc/boot/string.h (renamed from arch/ppc64/boot/string.h)0
-rw-r--r--arch/powerpc/boot/zImage.lds (renamed from arch/ppc64/boot/zImage.lds)0
18 files changed, 91 insertions, 61 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index d41ad2e675db..99dbea8c5c50 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -14,10 +14,6 @@
14 14
15HAS_BIARCH := $(call cc-option-yn, -m32) 15HAS_BIARCH := $(call cc-option-yn, -m32)
16 16
17ifeq ($(CONFIG_PPC64),y)
18OLDARCH := ppc64
19SZ := 64
20
21# Set default 32 bits cross compilers for vdso and boot wrapper 17# Set default 32 bits cross compilers for vdso and boot wrapper
22CROSS32_COMPILE ?= 18CROSS32_COMPILE ?=
23 19
@@ -37,6 +33,10 @@ endif
37 33
38export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY 34export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
39 35
36ifeq ($(CONFIG_PPC64),y)
37OLDARCH := ppc64
38SZ := 64
39
40new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) 40new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
41 41
42ifeq ($(new_nm),y) 42ifeq ($(new_nm),y)
@@ -139,7 +139,7 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
139 139
140drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 140drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
141 141
142defaultimage-$(CONFIG_PPC32) := uImage zImage 142defaultimage-$(CONFIG_PPC32) := zImage
143defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux 143defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
144defaultimage-$(CONFIG_PPC_PSERIES) := zImage 144defaultimage-$(CONFIG_PPC_PSERIES) := zImage
145KBUILD_IMAGE := $(defaultimage-y) 145KBUILD_IMAGE := $(defaultimage-y)
@@ -154,23 +154,13 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
154 154
155.PHONY: $(BOOT_TARGETS) 155.PHONY: $(BOOT_TARGETS)
156 156
157boot := arch/$(OLDARCH)/boot 157boot := arch/$(ARCH)/boot
158 158
159# urk
160ifeq ($(CONFIG_PPC64),y)
161$(BOOT_TARGETS): vmlinux 159$(BOOT_TARGETS): vmlinux
162 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) 160 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
163else
164$(BOOT_TARGETS): vmlinux
165 $(Q)$(MAKE) ARCH=ppc $(build)=$(boot) $@
166endif
167
168uImage: vmlinux
169 $(Q)$(MAKE) ARCH=$(OLDARCH) $(build)=$(boot)/images $(boot)/images/$@
170 161
171define archhelp 162define archhelp
172 @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)' 163 @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
173 @echo ' uImage - Create a bootable image for U-Boot / PPCBoot'
174 @echo ' install - Install kernel using' 164 @echo ' install - Install kernel using'
175 @echo ' (your) ~/bin/installkernel or' 165 @echo ' (your) ~/bin/installkernel or'
176 @echo ' (distribution) /sbin/installkernel or' 166 @echo ' (distribution) /sbin/installkernel or'
@@ -180,7 +170,6 @@ endef
180 170
181archclean: 171archclean:
182 $(Q)$(MAKE) $(clean)=$(boot) 172 $(Q)$(MAKE) $(clean)=$(boot)
183 # Temporary hack until we have migrated to asm-powerpc
184 $(Q)rm -rf arch/$(ARCH)/include 173 $(Q)rm -rf arch/$(ARCH)/include
185 174
186archprepare: checkbin 175archprepare: checkbin
diff --git a/arch/ppc64/boot/Makefile b/arch/powerpc/boot/Makefile
index 301bc1536c49..9770f587af73 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -22,7 +22,8 @@
22 22
23 23
24HOSTCC := gcc 24HOSTCC := gcc
25BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) -fPIC 25BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
26 $(shell $(CROSS32CC) -print-file-name=include) -fPIC
26BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc 27BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
27BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds 28BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds
28OBJCOPYFLAGS := contents,alloc,load,readonly,data 29OBJCOPYFLAGS := contents,alloc,load,readonly,data
@@ -98,7 +99,7 @@ quiet_cmd_ramdisk = RAMDISK $@
98 cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ 99 cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
99 100
100quiet_cmd_stripvm = STRIP $@ 101quiet_cmd_stripvm = STRIP $@
101 cmd_stripvm = $(STRIP) -s $< -o $@ 102 cmd_stripvm = $(STRIP) -s -R .comment $< -o $@
102 103
103vmlinux.strip: vmlinux 104vmlinux.strip: vmlinux
104 $(call if_changed,stripvm) 105 $(call if_changed,stripvm)
diff --git a/arch/ppc64/boot/README b/arch/powerpc/boot/README
index 3e11058760e4..3e11058760e4 100644
--- a/arch/ppc64/boot/README
+++ b/arch/powerpc/boot/README
diff --git a/arch/ppc64/boot/addRamDisk.c b/arch/powerpc/boot/addRamDisk.c
index c02a99952be7..c02a99952be7 100644
--- a/arch/ppc64/boot/addRamDisk.c
+++ b/arch/powerpc/boot/addRamDisk.c
diff --git a/arch/ppc64/boot/addnote.c b/arch/powerpc/boot/addnote.c
index 8041a9845ab7..8041a9845ab7 100644
--- a/arch/ppc64/boot/addnote.c
+++ b/arch/powerpc/boot/addnote.c
diff --git a/arch/ppc64/boot/crt0.S b/arch/powerpc/boot/crt0.S
index 9cc442263939..9cc442263939 100644
--- a/arch/ppc64/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
diff --git a/arch/ppc64/boot/div64.S b/arch/powerpc/boot/div64.S
index 722f360a32a9..722f360a32a9 100644
--- a/arch/ppc64/boot/div64.S
+++ b/arch/powerpc/boot/div64.S
diff --git a/arch/ppc64/boot/elf.h b/arch/powerpc/boot/elf.h
index d4828fcf1cb9..d4828fcf1cb9 100644
--- a/arch/ppc64/boot/elf.h
+++ b/arch/powerpc/boot/elf.h
diff --git a/arch/ppc64/boot/install.sh b/arch/powerpc/boot/install.sh
index eacce9590816..eacce9590816 100644
--- a/arch/ppc64/boot/install.sh
+++ b/arch/powerpc/boot/install.sh
diff --git a/arch/ppc64/boot/main.c b/arch/powerpc/boot/main.c
index e0dde24a72ce..64ec93116fa6 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -42,6 +42,8 @@ static struct addr_range vmlinux;
42static struct addr_range vmlinuz; 42static struct addr_range vmlinuz;
43static struct addr_range initrd; 43static struct addr_range initrd;
44 44
45static unsigned long elfoffset;
46
45static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ 47static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
46static char elfheader[256]; 48static char elfheader[256];
47 49
@@ -131,13 +133,70 @@ static unsigned long try_claim(unsigned long size)
131 return addr; 133 return addr;
132} 134}
133 135
136static int is_elf64(void *hdr)
137{
138 Elf64_Ehdr *elf64 = hdr;
139 Elf64_Phdr *elf64ph;
140 unsigned int i;
141
142 if (!(elf64->e_ident[EI_MAG0] == ELFMAG0 &&
143 elf64->e_ident[EI_MAG1] == ELFMAG1 &&
144 elf64->e_ident[EI_MAG2] == ELFMAG2 &&
145 elf64->e_ident[EI_MAG3] == ELFMAG3 &&
146 elf64->e_ident[EI_CLASS] == ELFCLASS64 &&
147 elf64->e_ident[EI_DATA] == ELFDATA2MSB &&
148 elf64->e_type == ET_EXEC &&
149 elf64->e_machine == EM_PPC64))
150 return 0;
151
152 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
153 (unsigned long)elf64->e_phoff);
154 for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
155 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
156 break;
157 if (i >= (unsigned int)elf64->e_phnum)
158 return 0;
159
160 elfoffset = (unsigned long)elf64ph->p_offset;
161 vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
162 vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
163 return 1;
164}
165
166static int is_elf32(void *hdr)
167{
168 Elf32_Ehdr *elf32 = hdr;
169 Elf32_Phdr *elf32ph;
170 unsigned int i;
171
172 if (!(elf32->e_ident[EI_MAG0] == ELFMAG0 &&
173 elf32->e_ident[EI_MAG1] == ELFMAG1 &&
174 elf32->e_ident[EI_MAG2] == ELFMAG2 &&
175 elf32->e_ident[EI_MAG3] == ELFMAG3 &&
176 elf32->e_ident[EI_CLASS] == ELFCLASS32 &&
177 elf32->e_ident[EI_DATA] == ELFDATA2MSB &&
178 elf32->e_type == ET_EXEC &&
179 elf32->e_machine == EM_PPC))
180 return 0;
181
182 elf32 = (Elf32_Ehdr *)elfheader;
183 elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
184 for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
185 if (elf32ph->p_type == PT_LOAD && elf32ph->p_offset != 0)
186 break;
187 if (i >= elf32->e_phnum)
188 return 0;
189
190 elfoffset = elf32ph->p_offset;
191 vmlinux.size = elf32ph->p_filesz + elf32ph->p_offset;
192 vmlinux.memsize = elf32ph->p_memsz + elf32ph->p_offset;
193 return 1;
194}
195
134void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) 196void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
135{ 197{
136 unsigned long i;
137 int len; 198 int len;
138 kernel_entry_t kernel_entry; 199 kernel_entry_t kernel_entry;
139 Elf64_Ehdr *elf64;
140 Elf64_Phdr *elf64ph;
141 200
142 memset(__bss_start, 0, _end - __bss_start); 201 memset(__bss_start, 0, _end - __bss_start);
143 202
@@ -153,6 +212,22 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
153 212
154 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); 213 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
155 214
215 vmlinuz.addr = (unsigned long)_vmlinux_start;
216 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
217
218 /* gunzip the ELF header of the kernel */
219 if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
220 len = vmlinuz.size;
221 gunzip(elfheader, sizeof(elfheader),
222 (unsigned char *)vmlinuz.addr, &len);
223 } else
224 memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
225
226 if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
227 printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
228 exit();
229 }
230
156 /* 231 /*
157 * The first available claim_base must be above the end of the 232 * The first available claim_base must be above the end of the
158 * the loaded kernel wrapper file (_start to _end includes the 233 * the loaded kernel wrapper file (_start to _end includes the
@@ -172,46 +247,11 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
172 claim_base = PROG_START; 247 claim_base = PROG_START;
173#endif 248#endif
174 249
175 vmlinuz.addr = (unsigned long)_vmlinux_start;
176 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
177
178 /* gunzip the ELF header of the kernel */
179 if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
180 len = vmlinuz.size;
181 gunzip(elfheader, sizeof(elfheader),
182 (unsigned char *)vmlinuz.addr, &len);
183 } else
184 memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
185
186 elf64 = (Elf64_Ehdr *)elfheader;
187 if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
188 elf64->e_ident[EI_MAG1] != ELFMAG1 ||
189 elf64->e_ident[EI_MAG2] != ELFMAG2 ||
190 elf64->e_ident[EI_MAG3] != ELFMAG3 ||
191 elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
192 elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
193 elf64->e_type != ET_EXEC ||
194 elf64->e_machine != EM_PPC64 )
195 {
196 printf("Error: not a valid PPC64 ELF file!\n\r");
197 exit();
198 }
199
200 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
201 (unsigned long)elf64->e_phoff);
202 for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
203 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
204 break;
205 }
206 vmlinux.size = (unsigned long)elf64ph->p_filesz +
207 (unsigned long)elf64ph->p_offset;
208 /* We need to claim the memsize plus the file offset since gzip 250 /* We need to claim the memsize plus the file offset since gzip
209 * will expand the header (file offset), then the kernel, then 251 * will expand the header (file offset), then the kernel, then
210 * possible rubbish we don't care about. But the kernel bss must 252 * possible rubbish we don't care about. But the kernel bss must
211 * be claimed (it will be zero'd by the kernel itself) 253 * be claimed (it will be zero'd by the kernel itself)
212 */ 254 */
213 vmlinux.memsize = (unsigned long)elf64ph->p_memsz +
214 (unsigned long)elf64ph->p_offset;
215 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); 255 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
216 vmlinux.addr = try_claim(vmlinux.memsize); 256 vmlinux.addr = try_claim(vmlinux.memsize);
217 if (vmlinux.addr == 0) { 257 if (vmlinux.addr == 0) {
@@ -254,9 +294,9 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
254 /* Skip over the ELF header */ 294 /* Skip over the ELF header */
255#ifdef DEBUG 295#ifdef DEBUG
256 printf("... skipping 0x%lx bytes of ELF header\n\r", 296 printf("... skipping 0x%lx bytes of ELF header\n\r",
257 (unsigned long)elf64ph->p_offset); 297 elfoffset);
258#endif 298#endif
259 vmlinux.addr += (unsigned long)elf64ph->p_offset; 299 vmlinux.addr += elfoffset;
260 300
261 flush_cache((void *)vmlinux.addr, vmlinux.size); 301 flush_cache((void *)vmlinux.addr, vmlinux.size);
262 302
@@ -272,7 +312,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
272 (unsigned long)prom, NULL); 312 (unsigned long)prom, NULL);
273#endif 313#endif
274 314
275 kernel_entry( a1, a2, prom, NULL ); 315 kernel_entry(a1, a2, prom, NULL);
276 316
277 printf("Error: Linux kernel returned to zImage bootloader!\n\r"); 317 printf("Error: Linux kernel returned to zImage bootloader!\n\r");
278 318
diff --git a/arch/ppc64/boot/page.h b/arch/powerpc/boot/page.h
index 14eca30fef64..14eca30fef64 100644
--- a/arch/ppc64/boot/page.h
+++ b/arch/powerpc/boot/page.h
diff --git a/arch/ppc64/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h
index 1c2c2817f9b7..1c2c2817f9b7 100644
--- a/arch/ppc64/boot/ppc_asm.h
+++ b/arch/powerpc/boot/ppc_asm.h
diff --git a/arch/ppc64/boot/prom.c b/arch/powerpc/boot/prom.c
index 4bea2f4dcb06..4bea2f4dcb06 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/powerpc/boot/prom.c
diff --git a/arch/ppc64/boot/prom.h b/arch/powerpc/boot/prom.h
index 96ab5aec740c..96ab5aec740c 100644
--- a/arch/ppc64/boot/prom.h
+++ b/arch/powerpc/boot/prom.h
diff --git a/arch/ppc64/boot/stdio.h b/arch/powerpc/boot/stdio.h
index 24bd3a8dee94..24bd3a8dee94 100644
--- a/arch/ppc64/boot/stdio.h
+++ b/arch/powerpc/boot/stdio.h
diff --git a/arch/ppc64/boot/string.S b/arch/powerpc/boot/string.S
index b1eeaed7db17..b1eeaed7db17 100644
--- a/arch/ppc64/boot/string.S
+++ b/arch/powerpc/boot/string.S
diff --git a/arch/ppc64/boot/string.h b/arch/powerpc/boot/string.h
index 9fdff1cc0d70..9fdff1cc0d70 100644
--- a/arch/ppc64/boot/string.h
+++ b/arch/powerpc/boot/string.h
diff --git a/arch/ppc64/boot/zImage.lds b/arch/powerpc/boot/zImage.lds
index 4b6bb3ffe3dc..4b6bb3ffe3dc 100644
--- a/arch/ppc64/boot/zImage.lds
+++ b/arch/powerpc/boot/zImage.lds