1 #!/bin/sh 2 # 3 # Copyright (C) 2011 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 # This script is used to rebuild the Android goldfish arm-based kernel from 19 # sources. 20 21 ### 22 ### Utilities 23 ### 24 25 # Implementation of 'dirname' that works safely when paths contains spaces 26 # $1: output variable name 27 # $2: path (may contain spaces) 28 # Usage: set_dirname FOO "/path/to/foo with spaces" 29 set_dirname () 30 { 31 eval $1="`dirname \"$2\"`" 32 } 33 34 # Same as set_dirname, but for the 'basename' command 35 set_basename () 36 { 37 eval $1="`basename \"$2\"`" 38 } 39 40 # Check the status of the previous command, and print a message and exit 41 # if it didn't succeed. 42 fail_panic () 43 { 44 if [ $? != 0 ]; then 45 echo "ERROR: $@" 46 exit 1 47 fi 48 } 49 50 # Send a message to the log. Does nothing if --verbose is not used 51 log () 52 { 53 if [ "$VERBOSE" = "yes" ] ; then 54 echo "$@" 55 fi 56 } 57 58 # Run a comment. Print it to the output first if --verbose is used 59 run () 60 { 61 if [ "$VERBOSE" = "yes" ] ; then 62 echo "### COMMAND: $@" 63 $@ 64 else 65 $@ >/dev/null 2>&1 66 fi 67 } 68 69 fail_ifnotdir () 70 { 71 local _dir="$1" 72 if [ ! -d "$_dir" ]; then 73 shift 74 echo "ERROR: $@ ($_dir)" 75 exit 1 76 fi 77 } 78 79 # Check wether program '$2' is in your path, and set variable $1 to its 80 # full path, or to empty otherwise. 81 # Example: find_program FOO foo 82 # 83 # $1: Variable name 84 # $2: Program name 85 find_program () 86 { 87 local FINDPROG_=`which $2 2>/dev/null` 88 if [ -n "$FINDPROG_" ]; then 89 eval $1="$FINDPROG_"; 90 else 91 eval $1= 92 fi 93 } 94 95 set_dirname PROGDIR "$0" 96 set_basename PROGNAME "$0" 97 98 ### 99 ### Get defaults 100 ### 101 102 # Location of prebuilt kernel images relative to Android top-level 103 PREBUILT_KERNEL_DIR="prebuilts/qemu-kernel/arm" 104 105 # Look for top-level Android build source tree if not in environment 106 107 if [ -n "$ANDROID_BUILD_TOP" ] ; then 108 OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR" 109 else 110 OUT_DIR= 111 fi 112 113 TOOLCHAIN_NAME=arm-eabi-4.4.0 114 TOOLCHAIN_PREFIX=arm-eabi 115 GCC="$TOOLCHAIN_PREFIX-gcc" 116 117 JOBS="`cat /proc/cpuinfo | grep -e "^processor" | wc -l`" 118 119 ### 120 ### Parse options 121 ### 122 OPTION_HELP=no 123 VERBOSE=no 124 VERBOSE2=no 125 OPTION_OUT_DIR= 126 OPTION_CC= 127 128 PARAMS="" 129 130 for opt do 131 optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` 132 case "$opt" in 133 --help|-h|-\?) OPTION_HELP=yes 134 ;; 135 --verbose) 136 if [ "$VERBOSE" = "yes" ] ; then 137 VERBOSE2=yes 138 else 139 VERBOSE=yes 140 fi 141 ;; 142 --out-dir=*) 143 OPTION_OUT_DIR="$optarg" 144 ;; 145 --cc=*) 146 OPTION_CC="$optarg" 147 ;; 148 --toolchain=*) 149 TOOLCHAIN_NAME="$optarg" 150 ;; 151 --jobs=*) 152 JOBS="$optarg" 153 ;; 154 -*) 155 echo "unknown option '$opt', use --help" 156 exit 1 157 ;; 158 *) 159 if [ -z "$PARAMS" ] ; then 160 PARAMS="$opt" 161 else 162 PARAMS="$PARAMS $opt" 163 fi 164 ;; 165 esac 166 done 167 168 if [ "$OPTION_HELP" = "yes" ] ; then 169 echo "Usage: $PROGNAME <options> /path/to/kernel" 170 echo "" 171 echo "Rebuild the prebuilt Android goldfish-specific kernel from sources." 172 echo "" 173 echo "Options (default are inside brackets):" 174 echo "" 175 echo " --help Print this message." 176 echo " --verbose Enable verbose output." 177 echo " --android=<path> Set Android top-level directory [$ANDROID_BUILD_TOP]" 178 echo " --out-dir=<path> Set output directory [$OUT_DIR]" 179 echo " --toolchain=<name> Toolchain name [$TOOLCHAIN_NAME]" 180 echo " --cc=<path> Path to C compiler [$GCC]" 181 echo " --jobs=<count> Perform <count> parallel builds [$JOBS]" 182 echo "" 183 echo "The --toolchain option is ignored if you use the --cc one." 184 exit 0 185 fi 186 187 ### 188 ### Parse parameters 189 ### 190 191 set_parameters () 192 { 193 if [ -z "$1" ] ; then 194 echo "ERROR: Please specify path of kernel sources directory. See --help for details." 195 exit 1 196 fi 197 if [ -n "$2" ]; then 198 echo "ERROR: Too many arguments. See --help for details." 199 exit 1 200 fi 201 KERNEL_DIR="$1" 202 fail_ifnotdir "$KERNEL_DIR" "Missing kernel directory" 203 fail_ifnotdir "$KERNEL_DIR/kernel" "Missing kernel-specific directory" 204 fail_ifnotdir "$KERNEL_DIR/arch" "Missing kernel-specific directory" 205 fail_ifnotdir "$KERNEL_DIR/arch/arm/mach-goldfish" "Missing goldfish-specific directory" 206 } 207 208 set_parameters $PARAMS 209 210 ### 211 ### Determine build configuration 212 ### 213 214 if [ -n "$OPTION_OUT_DIR" ] ; then 215 OUT_DIR="$OPTION_OUT_DIR" 216 fi 217 218 if [ -z "$ANDROID_BUILD_TOP" ] ; then 219 # Assume that we are under $ANDROID_BUILD_TOP/prebuilt/android-arm/kernel 220 ANDROID_BUILD_TOP="`cd \"$PROGDIR\"/../../.. && pwd`" 221 if [ -d "$ANDROID_BUILD_TOP" ]; then 222 echo "Probed Android top-level directory: $ANDROID_BUILD_TOP" 223 else 224 echo "ERROR: Can't find Android top-leveld directory. Please define ANDROID_BUILD_TOP" 225 exit 1 226 fi 227 fi 228 229 if [ -z "$OUT_DIR" ] ; then 230 OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR" 231 if [ ! -d "$OUT_DIR" ]; then 232 echo "ERROR: Missing default output dir: $OUT_DIR" 233 echo "Please use --out-dir=<path> to specify alternative output directory." 234 exit 1 235 fi 236 fi 237 238 echo "Using output directory: $OUT_DIR" 239 mkdir -p "$OUT_DIR" 240 fail_panic "Could not create directory: $OUT_DIR" 241 242 # Find toolchain 243 244 if [ -n "$OPTION_CC" ]; then 245 GCC="$OPTION_CC" 246 else 247 find_program GCC $TOOLCHAIN_PREFIX-gcc 248 fi 249 250 if [ -z "$GCC" ]; then 251 TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilt/linux-x86/toolchain/$TOOLCHAIN_NAME/bin" 252 if [ ! -d "$TOOLCHAIN_DIR" ] ; then 253 echo "ERROR: Missing directory: $TOOLCHAIN_DIR" 254 exit 1 255 fi 256 GCC="$TOOLCHAIN_DIR/$TOOLCHAIN_PREFIX-gcc" 257 if [ ! -f "$GCC" ] ; then 258 echo "ERROR: Missing program file: $GCC" 259 exit 1 260 fi 261 fi 262 263 CROSS_COMPILE="`echo $GCC | sed -e 's!gcc$!!g' `" 264 echo "Using cross-toolchain prefix: $CROSS_COMPILE" 265 266 # Do we have ccache in our path? 267 find_program CCACHE ccache 268 if [ -n "$CCACHE" ]; then 269 echo "Using ccache program: $CCACHE" 270 CROSS_COMPILE="ccache $CROSS_COMPILE" 271 fi 272 273 ### 274 ### Do the build 275 ### 276 277 cd "$KERNEL_DIR" 278 ARCH=arm 279 SUBARCH=arm 280 281 export CROSS_COMPILE ARCH SUBARCH 282 283 # $1: defconfig name (e.g. goldfish or goldfish_armv7) 284 # $2: output suffix (e.g. "" or "-armv7") 285 do_build () 286 { 287 MAKE_FLAGS="-j$JOBS" 288 # Use --verbose --verbose to see build commands 289 if [ "$VERBOSE2" = "yes" ] ; then 290 MAKE_FLAGS="$MAKE_FLAGS V=1" 291 fi 292 echo "Cleaning up source tree." 293 git ls-files -o | xargs rm -f 294 echo "Setting up $1_defconfig..." 295 run make $1_defconfig 296 fail_panic "Could not setup $1_defconfig build!" 297 echo "Building $1_deconfig..." 298 run make $MAKE_FLAGS 299 fail_panic "Could not build $1_defconfig!" 300 echo "Copying $1_defconfig binaries to $OUT_DIR." 301 cp -f arch/arm/boot/zImage "$OUT_DIR/kernel-qemu$2" 302 cp -f vmlinux "$OUT_DIR/vmlinux-qemu$2" 303 } 304 305 do_build goldfish 306 if [ -f arch/arm/configs/goldfish_armv7_defconfig ]; then 307 do_build goldfish_armv7 -armv7 308 fi 309 310 echo "Done." 311 exit 0 312