Commit 147c05168fc86e824ccd1c0a02b40843e3cbca88
Committed by
Benjamin Herrenschmidt
1 parent
2d9afb369b
powerpc/boot: Add support for 64bit little endian wrapper
The code is only slightly modified : entry points now use the FIXUP_ENDIAN trampoline to switch endian order. The 32bit wrapper is kept for big endian kernels and 64bit is enforced for little endian kernels with a PPC64_BOOT_WRAPPER config option. The linker script is generated using the kernel preprocessor flags to make use of the CONFIG_* definitions and the wrapper script is modified to take into account the new elf64ppc format. Finally, the zImage file is compiled as a position independent executable (-pie) which makes it loadable at any address by the firmware. Signed-off-by: Cédric Le Goater <clg@fr.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Showing 7 changed files with 72 additions and 5 deletions Side-by-side Diff
arch/powerpc/boot/Makefile
... | ... | @@ -22,8 +22,14 @@ |
22 | 22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
23 | 23 | -fno-strict-aliasing -Os -msoft-float -pipe \ |
24 | 24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ |
25 | - -isystem $(shell $(CROSS32CC) -print-file-name=include) \ | |
26 | - -mbig-endian | |
25 | + -isystem $(shell $(CROSS32CC) -print-file-name=include) | |
26 | +ifdef CONFIG_PPC64_BOOT_WRAPPER | |
27 | +BOOTCFLAGS += -m64 | |
28 | +endif | |
29 | +ifdef CONFIG_CPU_BIG_ENDIAN | |
30 | +BOOTCFLAGS += -mbig-endian | |
31 | +endif | |
32 | + | |
27 | 33 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
28 | 34 | |
29 | 35 | ifdef CONFIG_DEBUG_INFO |
... | ... | @@ -142,7 +148,11 @@ |
142 | 148 | $(obj)/empty.c: |
143 | 149 | @touch $@ |
144 | 150 | |
145 | -$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S | |
151 | +$(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S | |
152 | + $(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \ | |
153 | + -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | |
154 | + | |
155 | +$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S | |
146 | 156 | @cp $< $@ |
147 | 157 | |
148 | 158 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ |
arch/powerpc/boot/crt0.S
arch/powerpc/boot/ppc_asm.h
... | ... | @@ -62,5 +62,17 @@ |
62 | 62 | #define SPRN_TBRL 268 |
63 | 63 | #define SPRN_TBRU 269 |
64 | 64 | |
65 | +#define FIXUP_ENDIAN \ | |
66 | + tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ | |
67 | + b $+36; /* Skip trampoline if endian is good */ \ | |
68 | + .long 0x05009f42; /* bcl 20,31,$+4 */ \ | |
69 | + .long 0xa602487d; /* mflr r10 */ \ | |
70 | + .long 0x1c004a39; /* addi r10,r10,28 */ \ | |
71 | + .long 0xa600607d; /* mfmsr r11 */ \ | |
72 | + .long 0x01006b69; /* xori r11,r11,1 */ \ | |
73 | + .long 0xa6035a7d; /* mtsrr0 r10 */ \ | |
74 | + .long 0xa6037b7d; /* mtsrr1 r11 */ \ | |
75 | + .long 0x2400004c /* rfid */ | |
76 | + | |
65 | 77 | #endif /* _PPC64_PPC_ASM_H */ |
arch/powerpc/boot/pseries-head.S
arch/powerpc/boot/wrapper
... | ... | @@ -40,6 +40,7 @@ |
40 | 40 | binary= |
41 | 41 | gzip=.gz |
42 | 42 | pie= |
43 | +format= | |
43 | 44 | |
44 | 45 | # cross-compilation prefix |
45 | 46 | CROSS= |
... | ... | @@ -136,6 +137,14 @@ |
136 | 137 | kernel=vmlinux |
137 | 138 | fi |
138 | 139 | |
140 | +elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" | |
141 | +case "$elfformat" in | |
142 | + elf64-powerpcle) format=elf64lppc ;; | |
143 | + elf64-powerpc) format=elf32ppc ;; | |
144 | + elf32-powerpc) format=elf32ppc ;; | |
145 | +esac | |
146 | + | |
147 | + | |
139 | 148 | platformo=$object/"$platform".o |
140 | 149 | lds=$object/zImage.lds |
141 | 150 | ext=strip |
... | ... | @@ -154,6 +163,10 @@ |
154 | 163 | pseries) |
155 | 164 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" |
156 | 165 | link_address='0x4000000' |
166 | + if [ "$format" != "elf32ppc" ]; then | |
167 | + link_address= | |
168 | + pie=-pie | |
169 | + fi | |
157 | 170 | make_space=n |
158 | 171 | ;; |
159 | 172 | maple) |
... | ... | @@ -379,7 +392,7 @@ |
379 | 392 | if [ -n "$link_address" ] ; then |
380 | 393 | text_start="-Ttext $link_address" |
381 | 394 | fi |
382 | - ${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \ | |
395 | + ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ | |
383 | 396 | $platformo $tmp $object/wrapper.a |
384 | 397 | rm $tmp |
385 | 398 | fi |
arch/powerpc/boot/zImage.lds.S
1 | +#include <asm-generic/vmlinux.lds.h> | |
2 | + | |
3 | +#ifdef CONFIG_PPC64_BOOT_WRAPPER | |
4 | +OUTPUT_ARCH(powerpc:common64) | |
5 | +#else | |
1 | 6 | OUTPUT_ARCH(powerpc:common) |
7 | +#endif | |
2 | 8 | ENTRY(_zimage_start) |
3 | 9 | EXTERN(_zimage_start) |
4 | 10 | SECTIONS |
5 | 11 | |
... | ... | @@ -16,7 +22,9 @@ |
16 | 22 | *(.rodata*) |
17 | 23 | *(.data*) |
18 | 24 | *(.sdata*) |
25 | +#ifndef CONFIG_PPC64_BOOT_WRAPPER | |
19 | 26 | *(.got2) |
27 | +#endif | |
20 | 28 | } |
21 | 29 | .dynsym : { *(.dynsym) } |
22 | 30 | .dynstr : { *(.dynstr) } |
... | ... | @@ -27,7 +35,13 @@ |
27 | 35 | } |
28 | 36 | .hash : { *(.hash) } |
29 | 37 | .interp : { *(.interp) } |
30 | - .rela.dyn : { *(.rela*) } | |
38 | + .rela.dyn : | |
39 | + { | |
40 | +#ifdef CONFIG_PPC64_BOOT_WRAPPER | |
41 | + __rela_dyn_start = .; | |
42 | +#endif | |
43 | + *(.rela*) | |
44 | + } | |
31 | 45 | |
32 | 46 | . = ALIGN(8); |
33 | 47 | .kernel:dtb : |
... | ... | @@ -52,6 +66,15 @@ |
52 | 66 | *(.kernel:initrd) |
53 | 67 | _initrd_end = .; |
54 | 68 | } |
69 | + | |
70 | +#ifdef CONFIG_PPC64_BOOT_WRAPPER | |
71 | + .got : | |
72 | + { | |
73 | + __toc_start = .; | |
74 | + *(.got) | |
75 | + *(.toc) | |
76 | + } | |
77 | +#endif | |
55 | 78 | |
56 | 79 | . = ALIGN(4096); |
57 | 80 | .bss : |
arch/powerpc/platforms/Kconfig.cputype
... | ... | @@ -422,6 +422,7 @@ |
422 | 422 | |
423 | 423 | config CPU_LITTLE_ENDIAN |
424 | 424 | bool "Build little endian kernel" |
425 | + select PPC64_BOOT_WRAPPER | |
425 | 426 | help |
426 | 427 | Build a little endian kernel. |
427 | 428 | |
... | ... | @@ -430,4 +431,8 @@ |
430 | 431 | little endian powerpc. |
431 | 432 | |
432 | 433 | endchoice |
434 | + | |
435 | +config PPC64_BOOT_WRAPPER | |
436 | + def_bool n | |
437 | + depends on CPU_LITTLE_ENDIAN |
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit b46f51
-
mentioned in commit 655471
-
mentioned in commit 655471
-
mentioned in commit 655471
-
mentioned in commit 655471
-
mentioned in commit 655471