David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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 |
Prathmesh Prabhu | 73521ea | 2015-09-22 13:15:40 -0700 | [diff] [blame] | 17 | GCC_VERSION=4.9 |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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 |
David 'Digit' Turner | a95ab5f | 2015-03-30 11:29:49 +0200 | [diff] [blame] | 171 | if [ "$ARCH" = "mips64" ]; then |
| 172 | GCC_VERSION=4.9 |
| 173 | fi |
Miodrag Dinic | 011961e | 2015-04-29 16:51:41 +0200 | [diff] [blame] | 174 | if [ "$ARCH" = "mips" ]; then |
| 175 | GCC_VERSION=4.9 |
| 176 | fi |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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" |
David 'Digit' Turner | 676e82a | 2015-02-24 09:27:24 +0100 | [diff] [blame] | 243 | CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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) |
Miodrag Dinic | 011961e | 2015-04-29 16:51:41 +0200 | [diff] [blame] | 257 | CROSSPREFIX=mips64el-linux-android- |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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 | ;; |
David 'Digit' Turner | 676e82a | 2015-02-24 09:27:24 +0100 | [diff] [blame] | 314 | mips64) |
| 315 | PREBUILT_ARCH=mips |
| 316 | ;; |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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 | |
David 'Digit' Turner | a95ab5f | 2015-03-30 11:29:49 +0200 | [diff] [blame] | 366 | ORG_ARCH=$ARCH |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 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 |
David 'Digit' Turner | a95ab5f | 2015-03-30 11:29:49 +0200 | [diff] [blame] | 429 | program, for the $ORG_ARCH CPU architecture. It was built with the $PROGNAME |
David 'Digit' Turner | 43e00a0 | 2015-02-04 19:42:17 +0100 | [diff] [blame] | 430 | script. For more details, read: |
| 431 | |
| 432 | \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT |
| 433 | |
| 434 | EOF |
| 435 | |
| 436 | exit 0 |