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