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>
This commit is contained in:
Cédric Le Goater 2014-04-24 09:23:39 +02:00 коммит произвёл Benjamin Herrenschmidt
Родитель 2d9afb369b
Коммит 147c05168f
7 изменённых файлов: 72 добавлений и 5 удалений

Просмотреть файл

@ -22,8 +22,14 @@ all: $(obj)/zImage
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -Os -msoft-float -pipe \ -fno-strict-aliasing -Os -msoft-float -pipe \
-fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
-isystem $(shell $(CROSS32CC) -print-file-name=include) \ -isystem $(shell $(CROSS32CC) -print-file-name=include)
-mbig-endian ifdef CONFIG_PPC64_BOOT_WRAPPER
BOOTCFLAGS += -m64
endif
ifdef CONFIG_CPU_BIG_ENDIAN
BOOTCFLAGS += -mbig-endian
endif
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
ifdef CONFIG_DEBUG_INFO ifdef CONFIG_DEBUG_INFO
@ -142,7 +148,11 @@ $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc
$(obj)/empty.c: $(obj)/empty.c:
@touch $@ @touch $@
$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S $(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S
$(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
$(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
@cp $< $@ @cp $< $@
clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \

Просмотреть файл

@ -275,6 +275,7 @@ prom:
rfid rfid
1: /* Return from OF */ 1: /* Return from OF */
FIXUP_ENDIAN
/* Restore registers and return. */ /* Restore registers and return. */
rldicl r1,r1,0,32 rldicl r1,r1,0,32

Просмотреть файл

@ -62,4 +62,16 @@
#define SPRN_TBRL 268 #define SPRN_TBRL 268
#define SPRN_TBRU 269 #define SPRN_TBRU 269
#define FIXUP_ENDIAN \
tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \
b $+36; /* Skip trampoline if endian is good */ \
.long 0x05009f42; /* bcl 20,31,$+4 */ \
.long 0xa602487d; /* mflr r10 */ \
.long 0x1c004a39; /* addi r10,r10,28 */ \
.long 0xa600607d; /* mfmsr r11 */ \
.long 0x01006b69; /* xori r11,r11,1 */ \
.long 0xa6035a7d; /* mtsrr0 r10 */ \
.long 0xa6037b7d; /* mtsrr1 r11 */ \
.long 0x2400004c /* rfid */
#endif /* _PPC64_PPC_ASM_H */ #endif /* _PPC64_PPC_ASM_H */

Просмотреть файл

@ -1,5 +1,8 @@
#include "ppc_asm.h"
.text .text
.globl _zimage_start .globl _zimage_start
_zimage_start: _zimage_start:
FIXUP_ENDIAN
b _zimage_start_lib b _zimage_start_lib

Просмотреть файл

@ -40,6 +40,7 @@ cacheit=
binary= binary=
gzip=.gz gzip=.gz
pie= pie=
format=
# cross-compilation prefix # cross-compilation prefix
CROSS= CROSS=
@ -136,6 +137,14 @@ if [ -z "$kernel" ]; then
kernel=vmlinux kernel=vmlinux
fi fi
elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`"
case "$elfformat" in
elf64-powerpcle) format=elf64lppc ;;
elf64-powerpc) format=elf32ppc ;;
elf32-powerpc) format=elf32ppc ;;
esac
platformo=$object/"$platform".o platformo=$object/"$platform".o
lds=$object/zImage.lds lds=$object/zImage.lds
ext=strip ext=strip
@ -154,6 +163,10 @@ of)
pseries) pseries)
platformo="$object/pseries-head.o $object/of.o $object/epapr.o" platformo="$object/pseries-head.o $object/of.o $object/epapr.o"
link_address='0x4000000' link_address='0x4000000'
if [ "$format" != "elf32ppc" ]; then
link_address=
pie=-pie
fi
make_space=n make_space=n
;; ;;
maple) maple)
@ -379,7 +392,7 @@ if [ "$platform" != "miboot" ]; then
if [ -n "$link_address" ] ; then if [ -n "$link_address" ] ; then
text_start="-Ttext $link_address" text_start="-Ttext $link_address"
fi fi
${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \ ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \
$platformo $tmp $object/wrapper.a $platformo $tmp $object/wrapper.a
rm $tmp rm $tmp
fi fi

Просмотреть файл

@ -1,4 +1,10 @@
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_PPC64_BOOT_WRAPPER
OUTPUT_ARCH(powerpc:common64)
#else
OUTPUT_ARCH(powerpc:common) OUTPUT_ARCH(powerpc:common)
#endif
ENTRY(_zimage_start) ENTRY(_zimage_start)
EXTERN(_zimage_start) EXTERN(_zimage_start)
SECTIONS SECTIONS
@ -16,7 +22,9 @@ SECTIONS
*(.rodata*) *(.rodata*)
*(.data*) *(.data*)
*(.sdata*) *(.sdata*)
#ifndef CONFIG_PPC64_BOOT_WRAPPER
*(.got2) *(.got2)
#endif
} }
.dynsym : { *(.dynsym) } .dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) } .dynstr : { *(.dynstr) }
@ -27,7 +35,13 @@ SECTIONS
} }
.hash : { *(.hash) } .hash : { *(.hash) }
.interp : { *(.interp) } .interp : { *(.interp) }
.rela.dyn : { *(.rela*) } .rela.dyn :
{
#ifdef CONFIG_PPC64_BOOT_WRAPPER
__rela_dyn_start = .;
#endif
*(.rela*)
}
. = ALIGN(8); . = ALIGN(8);
.kernel:dtb : .kernel:dtb :
@ -53,6 +67,15 @@ SECTIONS
_initrd_end = .; _initrd_end = .;
} }
#ifdef CONFIG_PPC64_BOOT_WRAPPER
.got :
{
__toc_start = .;
*(.got)
*(.toc)
}
#endif
. = ALIGN(4096); . = ALIGN(4096);
.bss : .bss :
{ {

Просмотреть файл

@ -422,6 +422,7 @@ config CPU_BIG_ENDIAN
config CPU_LITTLE_ENDIAN config CPU_LITTLE_ENDIAN
bool "Build little endian kernel" bool "Build little endian kernel"
select PPC64_BOOT_WRAPPER
help help
Build a little endian kernel. Build a little endian kernel.
@ -430,3 +431,7 @@ config CPU_LITTLE_ENDIAN
little endian powerpc. little endian powerpc.
endchoice endchoice
config PPC64_BOOT_WRAPPER
def_bool n
depends on CPU_LITTLE_ENDIAN