xref: /aosp_15_r20/prebuilts/qemu-kernel/build-kernel.sh (revision 8f44c3f556abf1c3d5b54135eb52d5c1f558a738)
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
7export LANG=C
8export LC_ALL=C
9
10PROGNAME=$(basename "$0")
11
12MACHINE=goldfish
13VARIANT=goldfish
14OUTPUT=/tmp/kernel-qemu
15CROSSPREFIX=arm-linux-androideabi-
16CONFIG=goldfish
17GCC_VERSION=4.9
18
19VALID_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#
24HOST_OS=`uname -s`
25case "$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
40esac
41
42# Default number of parallel jobs during the build: cores * 2
43JOBS=$(( $BUILD_NUM_CPUS * 2 ))
44
45ARCH=arm
46
47OPTION_HELP=no
48OPTION_ARMV7=yes
49OPTION_OUT=
50OPTION_CROSS=
51OPTION_ARCH=
52OPTION_CONFIG=
53OPTION_SAVEDEFCONFIG=no
54OPTION_JOBS=
55OPTION_VERBOSE=
56OPTION_GCC_VERSION=
57CCACHE=
58
59case "$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        ;;
68esac
69
70for 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
112done
113
114if [ $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
136fi
137
138if [ ! -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
141fi
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.
146KERNEL_MAJOR=$(awk '$1 == "VERSION" { print $3; }' Makefile)
147KERNEL_MINOR=$(awk '$1 == "PATCHLEVEL" { print $3; }' Makefile)
148KERNEL_PATCH=$(awk '$1 == "SUBLEVEL" { print $3; }' Makefile)
149KERNEL_VERSION="$KERNEL_MAJOR.$KERNEL_MINOR.$KERNEL_PATCH"
150echo "Found kernel version: $KERNEL_VERSION"
151
152if [ -n "$OPTION_ARCH" ]; then
153    ARCH=$OPTION_ARCH
154fi
155
156if [ -n "$OPTION_GCC_VERSION" ]; then
157    GCC_VERSION=$OPTION_GCC_VERSION
158else
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
171    if [ "$ARCH" = "mips64" ]; then
172        GCC_VERSION=4.9
173    fi
174    if [ "$ARCH" = "mips" ]; then
175        GCC_VERSION=4.9
176    fi
177    echo "Autoconfig: --gcc-version=$GCC_VERSION"
178fi
179
180if [ -n "$OPTION_CONFIG" ]; then
181    CONFIG=$OPTION_CONFIG
182else
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"
216fi
217
218# Check output directory.
219if [ -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
225else
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
239fi
240
241if [ -n "$OPTION_CROSS" ] ; then
242    CROSSPREFIX="$OPTION_CROSS"
243    CROSSTOOLCHAIN=${CROSSPREFIX}$GCC_VERSION
244else
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)
257            CROSSPREFIX=mips64el-linux-android-
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"
272fi
273
274ZIMAGE=zImage
275
276case $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        ;;
289esac
290
291# If the cross-compiler is not in the path, try to find it automatically
292CROSS_COMPILER="${CROSSPREFIX}gcc"
293CROSS_COMPILER_VERSION=$($CROSS_COMPILER --version 2>/dev/null)
294if [ $? != 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            ;;
314        mips64)
315            PREBUILT_ARCH=mips
316            ;;
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
329fi
330
331if [ "$CCACHE" ] ; then
332    echo "Using ccache program: $CCACHE"
333    CROSSPREFIX="$CCACHE $CROSSPREFIX"
334fi
335
336export CROSS_COMPILE="$CROSSPREFIX" ARCH SUBARCH=$ARCH
337
338if [ "$OPTION_JOBS" ]; then
339    JOBS=$OPTION_JOBS
340else
341    echo "Auto-config: -j$JOBS"
342fi
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#
349export REAL_CROSS_COMPILE="$CROSS_COMPILE"
350CROSS_COMPILE=$(dirname "$0")/kernel-toolchain/android-kernel-toolchain-
351
352MAKE_FLAGS=
353if [ "$OPTION_VERBOSE" ]; then
354  MAKE_FLAGS="$MAKE_FLAGS V=1"
355fi
356
357case $CONFIG in
358    defconfig)
359        MAKE_DEFCONFIG=$CONFIG
360        ;;
361    *)
362        MAKE_DEFCONFIG=${CONFIG}_defconfig
363        ;;
364esac
365
366ORG_ARCH=$ARCH
367case $ARCH in
368    mips64)
369        # MIPS64 Kernel code base is under arch/mips
370        ARCH=mips
371        ;;
372esac
373
374# Do the build
375#
376rm -f include/asm &&
377make $MAKE_DEFCONFIG &&    # configure the kernel
378make -j$JOBS $MAKE_FLAGS       # build it
379
380if [ $? != 0 ] ; then
381    echo "Could not build the kernel. Aborting !"
382    exit 1
383fi
384
385if [ "$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
396fi
397
398# Note: The exact names of the output files are important for the Android build,
399#       do not change the definitions lightly.
400KERNEL_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#
410OUTPUT_KERNEL=kernel-qemu
411OUTPUT_VMLINUX=vmlinux-qemu
412if [ "$CONFIG" = "goldfish_armv7" ]; then
413    OUTPUT_KERNEL=${OUTPUT_KERNEL}-armv7
414    OUTPUT_VMLINUX=${OUTPUT_VMLINUX}-armv7
415fi
416
417cp -f vmlinux $OUTPUT/$OUTPUT_VMLINUX
418if [ ! -z $ZIMAGE ]; then
419    cp -f arch/$ARCH/boot/$ZIMAGE $OUTPUT/$OUTPUT_KERNEL
420else
421    cp -f vmlinux $OUTPUT/$OUTPUT_KERNEL
422fi
423echo "Kernel $CONFIG prebuilt images ($OUTPUT_KERNEL and $OUTPUT_VMLINUX) copied to $OUTPUT successfully !"
424
425cp COPYING $OUTPUT/LINUX_KERNEL_COPYING
426
427cat > $OUTPUT/README <<EOF
428This directory contains kernel images to be used with the Android emulator
429program, for the $ORG_ARCH CPU architecture. It was built with the $PROGNAME
430script. For more details, read:
431
432  \$AOSP/external/qemu/docs/ANDROID-KERNEL.TXT
433
434EOF
435
436exit 0
437