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:
Родитель
2d9afb369b
Коммит
147c05168f
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче