diff options
author | David 'Digit' Turner <digit@google.com> | 2015-02-04 19:42:17 +0100 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2015-02-04 19:42:17 +0100 |
commit | 43e00a06976b969b04084a8ba406233c425ac23a (patch) | |
tree | 770a767590888b20178b4adff19758b1497c401f /build-kernel.sh | |
parent | 1dffc580d656397f0ffca65820aac524a7ba6f77 (diff) | |
download | qemu-kernel-43e00a06976b969b04084a8ba406233c425ac23a.tar.gz |
Add build-kernel.sh script
This patch moves the kernel rebuild script from external/qemu/distrib/
to prebuilts/qemu-kernel/, for two reasons:
- It's logical, captain!
- external/qemu was removed from aosp/master and downstream branches
while aosp/studio-1.2-dev doesn't provide all target toolchain
binaries required to build the kernel.
In other words, the instructions to rebuild emulator kernel images
are now to use
$AOSP/prebuilts/qemu-kernel/build-kernel.sh [options]
Where $AOSP points to a checkout of aosp/master.
Change-Id: I224618db8cc03cedcaabaee3fd5832dfdd5adb4a
Diffstat (limited to 'build-kernel.sh')
-rwxr-xr-x | build-kernel.sh | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/build-kernel.sh b/build-kernel.sh new file mode 100755 index 0000000..bb83eeb --- /dev/null +++ b/build-kernel.sh @@ -0,0 +1,425 @@ +#!/bin/sh +# +# A small script used to rebuild the Android goldfish kernel image +# See docs/KERNEL.TXT for usage instructions. +# + +export LANG=C +export LC_ALL=C + +PROGNAME=$(basename "$0") + +MACHINE=goldfish +VARIANT=goldfish +OUTPUT=/tmp/kernel-qemu +CROSSPREFIX=arm-linux-androideabi- +CONFIG=goldfish +GCC_VERSION=4.8 + +VALID_ARCHS="arm x86 x86_64 mips arm64 mips64" + +# Determine the host architecture, and which default prebuilt tag we need. +# For the toolchain auto-detection. +# +HOST_OS=`uname -s` +case "$HOST_OS" in + Darwin) + HOST_OS=darwin + HOST_TAG=darwin-x86 + BUILD_NUM_CPUS=$(sysctl -n hw.ncpu) + ;; + Linux) + # note that building 32-bit binaries on x86_64 is handled later + HOST_OS=linux + HOST_TAG=linux-x86 + BUILD_NUM_CPUS=$(grep -c processor /proc/cpuinfo) + ;; + *) + echo "ERROR: Unsupported OS: $HOST_OS" + exit 1 +esac + +# Default number of parallel jobs during the build: cores * 2 +JOBS=$(( $BUILD_NUM_CPUS * 2 )) + +ARCH=arm + +OPTION_HELP=no +OPTION_ARMV7=yes +OPTION_OUT= +OPTION_CROSS= +OPTION_ARCH= +OPTION_CONFIG= +OPTION_SAVEDEFCONFIG=no +OPTION_JOBS= +OPTION_VERBOSE= +OPTION_GCC_VERSION= +CCACHE= + +case "$USE_CCACHE" in + "") + CCACHE= + ;; + *) + # use ccache bundled in AOSP source tree + CCACHE=${ANDROID_BUILD_TOP:-$(dirname $0)/../..}/prebuilts/misc/$HOST_TAG/ccache/ccache + [ -x $CCACHE ] || CCACHE= + ;; +esac + +for opt do + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') + case $opt in + --help|-h|-\?) OPTION_HELP=yes + ;; + --arch=*) + OPTION_ARCH=$optarg + ;; + --armv5) + OPTION_ARMV7=no + ;; + --armv7) + OPTION_ARMV7=yes + ;; + --ccache=*) + CCACHE=$optarg + ;; + --config=*) + OPTION_CONFIG=$optarg + ;; + --cross=*) + OPTION_CROSS=$optarg + ;; + --gcc-version=*) + OPTION_GCC_VERSION=$optarg + ;; + -j*|--jobs=*) + OPTION_JOBS=$optarg + ;; + --out=*) + OPTION_OUT=$optarg + ;; + --savedefconfig) + OPTION_SAVEDEFCONFIG=yes + ;; + --verbose) + OPTION_VERBOSE=true + ;; + *) + echo "unknown option '$opt', use --help" + exit 1 + esac +done + +if [ $OPTION_HELP = "yes" ] ; then + echo "Rebuild the prebuilt kernel binary for Android's emulator." + echo "" + echo "options (defaults are within brackets):" + echo "" + echo " --help print this message" + echo " --arch=<arch> change target architecture [$ARCH]" + echo " --armv5 build ARMv5 binaries" + echo " --armv7 build ARMv7 binaries (default. see note below)" + echo " --out=<directory> output directory [$OUTPUT]" + echo " --cross=<prefix> cross-toolchain prefix [$CROSSPREFIX]" + echo " --config=<name> kernel config name [$CONFIG]" + echo " --savedefconfig run savedefconfig" + echo " --ccache=<path> use compiler cache [${CCACHE:-not set}]" + echo " --gcc-version=<version> use specific GCC version [$GCC_VERSION]" + echo " --verbose show build commands" + echo " -j<number> launch <number> parallel build jobs [$JOBS]" + echo "" + echo "NOTE: --armv7 is equivalent to --config=goldfish_armv7. It is" + echo " ignored if --config=<name> is used." + echo "" + exit 0 +fi + +if [ ! -f include/linux/vermagic.h ]; then + echo "ERROR: You must be in the top-level kernel source directory to run this script." + exit 1 +fi + +# Extract kernel version, we'll need to put this in the final binaries names +# to ensure the emulator can trivially know it without probing the binary with +# 'file' or other unreliable heuristics. +KERNEL_MAJOR=$(awk '$1 == "VERSION" { print $3; }' Makefile) +KERNEL_MINOR=$(awk '$1 == "PATCHLEVEL" { print $3; }' Makefile) +KERNEL_PATCH=$(awk '$1 == "SUBLEVEL" { print $3; }' Makefile) +KERNEL_VERSION="$KERNEL_MAJOR.$KERNEL_MINOR.$KERNEL_PATCH" +echo "Found kernel version: $KERNEL_VERSION" + +if [ -n "$OPTION_ARCH" ]; then + ARCH=$OPTION_ARCH +fi + +if [ -n "$OPTION_GCC_VERSION" ]; then + GCC_VERSION=$OPTION_GCC_VERSION +else + if [ "$ARCH" = "x86" ]; then + # Work-around a nasty bug. + # Hence 132637 is 2.6.29. + if [ "$KERNEL_VERSION" = "2.6.29" ]; then + GCC_VERSION=4.6 + echo "WARNING: android-goldfish-$KERNEL_VERSION doesn't build --arch=$ARCH with GCC 4.7" + fi + fi + if [ "$ARCH" = "arm64" ]; then + # There is no GCC 4.7 toolchain to build AARCH64 binaries. + GCC_VERSION=4.8 + fi + echo "Autoconfig: --gcc-version=$GCC_VERSION" +fi + +if [ -n "$OPTION_CONFIG" ]; then + CONFIG=$OPTION_CONFIG +else + case $ARCH in + arm) + CONFIG=goldfish_armv7 + if [ "$OPTION_ARMV7" = "no" ]; then + CONFIG=goldfish + fi + ;; + x86) + # Warning: this is ambiguous, should be 'goldfish' before 3.10, + # and 'i386_emu" after it. + if [ -f "arch/x86/configs/i386_emu_defconfig" ]; then + CONFIG=i386_emu + else + CONFIG=goldfish + fi + ;; + x86_64) + CONFIG=x86_64_emu + ;; + mips) + CONFIG=goldfish + ;; + mips64) + CONFIG=ranchu64 + ;; + arm64) + CONFIG=ranchu + ;; + *) + echo "ERROR: Invalid arch '$ARCH', try one of $VALID_ARCHS" + exit 1 + esac + echo "Auto-config: --config=$CONFIG" +fi + +# Check output directory. +if [ -n "$OPTION_OUT" ] ; then + if [ ! -d "$OPTION_OUT" ] ; then + echo "Output directory '$OPTION_OUT' does not exist ! Aborting." + exit 1 + fi + OUTPUT=$OPTION_OUT +else + OUTPUT=$OUTPUT/${ARCH}-${KERNEL_VERSION} + case $CONFIG in + vbox*) + OUTPUT=${OUTPUT}-vbox + ;; + goldfish) + if [ "$ARCH" = "arm" ]; then + OUTPUT=${OUTPUT}-armv5 + fi + ;; + esac + echo "Auto-config: --out=$OUTPUT" + mkdir -p $OUTPUT +fi + +if [ -n "$OPTION_CROSS" ] ; then + CROSSPREFIX="$OPTION_CROSS" +else + case $ARCH in + arm) + CROSSPREFIX=arm-linux-androideabi- + ;; + x86) + CROSSPREFIX=x86_64-linux-android- + # NOTE: kernel-toolchain/toolbox.sh will add -m32 + ;; + x86_64) + CROSSPREFIX=x86_64-linux-android- + ;; + mips) + CROSSPREFIX=mipsel-linux-android- + ;; + mips64) + CROSSPREFIX=mips64el-linux-android- + ;; + arm64) + CROSSPREFIX=aarch64-linux-android- + ;; + *) + echo "ERROR: Unsupported architecture!" + exit 1 + ;; + esac + CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION + echo "Auto-config: --cross=$CROSSPREFIX" +fi + +ZIMAGE=zImage + +case $ARCH in + x86|x86_64) + ZIMAGE=bzImage + ;; + arm64) + ZIMAGE=Image + ;; + mips) + ZIMAGE= + ;; + mips64) + ZIMAGE= + ;; +esac + +# If the cross-compiler is not in the path, try to find it automatically +CROSS_COMPILER="${CROSSPREFIX}gcc" +CROSS_COMPILER_VERSION=$($CROSS_COMPILER --version 2>/dev/null) +if [ $? != 0 ] ; then + BUILD_TOP=$ANDROID_BUILD_TOP + if [ -z "$BUILD_TOP" ]; then + # Assume this script is under external/qemu/distrib/ in the + # Android source tree. + BUILD_TOP=$(dirname $0)/../.. + if [ ! -d "$BUILD_TOP/prebuilts" ]; then + BUILD_TOP= + else + BUILD_TOP=$(cd $BUILD_TOP && pwd) + fi + fi + case $ARCH in + x86_64) + # x86_46 binaries are under prebuilts/gcc/<host>/x86 !! + PREBUILT_ARCH=x86 + ;; + arm64) + PREBUILT_ARCH=aarch64 + ;; + *) + PREBUILT_ARCH=$ARCH + ;; + esac + CROSSPREFIX=$BUILD_TOP/prebuilts/gcc/$HOST_TAG/$PREBUILT_ARCH/$CROSSTOOLCHAIN/bin/$CROSSPREFIX + echo "Checking for ${CROSSPREFIX}gcc" + if [ "$BUILD_TOP" -a -f ${CROSSPREFIX}gcc ]; then + echo "Auto-config: --cross=$CROSSPREFIX" + else + echo "It looks like $CROSS_COMPILER is not in your path ! Aborting." + exit 1 + fi +fi + +if [ "$CCACHE" ] ; then + echo "Using ccache program: $CCACHE" + CROSSPREFIX="$CCACHE $CROSSPREFIX" +fi + +export CROSS_COMPILE="$CROSSPREFIX" ARCH SUBARCH=$ARCH + +if [ "$OPTION_JOBS" ]; then + JOBS=$OPTION_JOBS +else + echo "Auto-config: -j$JOBS" +fi + + +# Special magic redirection with our magic toolbox script +# This is needed to add extra compiler flags to compiler. +# See kernel-toolchain/android-kernel-toolchain-* for details +# +export REAL_CROSS_COMPILE="$CROSS_COMPILE" +CROSS_COMPILE=$(dirname "$0")/kernel-toolchain/android-kernel-toolchain- + +MAKE_FLAGS= +if [ "$OPTION_VERBOSE" ]; then + MAKE_FLAGS="$MAKE_FLAGS V=1" +fi + +case $CONFIG in + defconfig) + MAKE_DEFCONFIG=$CONFIG + ;; + *) + MAKE_DEFCONFIG=${CONFIG}_defconfig + ;; +esac + +case $ARCH in + mips64) + # MIPS64 Kernel code base is under arch/mips + ARCH=mips + ;; +esac + +# Do the build +# +rm -f include/asm && +make $MAKE_DEFCONFIG && # configure the kernel +make -j$JOBS $MAKE_FLAGS # build it + +if [ $? != 0 ] ; then + echo "Could not build the kernel. Aborting !" + exit 1 +fi + +if [ "$OPTION_SAVEDEFCONFIG" = "yes" ]; then + case $ARCH in + x86_64) + DEFCONFIG_ARCH=x86 + ;; + *) + DEFCONFIG_ARCH=$ARCH + ;; + esac + make savedefconfig + mv -f defconfig arch/$DEFCONFIG_ARCH/configs/${CONFIG}_defconfig +fi + +# Note: The exact names of the output files are important for the Android build, +# do not change the definitions lightly. +KERNEL_PREFIX=kernel-$KERNEL_VERSION + +# Naming conventions for the kernel image files: +# +# 1) The kernel image is called kernel-qemu, except for 32-bit ARM +# where it must be called kernel-qemu-armv7 +# +# 2) The debug symbol file is called vmlinux-qemu, except for 32-bit +# ARM where it must be called vmlinux-qemu-armv7 +# +OUTPUT_KERNEL=kernel-qemu +OUTPUT_VMLINUX=vmlinux-qemu +if [ "$CONFIG" = "goldfish_armv7" ]; then + OUTPUT_KERNEL=${OUTPUT_KERNEL}-armv7 + OUTPUT_VMLINUX=${OUTPUT_VMLINUX}-armv7 +fi + +cp -f vmlinux $OUTPUT/$OUTPUT_VMLINUX +if [ ! -z $ZIMAGE ]; then + cp -f arch/$ARCH/boot/$ZIMAGE $OUTPUT/$OUTPUT_KERNEL +else + cp -f vmlinux $OUTPUT/$OUTPUT_KERNEL +fi +echo "Kernel $CONFIG prebuilt images ($OUTPUT_KERNEL and $OUTPUT_VMLINUX) copied to $OUTPUT successfully !" + +cp COPYING $OUTPUT/LINUX_KERNEL_COPYING + +cat > $OUTPUT/README <<EOF +This directory contains kernel images to be used with the Android emulator +program, for the $ARCH CPU architecture. It was built with the $PROGNAME +script. For more details, read: + + \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT + +EOF + +exit 0 |