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