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.8
     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     echo "Autoconfig: --gcc-version=$GCC_VERSION"
    175 fi
    176 
    177 if [ -n "$OPTION_CONFIG" ]; then
    178     CONFIG=$OPTION_CONFIG
    179 else
    180     case $ARCH in
    181         arm)
    182             CONFIG=goldfish_armv7
    183             if  [ "$OPTION_ARMV7" = "no" ]; then
    184                 CONFIG=goldfish
    185             fi
    186             ;;
    187         x86)
    188             # Warning: this is ambiguous, should be 'goldfish' before 3.10,
    189             # and 'i386_emu" after it.
    190             if [ -f "arch/x86/configs/i386_emu_defconfig" ]; then
    191                 CONFIG=i386_emu
    192             else
    193                 CONFIG=goldfish
    194             fi
    195             ;;
    196         x86_64)
    197             CONFIG=x86_64_emu
    198             ;;
    199         mips)
    200             CONFIG=goldfish
    201             ;;
    202         mips64)
    203             CONFIG=ranchu64
    204             ;;
    205         arm64)
    206             CONFIG=ranchu
    207             ;;
    208         *)
    209             echo "ERROR: Invalid arch '$ARCH', try one of $VALID_ARCHS"
    210             exit 1
    211     esac
    212     echo "Auto-config: --config=$CONFIG"
    213 fi
    214 
    215 # Check output directory.
    216 if [ -n "$OPTION_OUT" ] ; then
    217     if [ ! -d "$OPTION_OUT" ] ; then
    218         echo "Output directory '$OPTION_OUT' does not exist ! Aborting."
    219         exit 1
    220     fi
    221     OUTPUT=$OPTION_OUT
    222 else
    223     OUTPUT=$OUTPUT/${ARCH}-${KERNEL_VERSION}
    224     case $CONFIG in
    225         vbox*)
    226             OUTPUT=${OUTPUT}-vbox
    227             ;;
    228         goldfish)
    229             if [ "$ARCH" = "arm" ]; then
    230                 OUTPUT=${OUTPUT}-armv5
    231             fi
    232             ;;
    233     esac
    234     echo "Auto-config: --out=$OUTPUT"
    235     mkdir -p $OUTPUT
    236 fi
    237 
    238 if [ -n "$OPTION_CROSS" ] ; then
    239     CROSSPREFIX="$OPTION_CROSS"
    240     CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
    241 else
    242     case $ARCH in
    243         arm)
    244             CROSSPREFIX=arm-linux-androideabi-
    245             ;;
    246         x86)
    247             CROSSPREFIX=x86_64-linux-android-
    248             # NOTE: kernel-toolchain/toolbox.sh will add -m32
    249             ;;
    250         x86_64)
    251             CROSSPREFIX=x86_64-linux-android-
    252             ;;
    253         mips)
    254             CROSSPREFIX=mipsel-linux-android-
    255             ;;
    256         mips64)
    257             CROSSPREFIX=mips64el-linux-android-
    258             ;;
    259         arm64)
    260             CROSSPREFIX=aarch64-linux-android-
    261             ;;
    262         *)
    263             echo "ERROR: Unsupported architecture!"
    264             exit 1
    265             ;;
    266     esac
    267     CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
    268     echo "Auto-config: --cross=$CROSSPREFIX"
    269 fi
    270 
    271 ZIMAGE=zImage
    272 
    273 case $ARCH in
    274     x86|x86_64)
    275         ZIMAGE=bzImage
    276         ;;
    277     arm64)
    278         ZIMAGE=Image
    279         ;;
    280     mips)
    281         ZIMAGE=
    282         ;;
    283     mips64)
    284         ZIMAGE=
    285         ;;
    286 esac
    287 
    288 # If the cross-compiler is not in the path, try to find it automatically
    289 CROSS_COMPILER="${CROSSPREFIX}gcc"
    290 CROSS_COMPILER_VERSION=$($CROSS_COMPILER --version 2>/dev/null)
    291 if [ $? != 0 ] ; then
    292     BUILD_TOP=$ANDROID_BUILD_TOP
    293     if [ -z "$BUILD_TOP" ]; then
    294         # Assume this script is under external/qemu/distrib/ in the
    295         # Android source tree.
    296         BUILD_TOP=$(dirname $0)/../..
    297         if [ ! -d "$BUILD_TOP/prebuilts" ]; then
    298             BUILD_TOP=
    299         else
    300             BUILD_TOP=$(cd $BUILD_TOP && pwd)
    301         fi
    302     fi
    303     case $ARCH in
    304         x86_64)
    305             # x86_46 binaries are under prebuilts/gcc/<host>/x86 !!
    306             PREBUILT_ARCH=x86
    307             ;;
    308         arm64)
    309             PREBUILT_ARCH=aarch64
    310             ;;
    311         mips64)
    312             PREBUILT_ARCH=mips
    313             ;;
    314         *)
    315             PREBUILT_ARCH=$ARCH
    316             ;;
    317     esac
    318     CROSSPREFIX=$BUILD_TOP/prebuilts/gcc/$HOST_TAG/$PREBUILT_ARCH/$CROSSTOOLCHAIN/bin/$CROSSPREFIX
    319     echo "Checking for ${CROSSPREFIX}gcc"
    320     if [ "$BUILD_TOP" -a -f ${CROSSPREFIX}gcc ]; then
    321         echo "Auto-config: --cross=$CROSSPREFIX"
    322     else
    323         echo "It looks like $CROSS_COMPILER is not in your path ! Aborting."
    324         exit 1
    325     fi
    326 fi
    327 
    328 if [ "$CCACHE" ] ; then
    329     echo "Using ccache program: $CCACHE"
    330     CROSSPREFIX="$CCACHE $CROSSPREFIX"
    331 fi
    332 
    333 export CROSS_COMPILE="$CROSSPREFIX" ARCH SUBARCH=$ARCH
    334 
    335 if [ "$OPTION_JOBS" ]; then
    336     JOBS=$OPTION_JOBS
    337 else
    338     echo "Auto-config: -j$JOBS"
    339 fi
    340 
    341 
    342 # Special magic redirection with our magic toolbox script
    343 # This is needed to add extra compiler flags to compiler.
    344 # See kernel-toolchain/android-kernel-toolchain-* for details
    345 #
    346 export REAL_CROSS_COMPILE="$CROSS_COMPILE"
    347 CROSS_COMPILE=$(dirname "$0")/kernel-toolchain/android-kernel-toolchain-
    348 
    349 MAKE_FLAGS=
    350 if [ "$OPTION_VERBOSE" ]; then
    351   MAKE_FLAGS="$MAKE_FLAGS V=1"
    352 fi
    353 
    354 case $CONFIG in
    355     defconfig)
    356         MAKE_DEFCONFIG=$CONFIG
    357         ;;
    358     *)
    359         MAKE_DEFCONFIG=${CONFIG}_defconfig
    360         ;;
    361 esac
    362 
    363 ORG_ARCH=$ARCH
    364 case $ARCH in
    365     mips64)
    366         # MIPS64 Kernel code base is under arch/mips
    367         ARCH=mips
    368         ;;
    369 esac
    370 
    371 # Do the build
    372 #
    373 rm -f include/asm &&
    374 make $MAKE_DEFCONFIG &&    # configure the kernel
    375 make -j$JOBS $MAKE_FLAGS       # build it
    376 
    377 if [ $? != 0 ] ; then
    378     echo "Could not build the kernel. Aborting !"
    379     exit 1
    380 fi
    381 
    382 if [ "$OPTION_SAVEDEFCONFIG" = "yes" ]; then
    383     case $ARCH in
    384         x86_64)
    385             DEFCONFIG_ARCH=x86
    386             ;;
    387         *)
    388             DEFCONFIG_ARCH=$ARCH
    389             ;;
    390     esac
    391     make savedefconfig
    392     mv -f defconfig arch/$DEFCONFIG_ARCH/configs/${CONFIG}_defconfig
    393 fi
    394 
    395 # Note: The exact names of the output files are important for the Android build,
    396 #       do not change the definitions lightly.
    397 KERNEL_PREFIX=kernel-$KERNEL_VERSION
    398 
    399 # Naming conventions for the kernel image files:
    400 #
    401 #   1) The kernel image is called kernel-qemu, except for 32-bit ARM
    402 #      where it must be called kernel-qemu-armv7
    403 #
    404 #   2) The debug symbol file is called vmlinux-qemu, except for 32-bit
    405 #      ARM where it must be called vmlinux-qemu-armv7
    406 #
    407 OUTPUT_KERNEL=kernel-qemu
    408 OUTPUT_VMLINUX=vmlinux-qemu
    409 if [ "$CONFIG" = "goldfish_armv7" ]; then
    410     OUTPUT_KERNEL=${OUTPUT_KERNEL}-armv7
    411     OUTPUT_VMLINUX=${OUTPUT_VMLINUX}-armv7
    412 fi
    413 
    414 cp -f vmlinux $OUTPUT/$OUTPUT_VMLINUX
    415 if [ ! -z $ZIMAGE ]; then
    416     cp -f arch/$ARCH/boot/$ZIMAGE $OUTPUT/$OUTPUT_KERNEL
    417 else
    418     cp -f vmlinux $OUTPUT/$OUTPUT_KERNEL
    419 fi
    420 echo "Kernel $CONFIG prebuilt images ($OUTPUT_KERNEL and $OUTPUT_VMLINUX) copied to $OUTPUT successfully !"
    421 
    422 cp COPYING $OUTPUT/LINUX_KERNEL_COPYING
    423 
    424 cat > $OUTPUT/README <<EOF
    425 This directory contains kernel images to be used with the Android emulator
    426 program, for the $ORG_ARCH CPU architecture. It was built with the $PROGNAME
    427 script. For more details, read:
    428 
    429   \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT
    430 
    431 EOF
    432 
    433 exit 0
    434