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