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