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 7export LANG=C 8export LC_ALL=C 9 10PROGNAME=$(basename "$0") 11 12MACHINE=goldfish 13VARIANT=goldfish 14OUTPUT=/tmp/kernel-qemu 15CROSSPREFIX=arm-linux-androideabi- 16CONFIG=goldfish 17GCC_VERSION=4.9 18 19VALID_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# 24HOST_OS=`uname -s` 25case "$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 40esac 41 42# Default number of parallel jobs during the build: cores * 2 43JOBS=$(( $BUILD_NUM_CPUS * 2 )) 44 45ARCH=arm 46 47OPTION_HELP=no 48OPTION_ARMV7=yes 49OPTION_OUT= 50OPTION_CROSS= 51OPTION_ARCH= 52OPTION_CONFIG= 53OPTION_SAVEDEFCONFIG=no 54OPTION_JOBS= 55OPTION_VERBOSE= 56OPTION_GCC_VERSION= 57CCACHE= 58 59case "$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 ;; 68esac 69 70for 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 112done 113 114if [ $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 136fi 137 138if [ ! -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 141fi 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. 146KERNEL_MAJOR=$(awk '$1 == "VERSION" { print $3; }' Makefile) 147KERNEL_MINOR=$(awk '$1 == "PATCHLEVEL" { print $3; }' Makefile) 148KERNEL_PATCH=$(awk '$1 == "SUBLEVEL" { print $3; }' Makefile) 149KERNEL_VERSION="$KERNEL_MAJOR.$KERNEL_MINOR.$KERNEL_PATCH" 150echo "Found kernel version: $KERNEL_VERSION" 151 152if [ -n "$OPTION_ARCH" ]; then 153 ARCH=$OPTION_ARCH 154fi 155 156if [ -n "$OPTION_GCC_VERSION" ]; then 157 GCC_VERSION=$OPTION_GCC_VERSION 158else 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" 178fi 179 180if [ -n "$OPTION_CONFIG" ]; then 181 CONFIG=$OPTION_CONFIG 182else 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" 216fi 217 218# Check output directory. 219if [ -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 225else 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 239fi 240 241if [ -n "$OPTION_CROSS" ] ; then 242 CROSSPREFIX="$OPTION_CROSS" 243 CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION 244else 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" 272fi 273 274ZIMAGE=zImage 275 276case $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 ;; 289esac 290 291# If the cross-compiler is not in the path, try to find it automatically 292CROSS_COMPILER="${CROSSPREFIX}gcc" 293CROSS_COMPILER_VERSION=$($CROSS_COMPILER --version 2>/dev/null) 294if [ $? != 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 329fi 330 331if [ "$CCACHE" ] ; then 332 echo "Using ccache program: $CCACHE" 333 CROSSPREFIX="$CCACHE $CROSSPREFIX" 334fi 335 336export CROSS_COMPILE="$CROSSPREFIX" ARCH SUBARCH=$ARCH 337 338if [ "$OPTION_JOBS" ]; then 339 JOBS=$OPTION_JOBS 340else 341 echo "Auto-config: -j$JOBS" 342fi 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# 349export REAL_CROSS_COMPILE="$CROSS_COMPILE" 350CROSS_COMPILE=$(dirname "$0")/kernel-toolchain/android-kernel-toolchain- 351 352MAKE_FLAGS= 353if [ "$OPTION_VERBOSE" ]; then 354 MAKE_FLAGS="$MAKE_FLAGS V=1" 355fi 356 357case $CONFIG in 358 defconfig) 359 MAKE_DEFCONFIG=$CONFIG 360 ;; 361 *) 362 MAKE_DEFCONFIG=${CONFIG}_defconfig 363 ;; 364esac 365 366ORG_ARCH=$ARCH 367case $ARCH in 368 mips64) 369 # MIPS64 Kernel code base is under arch/mips 370 ARCH=mips 371 ;; 372esac 373 374# Do the build 375# 376rm -f include/asm && 377make $MAKE_DEFCONFIG && # configure the kernel 378make -j$JOBS $MAKE_FLAGS # build it 379 380if [ $? != 0 ] ; then 381 echo "Could not build the kernel. Aborting !" 382 exit 1 383fi 384 385if [ "$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 396fi 397 398# Note: The exact names of the output files are important for the Android build, 399# do not change the definitions lightly. 400KERNEL_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# 410OUTPUT_KERNEL=kernel-qemu 411OUTPUT_VMLINUX=vmlinux-qemu 412if [ "$CONFIG" = "goldfish_armv7" ]; then 413 OUTPUT_KERNEL=${OUTPUT_KERNEL}-armv7 414 OUTPUT_VMLINUX=${OUTPUT_VMLINUX}-armv7 415fi 416 417cp -f vmlinux $OUTPUT/$OUTPUT_VMLINUX 418if [ ! -z $ZIMAGE ]; then 419 cp -f arch/$ARCH/boot/$ZIMAGE $OUTPUT/$OUTPUT_KERNEL 420else 421 cp -f vmlinux $OUTPUT/$OUTPUT_KERNEL 422fi 423echo "Kernel $CONFIG prebuilt images ($OUTPUT_KERNEL and $OUTPUT_VMLINUX) copied to $OUTPUT successfully !" 424 425cp COPYING $OUTPUT/LINUX_KERNEL_COPYING 426 427cat > $OUTPUT/README <<EOF 428This directory contains kernel images to be used with the Android emulator 429program, for the $ORG_ARCH CPU architecture. It was built with the $PROGNAME 430script. For more details, read: 431 432 \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT 433 434EOF 435 436exit 0 437