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