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