1#!/bin/bash
2
3# Copyright (C) 2019 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# Usage:
18#   build/build.sh <make options>*
19# or:
20#   OUT_DIR=<out dir> DIST_DIR=<dist dir> build/build.sh <make options>*
21#
22# Example:
23#   OUT_DIR=output DIST_DIR=dist build/build.sh -j24 V=1
24#
25#
26# The following environment variables are considered during execution:
27#
28#   BUILD_CONFIG
29#     Build config file to initialize the build environment from. The location
30#     is to be defined relative to the repo root directory.
31#     Defaults to 'build.config'.
32#
33#   OUT_DIR
34#     Base output directory for the kernel build.
35#     Defaults to <REPO_ROOT>/out/<BRANCH>.
36#
37#   DIST_DIR
38#     Base output directory for the kernel distribution.
39#     Defaults to <OUT_DIR>/dist
40#
41#   EXT_MODULES
42#     Space separated list of external kernel modules to be build.
43#
44#   UNSTRIPPED_MODULES
45#     Space separated list of modules to be copied to <DIST_DIR>/unstripped
46#     for debugging purposes.
47#
48#   CC
49#     Override compiler to be used. (e.g. CC=clang) Specifying CC=gcc
50#     effectively unsets CC to fall back to the default gcc detected by kbuild
51#     (including any target triplet). To use a custom 'gcc' from PATH, use an
52#     absolute path, e.g.  CC=/usr/local/bin/gcc
53#
54#   LD
55#     Override linker (flags) to be used.
56#
57#   ABI_DEFINITION
58#     Location of the abi definition file relative to <REPO_ROOT>/KERNEL_DIR
59#     If defined (usually in build.config), also copy that abi definition to
60#     <OUT_DIR>/dist/abi.xml when creating the distribution.
61#
62#   KMI_WHITELIST
63#     Location of the main KMI whitelist file relative to <REPO_ROOT>/KERNEL_DIR
64#     If defined (usually in build.config), also copy that whitelist definition
65#     to <OUT_DIR>/dist/abi_whitelist when creating the distribution.
66#
67#   ADDITIONAL_KMI_WHITELISTS
68#     Location of secondary KMI whitelist files relative to
69#     <REPO_ROOT>/KERNEL_DIR. If defined, these additional whitelists will be
70#     appended to the main one before proceeding to the distribution creation.
71#
72# Environment variables to influence the stages of the kernel build.
73#
74#   SKIP_MRPROPER
75#     if defined, skip `make mrproper`
76#
77#   SKIP_DEFCONFIG
78#     if defined, skip `make defconfig`
79#
80#   PRE_DEFCONFIG_CMDS
81#     Command evaluated before `make defconfig`
82#
83#   POST_DEFCONFIG_CMDS
84#     Command evaluated after `make defconfig` and before `make`.
85#
86#   POST_KERNEL_BUILD_CMDS
87#     Command evaluated after `make`.
88#
89#   TAGS_CONFIG
90#     if defined, calls ./scripts/tags.sh utility with TAGS_CONFIG as argument
91#     and exit once tags have been generated
92#
93#   IN_KERNEL_MODULES
94#     if defined, install kernel modules
95#
96#   SKIP_EXT_MODULES
97#     if defined, skip building and installing of external modules
98#
99#   DO_NOT_STRIP_MODULES
100#     Keep debug information for distributed modules.
101#     Note, modules will still be stripped when copied into the ramdisk.
102#
103#   EXTRA_CMDS
104#     Command evaluated after building and installing kernel and modules.
105#
106#   SKIP_CP_KERNEL_HDR
107#     if defined, skip installing kernel headers.
108#
109#   BUILD_BOOT_IMG
110#     if defined, build a boot.img binary that can be flashed into the 'boot'
111#     partition of an Android device. The boot image contains a header as per the
112#     format defined by https://source.android.com/devices/bootloader/boot-image-header
113#     followed by several components like kernel, ramdisk, DTB etc. The ramdisk
114#     component comprises of a GKI ramdisk cpio archive concatenated with a
115#     vendor ramdisk cpio archive which is then gzipped. It is expected that
116#     all components are present in ${DIST_DIR}.
117#
118#     When the BUILD_BOOT_IMG flag is defined, the following flags that point to the
119#     various components needed to build a boot.img also need to be defined.
120#     - MKBOOTIMG_PATH=<path to the mkbootimg.py script which builds boot.img>
121#       (defaults to tools/mkbootimg/mkbootimg.py)
122#     - GKI_RAMDISK_PREBUILT_BINARY=<Name of the GKI ramdisk prebuilt which includes
123#       the generic ramdisk components like init and the non-device-specific rc files>
124#     - VENDOR_RAMDISK_BINARY=<Name of the vendor ramdisk binary which includes the
125#       device-specific components of ramdisk like the fstab file and the
126#       device-specific rc files.>
127#     - KERNEL_BINARY=<name of kernel binary, eg. Image.lz4, Image.gz etc>
128#     - BOOT_IMAGE_HEADER_VERSION=<version of the boot image header>
129#       (defaults to 3)
130#     - KERNEL_CMDLINE=<string of kernel parameters for boot>
131#     If the BOOT_IMAGE_HEADER_VERSION is less than 3, two additional variables must
132#     be defined:
133#     - BASE_ADDRESS=<base address to load the kernel at>
134#     - PAGE_SIZE=<flash page size>
135#
136#   BUILD_INITRAMFS
137#     if defined, build a ramdisk containing all .ko files and resulting depmod artifacts
138#
139#   MODULES_OPTIONS
140#     A /lib/modules/modules.options file is created on the ramdisk containing
141#     the contents of this variable, lines should be of the form: options
142#     <modulename> <param1>=<val> <param2>=<val> ...
143#
144# Note: For historic reasons, internally, OUT_DIR will be copied into
145# COMMON_OUT_DIR, and OUT_DIR will be then set to
146# ${COMMON_OUT_DIR}/${KERNEL_DIR}. This has been done to accommodate existing
147# build.config files that expect ${OUT_DIR} to point to the output directory of
148# the kernel build.
149#
150# The kernel is built in ${COMMON_OUT_DIR}/${KERNEL_DIR}.
151# Out-of-tree modules are built in ${COMMON_OUT_DIR}/${EXT_MOD} where
152# ${EXT_MOD} is the path to the module source code.
153
154set -e
155
156# rel_path <to> <from>
157# Generate relative directory path to reach directory <to> from <from>
158function rel_path() {
159	local to=$1
160	local from=$2
161	local path=
162	local stem=
163	local prevstem=
164	[ -n "$to" ] || return 1
165	[ -n "$from" ] || return 1
166	to=$(readlink -e "$to")
167	from=$(readlink -e "$from")
168	[ -n "$to" ] || return 1
169	[ -n "$from" ] || return 1
170	stem=${from}/
171	while [ "${to#$stem}" == "${to}" -a "${stem}" != "${prevstem}" ]; do
172		prevstem=$stem
173		stem=$(readlink -e "${stem}/..")
174		[ "${stem%/}" == "${stem}" ] && stem=${stem}/
175		path=${path}../
176	done
177	echo ${path}${to#$stem}
178}
179
180export ROOT_DIR=$(readlink -f $(dirname $0)/..)
181
182# For module file Signing with the kernel (if needed)
183FILE_SIGN_BIN=scripts/sign-file
184SIGN_SEC=certs/signing_key.pem
185SIGN_CERT=certs/signing_key.x509
186SIGN_ALGO=sha512
187
188# Save environment parameters before being overwritten by sourcing
189# BUILD_CONFIG.
190CC_ARG="${CC}"
191
192source "${ROOT_DIR}/build/_setup_env.sh"
193
194export MAKE_ARGS=$*
195export MAKEFLAGS="-j$(nproc) ${MAKEFLAGS}"
196export MODULES_STAGING_DIR=$(readlink -m ${COMMON_OUT_DIR}/staging)
197export MODULES_PRIVATE_DIR=$(readlink -m ${COMMON_OUT_DIR}/private)
198export UNSTRIPPED_DIR=${DIST_DIR}/unstripped
199export KERNEL_UAPI_HEADERS_DIR=$(readlink -m ${COMMON_OUT_DIR}/kernel_uapi_headers)
200export INITRAMFS_STAGING_DIR=${MODULES_STAGING_DIR}/initramfs_staging
201
202cd ${ROOT_DIR}
203
204export CLANG_TRIPLE CROSS_COMPILE CROSS_COMPILE_ARM32 ARCH SUBARCH
205
206# Restore the previously saved CC argument that might have been overridden by
207# the BUILD_CONFIG.
208[ -n "${CC_ARG}" ] && CC="${CC_ARG}"
209
210# CC=gcc is effectively a fallback to the default gcc including any target
211# triplets. An absolute path (e.g., CC=/usr/bin/gcc) must be specified to use a
212# custom compiler.
213[ "${CC}" == "gcc" ] && unset CC && unset CC_ARG
214
215TOOL_ARGS=()
216
217if [ -n "${CC}" ]; then
218  TOOL_ARGS+=("CC=${CC}" "HOSTCC=${CC}")
219fi
220
221if [ -n "${LD}" ]; then
222  TOOL_ARGS+=("LD=${LD}")
223fi
224
225if [ -n "${NM}" ]; then
226  TOOL_ARGS+=("NM=${NM}")
227fi
228
229if [ -n "${OBJCOPY}" ]; then
230  TOOL_ARGS+=("OBJCOPY=${OBJCOPY}")
231fi
232
233# Allow hooks that refer to $CC_LD_ARG to keep working until they can be
234# updated.
235CC_LD_ARG="${TOOL_ARGS[@]}"
236
237mkdir -p ${OUT_DIR}
238echo "========================================================"
239echo " Setting up for build"
240if [ -z "${SKIP_MRPROPER}" ] ; then
241  set -x
242  (cd ${KERNEL_DIR} && make "${TOOL_ARGS[@]}" O=${OUT_DIR} ${MAKE_ARGS} mrproper)
243  set +x
244fi
245
246if [ -n "${PRE_DEFCONFIG_CMDS}" ]; then
247  echo "========================================================"
248  echo " Running pre-defconfig command(s):"
249  set -x
250  eval ${PRE_DEFCONFIG_CMDS}
251  set +x
252fi
253
254if [ -z "${SKIP_DEFCONFIG}" ] ; then
255set -x
256(cd ${KERNEL_DIR} && make "${TOOL_ARGS[@]}" O=${OUT_DIR} ${MAKE_ARGS} ${DEFCONFIG})
257set +x
258
259if [ -n "${POST_DEFCONFIG_CMDS}" ]; then
260  echo "========================================================"
261  echo " Running pre-make command(s):"
262  set -x
263  eval ${POST_DEFCONFIG_CMDS}
264  set +x
265fi
266fi
267
268if [ -n "${TAGS_CONFIG}" ]; then
269  echo "========================================================"
270  echo " Running tags command:"
271  set -x
272  (cd ${KERNEL_DIR} && SRCARCH=${ARCH} ./scripts/tags.sh ${TAGS_CONFIG})
273  set +x
274  exit 0
275fi
276
277echo "========================================================"
278echo " Building kernel"
279
280set -x
281(cd ${OUT_DIR} && make O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MAKE_ARGS})
282set +x
283
284if [ -n "${POST_KERNEL_BUILD_CMDS}" ]; then
285  echo "========================================================"
286  echo " Running post-kernel-build command(s):"
287  set -x
288  eval ${POST_KERNEL_BUILD_CMDS}
289  set +x
290fi
291
292rm -rf ${MODULES_STAGING_DIR}
293mkdir -p ${MODULES_STAGING_DIR}
294
295if [ -z "${DO_NOT_STRIP_MODULES}" ]; then
296    MODULE_STRIP_FLAG="INSTALL_MOD_STRIP=1"
297fi
298
299if [ -n "${BUILD_INITRAMFS}" -o  -n "${IN_KERNEL_MODULES}" ]; then
300  echo "========================================================"
301  echo " Installing kernel modules into staging directory"
302
303  (cd ${OUT_DIR} &&                                                           \
304   make O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MODULE_STRIP_FLAG}                   \
305        INSTALL_MOD_PATH=${MODULES_STAGING_DIR} ${MAKE_ARGS} modules_install)
306fi
307
308if [[ -z "${SKIP_EXT_MODULES}" ]] && [[ -n "${EXT_MODULES}" ]]; then
309  echo "========================================================"
310  echo " Building external modules and installing them into staging directory"
311
312  for EXT_MOD in ${EXT_MODULES}; do
313    # The path that we pass in via the variable M needs to be a relative path
314    # relative to the kernel source directory. The source files will then be
315    # looked for in ${KERNEL_DIR}/${EXT_MOD_REL} and the object files (i.e. .o
316    # and .ko) files will be stored in ${OUT_DIR}/${EXT_MOD_REL}. If we
317    # instead set M to an absolute path, then object (i.e. .o and .ko) files
318    # are stored in the module source directory which is not what we want.
319    EXT_MOD_REL=$(rel_path ${ROOT_DIR}/${EXT_MOD} ${KERNEL_DIR})
320    # The output directory must exist before we invoke make. Otherwise, the
321    # build system behaves horribly wrong.
322    mkdir -p ${OUT_DIR}/${EXT_MOD_REL}
323    set -x
324    make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR}  \
325                       O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MAKE_ARGS}
326    make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR}  \
327                       O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MODULE_STRIP_FLAG}    \
328                       INSTALL_MOD_PATH=${MODULES_STAGING_DIR}                \
329                       ${MAKE_ARGS} modules_install
330    set +x
331  done
332
333fi
334
335if [ -n "${EXTRA_CMDS}" ]; then
336  echo "========================================================"
337  echo " Running extra build command(s):"
338  set -x
339  eval ${EXTRA_CMDS}
340  set +x
341fi
342
343OVERLAYS_OUT=""
344for ODM_DIR in ${ODM_DIRS}; do
345  OVERLAY_DIR=${ROOT_DIR}/device/${ODM_DIR}/overlays
346
347  if [ -d ${OVERLAY_DIR} ]; then
348    OVERLAY_OUT_DIR=${OUT_DIR}/overlays/${ODM_DIR}
349    mkdir -p ${OVERLAY_OUT_DIR}
350    make -C ${OVERLAY_DIR} DTC=${OUT_DIR}/scripts/dtc/dtc                     \
351                           OUT_DIR=${OVERLAY_OUT_DIR} ${MAKE_ARGS}
352    OVERLAYS=$(find ${OVERLAY_OUT_DIR} -name "*.dtbo")
353    OVERLAYS_OUT="$OVERLAYS_OUT $OVERLAYS"
354  fi
355done
356
357mkdir -p ${DIST_DIR}
358echo "========================================================"
359echo " Copying files"
360for FILE in $(cd ${OUT_DIR} && ls -1 ${FILES}); do
361  if [ -f ${OUT_DIR}/${FILE} ]; then
362    echo "  $FILE"
363    cp -p ${OUT_DIR}/${FILE} ${DIST_DIR}/
364  else
365    echo "  $FILE is not a file, skipping"
366  fi
367done
368
369for FILE in ${OVERLAYS_OUT}; do
370  OVERLAY_DIST_DIR=${DIST_DIR}/$(dirname ${FILE#${OUT_DIR}/overlays/})
371  echo "  ${FILE#${OUT_DIR}/}"
372  mkdir -p ${OVERLAY_DIST_DIR}
373  cp ${FILE} ${OVERLAY_DIST_DIR}/
374done
375
376MODULES=$(find ${MODULES_STAGING_DIR} -type f -name "*.ko")
377if [ -n "${MODULES}" ]; then
378  if [ -n "${IN_KERNEL_MODULES}" -o -n "${EXT_MODULES}" ]; then
379    echo "========================================================"
380    echo " Copying modules files"
381    for FILE in ${MODULES}; do
382      echo "  ${FILE#${MODULES_STAGING_DIR}/}"
383      cp -p ${FILE} ${DIST_DIR}
384    done
385  fi
386  if [ -n "${BUILD_INITRAMFS}" ]; then
387    echo "========================================================"
388    echo " Creating initramfs"
389    set -x
390    rm -rf ${INITRAMFS_STAGING_DIR}
391    # Depmod requires a version number; use 0.0 instead of determining the
392    # actual kernel version since it is not necessary and will be removed for
393    # the final initramfs image.
394    mkdir -p ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/kernel/
395    cp -r ${MODULES_STAGING_DIR}/lib/modules/*/kernel/* ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/kernel/
396    cp ${MODULES_STAGING_DIR}/lib/modules/*/modules.order ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/modules.order
397    cp ${MODULES_STAGING_DIR}/lib/modules/*/modules.builtin ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/modules.builtin
398
399    if [ -n "${EXT_MODULES}" ]; then
400      mkdir -p ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/extra/
401      cp -r ${MODULES_STAGING_DIR}/lib/modules/*/extra/* ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/extra/
402      (cd ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/ && \
403          find extra -type f -name "*.ko" | sort >> modules.order)
404    fi
405
406    if [ -n "${DO_NOT_STRIP_MODULES}" ]; then
407      # strip debug symbols off initramfs modules
408      find ${INITRAMFS_STAGING_DIR} -type f -name "*.ko" \
409        -exec ${OBJCOPY:${CROSS_COMPILE}strip} --strip-debug {} \;
410    fi
411
412    # Re-run depmod to detect any dependencies between in-kernel and external
413    # modules. Then, create modules.load based on all the modules compiled.
414    (
415      set +x
416      set +e # disable exiting of error so we can add extra comments
417      cd ${INITRAMFS_STAGING_DIR}
418      DEPMOD_OUTPUT=$(depmod -e -F ${DIST_DIR}/System.map -b . 0.0 2>&1)
419      if [[ "$?" -ne 0 ]]; then
420        echo "$DEPMOD_OUTPUT"
421        exit 1;
422      fi
423      echo "$DEPMOD_OUTPUT"
424      if [[ -n $(echo $DEPMOD_OUTPUT | grep "needs unknown symbol") ]]; then
425        echo "ERROR: out-of-tree kernel module(s) need unknown symbol(s)"
426        exit 1
427      fi
428      set -e
429      set -x
430    )
431    cp ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/modules.order ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/modules.load
432    echo "${MODULES_OPTIONS}" > ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/modules.options
433    mv ${INITRAMFS_STAGING_DIR}/lib/modules/0.0/* ${INITRAMFS_STAGING_DIR}/lib/modules/.
434    rmdir ${INITRAMFS_STAGING_DIR}/lib/modules/0.0
435
436    (cd ${INITRAMFS_STAGING_DIR} && find . | cpio -H newc -o > ${MODULES_STAGING_DIR}/initramfs.cpio)
437    gzip -fc ${MODULES_STAGING_DIR}/initramfs.cpio > ${MODULES_STAGING_DIR}/initramfs.cpio.gz
438    mv ${MODULES_STAGING_DIR}/initramfs.cpio.gz ${DIST_DIR}/initramfs.img
439    set +x
440  fi
441fi
442
443if [ -n "${UNSTRIPPED_MODULES}" ]; then
444  echo "========================================================"
445  echo " Copying unstripped module files for debugging purposes (not loaded on device)"
446  mkdir -p ${UNSTRIPPED_DIR}
447  for MODULE in ${UNSTRIPPED_MODULES}; do
448    find ${MODULES_PRIVATE_DIR} -name ${MODULE} -exec cp {} ${UNSTRIPPED_DIR} \;
449  done
450fi
451
452if [ -z "${SKIP_CP_KERNEL_HDR}" ]; then
453  echo "========================================================"
454  echo " Installing UAPI kernel headers:"
455  mkdir -p "${KERNEL_UAPI_HEADERS_DIR}/usr"
456  make -C ${OUT_DIR} O=${OUT_DIR} "${TOOL_ARGS[@]}"                           \
457          INSTALL_HDR_PATH="${KERNEL_UAPI_HEADERS_DIR}/usr" ${MAKE_ARGS}      \
458          headers_install
459  # The kernel makefiles create files named ..install.cmd and .install which
460  # are only side products. We don't want those. Let's delete them.
461  find ${KERNEL_UAPI_HEADERS_DIR} \( -name ..install.cmd -o -name .install \) -exec rm '{}' +
462  KERNEL_UAPI_HEADERS_TAR=${DIST_DIR}/kernel-uapi-headers.tar.gz
463  echo " Copying kernel UAPI headers to ${KERNEL_UAPI_HEADERS_TAR}"
464  tar -czf ${KERNEL_UAPI_HEADERS_TAR} --directory=${KERNEL_UAPI_HEADERS_DIR} usr/
465fi
466
467if [ -z "${SKIP_CP_KERNEL_HDR}" ] ; then
468  echo "========================================================"
469  KERNEL_HEADERS_TAR=${DIST_DIR}/kernel-headers.tar.gz
470  echo " Copying kernel headers to ${KERNEL_HEADERS_TAR}"
471  pushd $ROOT_DIR/$KERNEL_DIR
472    find arch include $OUT_DIR -name *.h -print0               \
473            | tar -czf $KERNEL_HEADERS_TAR                     \
474              --absolute-names                                 \
475              --dereference                                    \
476              --transform "s,.*$OUT_DIR,,"                     \
477              --transform "s,^,kernel-headers/,"               \
478              --null -T -
479  popd
480fi
481
482# Copy the abi_${arch}.xml file from the sources into the dist dir
483if [ -n "${ABI_DEFINITION}" ]; then
484  echo "========================================================"
485  echo " Copying abi definition to ${DIST_DIR}/abi.xml"
486  pushd $ROOT_DIR/$KERNEL_DIR
487    cp "${ABI_DEFINITION}" ${DIST_DIR}/abi.xml
488  popd
489fi
490
491# Copy the abi whitelist file from the sources into the dist dir
492if [ -n "${KMI_WHITELIST}" ]; then
493  echo "========================================================"
494  echo " Copying abi whitelist definition to ${DIST_DIR}/abi_whitelist"
495  pushd $ROOT_DIR/$KERNEL_DIR
496    cp "${KMI_WHITELIST}" ${DIST_DIR}/abi_whitelist
497
498    # If there are additional whitelists specified, append them
499    if [ -n "${ADDITIONAL_KMI_WHITELISTS}" ]; then
500      for whitelist in ${ADDITIONAL_KMI_WHITELISTS}; do
501          echo >> ${DIST_DIR}/abi_whitelist
502          cat "${whitelist}" >> ${DIST_DIR}/abi_whitelist
503      done
504    fi
505
506  popd # $ROOT_DIR/$KERNEL_DIR
507fi
508
509echo "========================================================"
510echo " Files copied to ${DIST_DIR}"
511
512if [ ! -z "${BUILD_BOOT_IMG}" ] ; then
513	if [ -z "${BOOT_IMAGE_HEADER_VERSION}" ]; then
514		BOOT_IMAGE_HEADER_VERSION="3"
515	fi
516	MKBOOTIMG_BASE_ADDR=
517	MKBOOTIMG_PAGE_SIZE=
518	MKBOOTIMG_CMDLINE=
519	if [ -n  "${BASE_ADDRESS}" ]; then
520		MKBOOTIMG_BASE_ADDR="--base ${BASE_ADDRESS}"
521	fi
522	if [ -n  "${PAGE_SIZE}" ]; then
523		MKBOOTIMG_PAGE_SIZE="--pagesize ${PAGE_SIZE}"
524	fi
525	if [ -n "${KERNEL_CMDLINE}" ]; then
526		MKBOOTIMG_CMDLINE="--cmdline \"${KERNEL_CMDLINE}\""
527	fi
528
529	MKBOOTIMG_DTB=
530	if [ "${BOOT_IMAGE_HEADER_VERSION}" -lt "3" ]; then
531		DTB_FILE_LIST=$(find ${DIST_DIR} -name "*.dtb")
532		if [ -z "${DTB_FILE_LIST}" ]; then
533			echo "No *.dtb files found in ${DIST_DIR}"
534			exit 1
535		fi
536		cat $DTB_FILE_LIST > ${DIST_DIR}/dtb.img
537		MKBOOTIMG_DTB="--dtb ${DIST_DIR}/dtb.img"
538	fi
539
540	set -x
541	MKBOOTIMG_RAMDISKS=()
542	for ramdisk in ${VENDOR_RAMDISK_BINARY} ${GKI_RAMDISK_PREBUILT_BINARY} \
543		       "${MODULES_STAGING_DIR}/initramfs.cpio"; do
544		if [ -f "${DIST_DIR}/${ramdisk}" ]; then
545			MKBOOTIMG_RAMDISKS+=("${DIST_DIR}/${ramdisk}")
546		else
547			if [ -f "${ramdisk}" ]; then
548				MKBOOTIMG_RAMDISKS+=("${ramdisk}")
549			fi
550		fi
551	done
552	set +e # disable exiting of error so gzip -t can be handled properly
553	for ((i=0; i<"${#MKBOOTIMG_RAMDISKS[@]}"; i++)); do
554		TEST_GZIP=$(gzip -t "${MKBOOTIMG_RAMDISKS[$i]}" 2>&1 > /dev/null)
555		if [ "$?" -eq 0 ]; then
556			CPIO_NAME=$(echo "${MKBOOTIMG_RAMDISKS[$i]}" | sed -e 's/\(.\+\)\.[a-z]\+$/\1.cpio/')
557			gzip -cd "${MKBOOTIMG_RAMDISKS[$i]}" > ${CPIO_NAME}
558			MKBOOTIMG_RAMDISKS[$i]=${CPIO_NAME}
559		fi
560	done
561	set -e # re-enable exiting on errors
562	if [ "${#MKBOOTIMG_RAMDISKS[@]}" -gt 0 ]; then
563		cat ${MKBOOTIMG_RAMDISKS[*]} | gzip - > ${DIST_DIR}/ramdisk.gz
564	else
565		echo "No ramdisk found. Please provide a GKI and/or a vendor ramdisk."
566		exit 1
567	fi
568	set -x
569
570	if [ -z "${MKBOOTIMG_PATH}" ]; then
571		MKBOOTIMG_PATH="tools/mkbootimg/mkbootimg.py"
572	fi
573	if [ ! -f "$MKBOOTIMG_PATH" ]; then
574		echo "mkbootimg.py script not found. MKBOOTIMG_PATH = $MKBOOTIMG_PATH"
575		exit 1
576	fi
577
578	if [ ! -f "${DIST_DIR}/$KERNEL_BINARY" ]; then
579		echo "kernel binary(KERNEL_BINARY = $KERNEL_BINARY) not present in ${DIST_DIR}"
580		exit 1
581	fi
582
583	if [ -z "${BOOT_IMAGE_HEADER_VERSION}" ]; then
584		echo "BOOT_IMAGE_HEADER_VERSION must specify the boot image header version"
585		exit 1
586	fi
587
588	# (b/141990457) Investigate parenthesis issue with MKBOOTIMG_CMDLINE when
589	# executed outside of this "bash -c".
590	(set -x; bash -c "python $MKBOOTIMG_PATH --kernel ${DIST_DIR}/$KERNEL_BINARY \
591		--ramdisk ${DIST_DIR}/ramdisk.gz \
592		${MKBOOTIMG_DTB} --header_version $BOOT_IMAGE_HEADER_VERSION \
593		${MKBOOTIMG_BASE_ADDR} ${MKBOOTIMG_PAGE_SIZE} ${MKBOOTIMG_CMDLINE} \
594		-o ${DIST_DIR}/boot.img"
595	)
596	set +x
597	echo "boot image created at ${DIST_DIR}/boot.img"
598fi
599
600
601# No trace_printk use on build server build
602if readelf -a ${DIST_DIR}/vmlinux 2>&1 | grep -q trace_printk_fmt; then
603  echo "========================================================"
604  echo "WARN: Found trace_printk usage in vmlinux."
605  echo ""
606  echo "trace_printk will cause trace_printk_init_buffers executed in kernel"
607  echo "start, which will increase memory and lead warning shown during boot."
608  echo "We should not carry trace_printk in production kernel."
609  echo ""
610  if [ ! -z "${STOP_SHIP_TRACEPRINTK}" ]; then
611    echo "ERROR: stop ship on trace_printk usage." 1>&2
612    exit 1
613  fi
614fi
615