Home | History | Annotate | Download | only in qemu-kernel
      1 #!/bin/sh
      2 #
      3 # A small script used to rebuild the Android goldfish kernel image
      4 # See docs/KERNEL.TXT for usage instructions.
      5 #
      6 
      7 export LANG=C
      8 export LC_ALL=C
      9 
     10 PROGNAME=$(basename "$0")
     11 
     12 MACHINE=goldfish
     13 VARIANT=goldfish
     14 OUTPUT=/tmp/kernel-qemu
     15 CROSSPREFIX=arm-linux-androideabi-
     16 CONFIG=goldfish
     17 GCC_VERSION=4.9
     18 
     19 VALID_ARCHS="arm x86 x86_64 mips arm64 mips64"
     20 
     21 # Determine the host architecture, and which default prebuilt tag we need.
     22 # For the toolchain auto-detection.
     23 #
     24 HOST_OS=`uname -s`
     25 case "$HOST_OS" in
     26     Darwin)
     27         HOST_OS=darwin
     28         HOST_TAG=darwin-x86
     29         BUILD_NUM_CPUS=$(sysctl -n hw.ncpu)
     30         ;;
     31     Linux)
     32         # note that building  32-bit binaries on x86_64 is handled later
     33         HOST_OS=linux
     34         HOST_TAG=linux-x86
     35         BUILD_NUM_CPUS=$(grep -c processor /proc/cpuinfo)
     36         ;;
     37     *)
     38         echo "ERROR: Unsupported OS: $HOST_OS"
     39         exit 1
     40 esac
     41 
     42 # Default number of parallel jobs during the build: cores * 2
     43 JOBS=$(( $BUILD_NUM_CPUS * 2 ))
     44 
     45 ARCH=arm
     46 
     47 OPTION_HELP=no
     48 OPTION_ARMV7=yes
     49 OPTION_OUT=
     50 OPTION_CROSS=
     51 OPTION_ARCH=
     52 OPTION_CONFIG=
     53 OPTION_SAVEDEFCONFIG=no
     54 OPTION_JOBS=
     55 OPTION_VERBOSE=
     56 OPTION_GCC_VERSION=
     57 CCACHE=
     58 
     59 case "$USE_CCACHE" in
     60     "")
     61         CCACHE=
     62         ;;
     63     *)
     64         # use ccache bundled in AOSP source tree
     65         CCACHE=${ANDROID_BUILD_TOP:-$(dirname $0)/../..}/prebuilts/misc/$HOST_TAG/ccache/ccache
     66         [ -x $CCACHE ] || CCACHE=
     67         ;;
     68 esac
     69 
     70 for opt do
     71     optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
     72     case $opt in
     73     --help|-h|-\?) OPTION_HELP=yes
     74         ;;
     75     --arch=*)
     76         OPTION_ARCH=$optarg
     77         ;;
     78     --armv5)
     79         OPTION_ARMV7=no
     80         ;;
     81     --armv7)
     82         OPTION_ARMV7=yes
     83         ;;
     84     --ccache=*)
     85         CCACHE=$optarg
     86         ;;
     87     --config=*)
     88         OPTION_CONFIG=$optarg
     89         ;;
     90     --cross=*)
     91         OPTION_CROSS=$optarg
     92         ;;
     93     --gcc-version=*)
     94         OPTION_GCC_VERSION=$optarg
     95         ;;
     96     -j*|--jobs=*)
     97         OPTION_JOBS=$optarg
     98         ;;
     99     --out=*)
    100         OPTION_OUT=$optarg
    101         ;;
    102     --savedefconfig)
    103         OPTION_SAVEDEFCONFIG=yes
    104         ;;
    105     --verbose)
    106         OPTION_VERBOSE=true
    107         ;;
    108     *)
    109         echo "unknown option '$opt', use --help"
    110         exit 1
    111     esac
    112 done
    113 
    114 if [ $OPTION_HELP = "yes" ] ; then
    115     echo "Rebuild the prebuilt kernel binary for Android's emulator."
    116     echo ""
    117     echo "options (defaults are within brackets):"
    118     echo ""
    119     echo "  --help                   print this message"
    120     echo "  --arch=<arch>            change target architecture [$ARCH]"
    121     echo "  --armv5                  build ARMv5 binaries"
    122     echo "  --armv7                  build ARMv7 binaries (default. see note below)"
    123     echo "  --out=<directory>        output directory [$OUTPUT]"
    124     echo "  --cross=<prefix>         cross-toolchain prefix [$CROSSPREFIX]"
    125     echo "  --config=<name>          kernel config name [$CONFIG]"
    126     echo "  --savedefconfig          run savedefconfig"
    127     echo "  --ccache=<path>          use compiler cache [${CCACHE:-not set}]"
    128     echo "  --gcc-version=<version>  use specific GCC version [$GCC_VERSION]"
    129     echo "  --verbose                show build commands"
    130     echo "  -j<number>               launch <number> parallel build jobs [$JOBS]"
    131     echo ""
    132     echo "NOTE: --armv7 is equivalent to --config=goldfish_armv7. It is"
    133     echo "      ignored if --config=<name> is used."
    134     echo ""
    135     exit 0
    136 fi
    137 
    138 if [ ! -f include/linux/vermagic.h ]; then
    139     echo "ERROR: You must be in the top-level kernel source directory to run this script."
    140     exit 1
    141 fi
    142 
    143 # Extract kernel version, we'll need to put this in the final binaries names
    144 # to ensure the emulator can trivially know it without probing the binary with
    145 # 'file' or other unreliable heuristics.
    146 KERNEL_MAJOR=$(awk '$1 == "VERSION" { print $3; }' Makefile)
    147 KERNEL_MINOR=$(awk '$1 == "PATCHLEVEL" { print $3; }' Makefile)
    148 KERNEL_PATCH=$(awk '$1 == "SUBLEVEL" { print $3; }' Makefile)
    149 KERNEL_VERSION="$KERNEL_MAJOR.$KERNEL_MINOR.$KERNEL_PATCH"
    150 echo "Found kernel version: $KERNEL_VERSION"
    151 
    152 if [ -n "$OPTION_ARCH" ]; then
    153     ARCH=$OPTION_ARCH
    154 fi
    155 
    156 if [ -n "$OPTION_GCC_VERSION" ]; then
    157     GCC_VERSION=$OPTION_GCC_VERSION
    158 else
    159     if [ "$ARCH" = "x86" ]; then
    160         # Work-around a nasty bug.
    161         # Hence 132637 is 2.6.29.
    162         if [ "$KERNEL_VERSION" = "2.6.29" ]; then
    163             GCC_VERSION=4.6
    164             echo "WARNING: android-goldfish-$KERNEL_VERSION doesn't build --arch=$ARCH with GCC 4.7"
    165         fi
    166     fi
    167     if [ "$ARCH" = "arm64" ]; then
    168         # There is no GCC 4.7 toolchain to build AARCH64 binaries.
    169         GCC_VERSION=4.8
    170     fi
    171     if [ "$ARCH" = "mips64" ]; then
    172         GCC_VERSION=4.9
    173     fi
    174     if [ "$ARCH" = "mips" ]; then
    175         GCC_VERSION=4.9
    176     fi
    177     echo "Autoconfig: --gcc-version=$GCC_VERSION"
    178 fi
    179 
    180 if [ -n "$OPTION_CONFIG" ]; then
    181     CONFIG=$OPTION_CONFIG
    182 else
    183     case $ARCH in
    184         arm)
    185             CONFIG=goldfish_armv7
    186             if  [ "$OPTION_ARMV7" = "no" ]; then
    187                 CONFIG=goldfish
    188             fi
    189             ;;
    190         x86)
    191             # Warning: this is ambiguous, should be 'goldfish' before 3.10,
    192             # and 'i386_emu" after it.
    193             if [ -f "arch/x86/configs/i386_emu_defconfig" ]; then
    194                 CONFIG=i386_emu
    195             else
    196                 CONFIG=goldfish
    197             fi
    198             ;;
    199         x86_64)
    200             CONFIG=x86_64_emu
    201             ;;
    202         mips)
    203             CONFIG=goldfish
    204             ;;
    205         mips64)
    206             CONFIG=ranchu64
    207             ;;
    208         arm64)
    209             CONFIG=ranchu
    210             ;;
    211         *)
    212             echo "ERROR: Invalid arch '$ARCH', try one of $VALID_ARCHS"
    213             exit 1
    214     esac
    215     echo "Auto-config: --config=$CONFIG"
    216 fi
    217 
    218 # Check output directory.
    219 if [ -n "$OPTION_OUT" ] ; then
    220     if [ ! -d "$OPTION_OUT" ] ; then
    221         echo "Output directory '$OPTION_OUT' does not exist ! Aborting."
    222         exit 1
    223     fi
    224     OUTPUT=$OPTION_OUT
    225 else
    226     OUTPUT=$OUTPUT/${ARCH}-${KERNEL_VERSION}
    227     case $CONFIG in
    228         vbox*)
    229             OUTPUT=${OUTPUT}-vbox
    230             ;;
    231         goldfish)
    232             if [ "$ARCH" = "arm" ]; then
    233                 OUTPUT=${OUTPUT}-armv5
    234             fi
    235             ;;
    236     esac
    237     echo "Auto-config: --out=$OUTPUT"
    238     mkdir -p $OUTPUT
    239 fi
    240 
    241 if [ -n "$OPTION_CROSS" ] ; then
    242     CROSSPREFIX="$OPTION_CROSS"
    243     CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
    244 else
    245     case $ARCH in
    246         arm)
    247             CROSSPREFIX=arm-linux-androideabi-
    248             ;;
    249         x86)
    250             CROSSPREFIX=x86_64-linux-android-
    251             # NOTE: kernel-toolchain/toolbox.sh will add -m32
    252             ;;
    253         x86_64)
    254             CROSSPREFIX=x86_64-linux-android-
    255             ;;
    256         mips)
    257             CROSSPREFIX=mips64el-linux-android-
    258             ;;
    259         mips64)
    260             CROSSPREFIX=mips64el-linux-android-
    261             ;;
    262         arm64)
    263             CROSSPREFIX=aarch64-linux-android-
    264             ;;
    265         *)
    266             echo "ERROR: Unsupported architecture!"
    267             exit 1
    268             ;;
    269     esac
    270     CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
    271     echo "Auto-config: --cross=$CROSSPREFIX"
    272 fi
    273 
    274 ZIMAGE=zImage
    275 
    276 case $ARCH in
    277     x86|x86_64)
    278         ZIMAGE=bzImage
    279         ;;
    280     arm64)
    281         ZIMAGE=Image
    282         ;;
    283     mips)
    284         ZIMAGE=
    285         ;;
    286     mips64)
    287         ZIMAGE=
    288         ;;
    289 esac
    290 
    291 # If the cross-compiler is not in the path, try to find it automatically
    292 CROSS_COMPILER="${CROSSPREFIX}gcc"
    293 CROSS_COMPILER_VERSION=$($CROSS_COMPILER --version 2>/dev/null)
    294 if [ $? != 0 ] ; then
    295     BUILD_TOP=$ANDROID_BUILD_TOP
    296     if [ -z "$BUILD_TOP" ]; then
    297         # Assume this script is under external/qemu/distrib/ in the
    298         # Android source tree.
    299         BUILD_TOP=$(dirname $0)/../..
    300         if [ ! -d "$BUILD_TOP/prebuilts" ]; then
    301             BUILD_TOP=
    302         else
    303             BUILD_TOP=$(cd $BUILD_TOP && pwd)
    304         fi
    305     fi
    306     case $ARCH in
    307         x86_64)
    308             # x86_46 binaries are under prebuilts/gcc/<host>/x86 !!
    309             PREBUILT_ARCH=x86
    310             ;;
    311         arm64)
    312             PREBUILT_ARCH=aarch64
    313             ;;
    314         mips64)
    315             PREBUILT_ARCH=mips
    316             ;;
    317         *)
    318             PREBUILT_ARCH=$ARCH
    319             ;;
    320     esac
    321     CROSSPREFIX=$BUILD_TOP/prebuilts/gcc/$HOST_TAG/$PREBUILT_ARCH/$CROSSTOOLCHAIN/bin/$CROSSPREFIX
    322     echo "Checking for ${CROSSPREFIX}gcc"
    323     if [ "$BUILD_TOP" -a -f ${CROSSPREFIX}gcc ]; then
    324         echo "Auto-config: --cross=$CROSSPREFIX"
    325     else
    326         echo "It looks like $CROSS_COMPILER is not in your path ! Aborting."
    327         exit 1
    328     fi
    329 fi
    330 
    331 if [ "$CCACHE" ] ; then
    332     echo "Using ccache program: $CCACHE"
    333     CROSSPREFIX="$CCACHE $CROSSPREFIX"
    334 fi
    335 
    336 export CROSS_COMPILE="$CROSSPREFIX" ARCH SUBARCH=$ARCH
    337 
    338 if [ "$OPTION_JOBS" ]; then
    339     JOBS=$OPTION_JOBS
    340 else
    341     echo "Auto-config: -j$JOBS"
    342 fi
    343 
    344 
    345 # Special magic redirection with our magic toolbox script
    346 # This is needed to add extra compiler flags to compiler.
    347 # See kernel-toolchain/android-kernel-toolchain-* for details
    348 #
    349 export REAL_CROSS_COMPILE="$CROSS_COMPILE"
    350 CROSS_COMPILE=$(dirname "$0")/kernel-toolchain/android-kernel-toolchain-
    351 
    352 MAKE_FLAGS=
    353 if [ "$OPTION_VERBOSE" ]; then
    354   MAKE_FLAGS="$MAKE_FLAGS V=1"
    355 fi
    356 
    357 case $CONFIG in
    358     defconfig)
    359         MAKE_DEFCONFIG=$CONFIG
    360         ;;
    361     *)
    362         MAKE_DEFCONFIG=${CONFIG}_defconfig
    363         ;;
    364 esac
    365 
    366 ORG_ARCH=$ARCH
    367 case $ARCH in
    368     mips64)
    369         # MIPS64 Kernel code base is under arch/mips
    370         ARCH=mips
    371         ;;
    372 esac
    373 
    374 # Do the build
    375 #
    376 rm -f include/asm &&
    377 make $MAKE_DEFCONFIG &&    # configure the kernel
    378 make -j$JOBS $MAKE_FLAGS       # build it
    379 
    380 if [ $? != 0 ] ; then
    381     echo "Could not build the kernel. Aborting !"
    382     exit 1
    383 fi
    384 
    385 if [ "$OPTION_SAVEDEFCONFIG" = "yes" ]; then
    386     case $ARCH in
    387         x86_64)
    388             DEFCONFIG_ARCH=x86
    389             ;;
    390         *)
    391             DEFCONFIG_ARCH=$ARCH
    392             ;;
    393     esac
    394     make savedefconfig
    395     mv -f defconfig arch/$DEFCONFIG_ARCH/configs/${CONFIG}_defconfig
    396 fi
    397 
    398 # Note: The exact names of the output files are important for the Android build,
    399 #       do not change the definitions lightly.
    400 KERNEL_PREFIX=kernel-$KERNEL_VERSION
    401 
    402 # Naming conventions for the kernel image files:
    403 #
    404 #   1) The kernel image is called kernel-qemu, except for 32-bit ARM
    405 #      where it must be called kernel-qemu-armv7
    406 #
    407 #   2) The debug symbol file is called vmlinux-qemu, except for 32-bit
    408 #      ARM where it must be called vmlinux-qemu-armv7
    409 #
    410 OUTPUT_KERNEL=kernel-qemu
    411 OUTPUT_VMLINUX=vmlinux-qemu
    412 if [ "$CONFIG" = "goldfish_armv7" ]; then
    413     OUTPUT_KERNEL=${OUTPUT_KERNEL}-armv7
    414     OUTPUT_VMLINUX=${OUTPUT_VMLINUX}-armv7
    415 fi
    416 
    417 cp -f vmlinux $OUTPUT/$OUTPUT_VMLINUX
    418 if [ ! -z $ZIMAGE ]; then
    419     cp -f arch/$ARCH/boot/$ZIMAGE $OUTPUT/$OUTPUT_KERNEL
    420 else
    421     cp -f vmlinux $OUTPUT/$OUTPUT_KERNEL
    422 fi
    423 echo "Kernel $CONFIG prebuilt images ($OUTPUT_KERNEL and $OUTPUT_VMLINUX) copied to $OUTPUT successfully !"
    424 
    425 cp COPYING $OUTPUT/LINUX_KERNEL_COPYING
    426 
    427 cat > $OUTPUT/README <<EOF
    428 This directory contains kernel images to be used with the Android emulator
    429 program, for the $ORG_ARCH CPU architecture. It was built with the $PROGNAME
    430 script. For more details, read:
    431 
    432   \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT
    433 
    434 EOF
    435 
    436 exit 0
    437