You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
437 lines
11 KiB
437 lines
11 KiB
4 months ago
|
#!/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.9
|
||
|
|
||
|
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
|
||
|
if [ "$ARCH" = "mips64" ]; then
|
||
|
GCC_VERSION=4.9
|
||
|
fi
|
||
|
if [ "$ARCH" = "mips" ]; then
|
||
|
GCC_VERSION=4.9
|
||
|
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"
|
||
|
CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
|
||
|
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=mips64el-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
|
||
|
;;
|
||
|
mips64)
|
||
|
PREBUILT_ARCH=mips
|
||
|
;;
|
||
|
*)
|
||
|
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
|
||
|
|
||
|
ORG_ARCH=$ARCH
|
||
|
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 $ORG_ARCH CPU architecture. It was built with the $PROGNAME
|
||
|
script. For more details, read:
|
||
|
|
||
|
\$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT
|
||
|
|
||
|
EOF
|
||
|
|
||
|
exit 0
|