| #!/bin/bash |
| # |
| # Copyright 2010 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # |
| # Script which ensures that a given image has an up-to-date |
| # kernel partition, rootfs integrity hashes, and legacy bootloader configs. |
| |
| # --- BEGIN COMMON.SH BOILERPLATE --- |
| # Load common CrOS utilities. Inside the chroot this file is installed in |
| # /usr/lib/crosutils. Outside the chroot we find it relative to the script's |
| # location. |
| find_common_sh() { |
| local common_paths=("$(dirname "$(readlink -f "$0")")/.." /usr/lib/crosutils) |
| local path |
| |
| SCRIPT_ROOT="${common_paths[0]}" |
| for path in "${common_paths[@]}"; do |
| if [ -r "${path}/common.sh" ]; then |
| SCRIPT_ROOT="${path}" |
| break |
| fi |
| done |
| } |
| |
| find_common_sh |
| # shellcheck source=../common.sh |
| . "${SCRIPT_ROOT}/common.sh" || exit 1 |
| # --- END COMMON.SH BOILERPLATE --- |
| |
| # Need to be inside the chroot to load chromeos-common.sh |
| assert_inside_chroot |
| |
| # Load functions and constants for chromeos-install |
| # shellcheck source=../../platform2/chromeos-common-script/share/chromeos-common.sh |
| . /usr/share/misc/chromeos-common.sh || exit 1 |
| # shellcheck source=../build_library/build_image_util.sh |
| . "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1 |
| # shellcheck source=../build_library/disk_layout_util.sh |
| . "${BUILD_LIBRARY_DIR}/disk_layout_util.sh" || exit 1 |
| # shellcheck source=../build_library/mount_gpt_util.sh |
| . "${BUILD_LIBRARY_DIR}/mount_gpt_util.sh" || exit 1 |
| # shellcheck source=../build_library/ext2_sb_util.sh |
| . "${BUILD_LIBRARY_DIR}/ext2_sb_util.sh" || exit 1 |
| |
| switch_to_strict_mode |
| |
| if [ $# -lt 2 ]; then |
| echo "Usage: ${0} /PATH/TO/IMAGE IMAGE.BIN [shflags overrides]" |
| exit 1 |
| fi |
| |
| IMAGE_DIR="$(readlink -f "${1}")" |
| IMAGE="${IMAGE_DIR}/${2}" |
| shift |
| shift |
| FLAG_OVERRIDES=( "$@" ) |
| |
| if get_boot_desc "${IMAGE_DIR}/boot.desc"; then |
| info "Boot-time configuration for ${IMAGE_DIR}:" |
| for flag in "${boot_desc_flags[@]}"; do |
| info " ${flag}" |
| done |
| else |
| warn "Falling back to command line parsing." |
| fi |
| |
| if [ ! -r "${IMAGE}" ]; then |
| die "${IMAGE} cannot be read!" |
| fi |
| |
| locate_gpt |
| set +e |
| |
| # Now parse the build settings from ${OUTPUT_DIR}/boot.desc |
| DEFINE_string adjust_part "" \ |
| "Adjustments to apply to the partition table" |
| DEFINE_string board "${DEFAULT_BOARD}" \ |
| "Board we're building for." |
| DEFINE_string image_type "base" \ |
| "Type of image we're building for (base/factory_install)." |
| DEFINE_string output_dir "/tmp" \ |
| "Directory to place output in." |
| DEFINE_string arch "x86" \ |
| "Architecture to make bootable for: arm, mips, x86, or amd64" |
| DEFINE_boolean cleanup_dirs "${FLAGS_TRUE}" \ |
| "Whether the mount dirs should be removed on completion." |
| |
| DEFINE_string boot_args "noinitrd" \ |
| "Additional boot arguments to pass to the commandline" |
| |
| DEFINE_string rootfs_hash "/tmp/rootfs.hash" \ |
| "Path where the rootfs hash should be stored." |
| DEFINE_boolean enable_rootfs_verification "${FLAGS_FALSE}" \ |
| "Default all bootloaders to NOT use kernel-based root fs integrity checking." |
| DEFINE_integer verity_error_behavior 3 \ |
| "Kernel verified boot error behavior (0: I/O errors, 1: reboot, 2: nothing)" |
| DEFINE_integer verity_max_ios -1 \ |
| "Number of outstanding I/O operations dm-verity caps at." |
| DEFINE_string verity_algorithm "sha256" \ |
| "Cryptographic hash algorithm used for kernel vboot." |
| DEFINE_string verity_salt "" \ |
| "Salt for rootfs hash tree." |
| |
| DEFINE_string keys_dir "${VBOOT_DEVKEYS_DIR}" \ |
| "Directory containing the signing keys." |
| |
| DEFINE_string rootfs_mountpoint "/tmp/rootfs" \ |
| "Path where the rootfs can be safely mounted" |
| DEFINE_string statefulfs_mountpoint "/tmp/statefulfs" \ |
| "Path where the statefulfs can be safely mounted" |
| DEFINE_string espfs_mountpoint "/tmp/espfs" \ |
| "Path where the espfs can be safely mounted" |
| |
| DEFINE_boolean use_dev_keys "${FLAGS_FALSE}" \ |
| "Use developer keys for signing. (Default: false)" |
| |
| DEFINE_boolean fsck_rootfs "${FLAGS_FALSE}" \ |
| "Check integrity of the rootfs on the modified image." |
| |
| DEFINE_boolean force_developer_mode "${FLAGS_FALSE}" \ |
| "Add cros_debug to boot args." |
| |
| DEFINE_string enable_serial "" \ |
| "Enable serial port for printks. Example values: ttyS0" |
| DEFINE_integer loglevel 7 \ |
| "The loglevel to add to the kernel command line." |
| |
| # Parse the boot.desc and any overrides |
| set -- "${boot_desc_flags[@]}" "${FLAG_OVERRIDES[@]}" |
| FLAGS "${@}" || exit 1 |
| |
| [ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt) |
| |
| # board_options.sh relies on ${SRC_IMAGE} environment variable. |
| SRC_IMAGE="${IMAGE}" |
| # shellcheck source=../build_library/board_options.sh |
| . "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1 |
| load_board_specific_script "board_specific_setup.sh" |
| |
| # Only now can we die on error. shflags functions leak non-zero error codes, |
| # so will die prematurely if 'switch_to_strict_mode' is specified before now. |
| switch_to_strict_mode -u |
| |
| append_boot_flag() { |
| local file="$1" |
| local pattern="$2" |
| local base_pattern="$3" |
| |
| [[ -f "${file}" ]] || return "${FLAGS_TRUE}" |
| sudo grep -wq "${pattern}" "${file}" && return "${FLAGS_TRUE}" |
| sudo sed -i "s/\b${base_pattern}\b/& ${pattern}/g" "${file}" |
| } |
| |
| check_kernel_size() { |
| local kernel_image_size="$1" |
| local kernel_part="$2" |
| local kernel_slot="$3" |
| local kernel_partition_size |
| kernel_partition_size=$(get_partition_size "${FLAGS_image_type}" \ |
| "${kernel_part}") |
| local kernel_partition_size_90 |
| kernel_partition_size_90=$(( kernel_partition_size * 90 / 100 )) |
| info "Kernel partition ${kernel_slot} size is ${kernel_partition_size} bytes." |
| if [[ ${kernel_image_size} -gt ${kernel_partition_size} ]]; then |
| die "Kernel image won't fit in partition ${kernel_slot}!" |
| elif [[ ${kernel_image_size} -gt ${kernel_partition_size_90} ]]; then |
| warn "Kernel partition ${kernel_slot} is more than 90% full!" |
| fi |
| } |
| |
| build_img() { |
| local image_name="$1" |
| local root_dev="$2" |
| local root_dev_size="$3" |
| local keyblock="$4" |
| local private="$5" |
| local public="$6" |
| local vblock=${7:-""} |
| local extra_arguments=() |
| |
| if [[ "${FLAGS_enable_rootfs_verification}" -eq "${FLAGS_TRUE}" ]]; then |
| extra_arguments+=(--enable_rootfs_verification) |
| else |
| # Default to non-verified |
| extra_arguments+=(--noenable_rootfs_verification) |
| fi |
| |
| if [[ -n "${vblock}" ]]; then |
| extra_arguments+=(--hd_vblock="${FLAGS_output_dir}/${vblock}") |
| fi |
| |
| "${SCRIPTS_DIR}"/build_kernel_image.sh \ |
| --board="${FLAGS_board}" \ |
| --arch="${FLAGS_arch}" \ |
| --to="${FLAGS_output_dir}/${image_name}" \ |
| --vmlinuz="${VMLINUZ}" \ |
| --working_dir="${FLAGS_output_dir}" \ |
| --boot_args="${FLAGS_boot_args}" \ |
| --keep_work \ |
| --rootfs_image="${root_dev}" \ |
| --rootfs_image_size="${root_dev_size}" \ |
| --rootfs_hash="${FLAGS_rootfs_hash}" \ |
| --verity_hash_alg="${FLAGS_verity_algorithm}" \ |
| --verity_max_ios="${FLAGS_verity_max_ios}" \ |
| --verity_error_behavior="${FLAGS_verity_error_behavior}" \ |
| --verity_salt="${FLAGS_verity_salt}" \ |
| --keys_dir="${FLAGS_keys_dir}" \ |
| --keyblock="${keyblock}" \ |
| --private="${private}" \ |
| --public="${public}" \ |
| --enable_serial="${FLAGS_enable_serial}" \ |
| "${extra_arguments[@]}" |
| } |
| |
| make_image_bootable() { |
| local image="$1" |
| |
| # Update legacy boot config templates (in rootfs) before rootfs is locked. |
| # This is required because postinst will copy new legacy boot configurations |
| # from rootfs partition instead of modifying existing entries in EFI |
| # partition. |
| if [[ "${FLAGS_force_developer_mode}" -eq "${FLAGS_TRUE}" ]]; then |
| trap "unmount_image ; die 'cros_make_image_bootable failed.'" EXIT |
| mount_image "${image}" "${FLAGS_rootfs_mountpoint}" \ |
| "${FLAGS_statefulfs_mountpoint}" |
| |
| append_boot_flag "${FLAGS_rootfs_mountpoint}/boot/syslinux/root.A.cfg" \ |
| "cros_debug" "cros_legacy" |
| append_boot_flag "${FLAGS_rootfs_mountpoint}/boot/syslinux/root.B.cfg" \ |
| "cros_debug" "cros_legacy" |
| append_boot_flag "${FLAGS_rootfs_mountpoint}/boot/syslinux/usb.A.cfg" \ |
| "cros_debug" "cros_legacy" |
| append_boot_flag "${FLAGS_rootfs_mountpoint}/boot/efi/boot/grub.cfg" \ |
| "cros_debug" "cros_efi" |
| |
| unmount_image |
| trap - EXIT |
| fi |
| |
| # Make the filesystem un-mountable as read-write. |
| # mount_gpt_image.sh will undo this as needed. |
| # TODO(wad) make sure there is parity in the signing scripts. |
| if [[ "${FLAGS_enable_rootfs_verification}" -eq "${FLAGS_TRUE}" ]]; then |
| # TODO(wad) this would be a good place to reset any other ext2 metadata. |
| info "Disabling r/w mount of the root filesystem" |
| local rootfs_offset |
| rootfs_offset="$(partoffset "${image}" 3)" |
| disable_rw_mount "${image}" "$(( rootfs_offset * 512 ))" |
| |
| # For factory_install images, override FLAGS_enable_rootfs_verification |
| # here, so the following build_img calls won't make kernel set up the |
| # device mapper on initialization. |
| if [[ "${FLAGS_image_type}" == "factory_install" ]]; then |
| FLAGS_enable_rootfs_verification="${FLAGS_FALSE}" |
| fi |
| fi |
| |
| trap "unmount_image ; die 'cros_make_image_bootable failed.'" EXIT |
| mount_image "${image}" "${FLAGS_rootfs_mountpoint}" \ |
| "${FLAGS_statefulfs_mountpoint}" "" "--safe" |
| |
| # Newer `mount` will decode the filename backing the loop device, |
| # so we need to dig deeper and find the answer ourselves. |
| root_dev=$(awk -v mnt="${FLAGS_rootfs_mountpoint}" \ |
| '$2 == mnt { print $1 }' /proc/mounts) |
| if [[ -z "${root_dev}" ]]; then |
| # If the read-only rootfs is not mounted via the kernel using a real block |
| # device and we need to create one here. So far, all the filesystems we |
| # use in the rootfs can be mounted read-only by the kernel (including |
| # squashfs) so we just exit if that's the case. |
| die "Didn't find the rootfs block device device after mounting it." |
| fi |
| |
| # We sign the image with the recovery_key, because this is what goes onto the |
| # USB key. We can only boot from the USB drive in recovery mode. |
| # For dev install shim, we need to use the installer keyblock instead of |
| # the recovery keyblock because of the difference in flags. |
| local keyblock |
| if [[ "${FLAGS_use_dev_keys}" -eq "${FLAGS_TRUE}" ]]; then |
| keyblock=installer_kernel.keyblock |
| info "DEBUG: use dev install keyblock" |
| else |
| keyblock=recovery_kernel.keyblock |
| info "DEBUG: use recovery keyblock" |
| fi |
| |
| if [[ "${FLAGS_force_developer_mode}" -eq "${FLAGS_TRUE}" ]]; then |
| FLAGS_boot_args="${FLAGS_boot_args} cros_debug" |
| fi |
| |
| # Builds the kernel partition image. |
| local partition_num_root_a |
| partition_num_root_a="$(get_layout_partition_number \ |
| "${FLAGS_image_type}" ROOT-A)" |
| local rootfs_fs_size |
| rootfs_fs_size=$(get_filesystem_size "${FLAGS_image_type}" \ |
| "${partition_num_root_a}") |
| |
| # Usually we need to ensure that there will always be a regular kernel on |
| # recovery and non-recovery images. But for factory shim, we need to |
| # support 2 kernels signed with different recovery key. b/269192903 |
| local kern_a_image="vmlinuz.image" |
| build_img "${kern_a_image}" "${root_dev}" "${rootfs_fs_size}" \ |
| "${keyblock}" "recovery_kernel_data_key.vbprivk" "recovery_key.vbpubk" |
| local kern_b_image="vmlinuz_b.image" |
| if [[ "${FLAGS_image_type}" == "factory_install" ]]; then |
| kern_b_image="vmlinuz.image" |
| else |
| build_img "${kern_b_image}" "${root_dev}" "${rootfs_fs_size}" \ |
| "kernel.keyblock" "kernel_data_key.vbprivk" \ |
| "kernel_subkey.vbpubk" "vmlinuz_hd.vblock" |
| fi |
| |
| # Check the size of kernel image and issue warning when image size is |
| # near the limit. |
| local kernel_image_size_A |
| kernel_image_size_A=$(stat -c '%s' "${FLAGS_output_dir}/${kern_a_image}") |
| info "Kernel image A size is ${kernel_image_size_A} bytes." |
| local kernel_image_size_B |
| kernel_image_size_B=$(stat -c '%s' "${FLAGS_output_dir}/${kern_b_image}") |
| info "Kernel image B size is ${kernel_image_size_B} bytes." |
| local partition_num_kern_a |
| partition_num_kern_a="$(get_layout_partition_number \ |
| "${FLAGS_image_type}" KERN-A)" |
| check_kernel_size "${kernel_image_size_A}" "${partition_num_kern_a}" A |
| local partition_num_kern_b |
| partition_num_kern_b="$(get_layout_partition_number \ |
| "${FLAGS_image_type}" KERN-B)" |
| |
| # Since the kernel-b of factory shim is optional, ignore kernel-b if the size |
| # of kernel-b is less than or equal to the default value 1MiB. |
| local need_kern_b="${FLAGS_TRUE}" |
| if [[ "${FLAGS_image_type}" == "factory_install" ]]; then |
| local kernel_partition_size |
| kernel_partition_size=$(get_partition_size "${FLAGS_image_type}" \ |
| "${partition_num_kern_b}") |
| local block_size |
| block_size="$(get_block_size)" |
| if [[ "${kernel_partition_size}" -le "${block_size}" ]]; then |
| need_kern_b="${FLAGS_FALSE}" |
| warn "Kernel partition B is skipped!" |
| fi |
| fi |
| if [[ ${need_kern_b} -eq ${FLAGS_TRUE} ]]; then |
| check_kernel_size "${kernel_image_size_B}" "${partition_num_kern_b}" B |
| fi |
| |
| local rootfs_hash_size |
| rootfs_hash_size=$(stat -c '%s' "${FLAGS_rootfs_hash}") |
| local rootfs_partition_size |
| rootfs_partition_size=$(get_partition_size "${FLAGS_image_type}" \ |
| "${partition_num_root_a}") |
| local rootfs_hash_pad |
| rootfs_hash_pad=$(( rootfs_partition_size - rootfs_fs_size )) |
| info "Appending rootfs.hash (${rootfs_hash_size} bytes) to the root fs" |
| if [[ ${rootfs_hash_size} -gt ${rootfs_hash_pad} ]]; then |
| die "rootfs_partition_size - rootfs_fs_size is less than the needed " \ |
| "rootfs_hash_size (${rootfs_hash_size}), update your disk layout " \ |
| "configuration" |
| fi |
| # Unfortunately, mount_gpt_image uses mount and not losetup to create the |
| # loop devices. This means that they are not the correct size. We have to |
| # write directly to the image to append the hash tree data. |
| local hash_offset |
| hash_offset="$(partoffset "${image}" "${partition_num_root_a}")" |
| hash_offset=$((hash_offset + ("${rootfs_fs_size}" / 512))) |
| sudo dd bs=512 \ |
| seek="${hash_offset}" \ |
| if="${FLAGS_rootfs_hash}" \ |
| of="${image}" \ |
| conv=notrunc \ |
| status=none |
| |
| # Move the verification block needed for the hard disk install to the |
| # stateful partition. Mount stateful fs, copy file, and umount fs. |
| # In original CL: http://codereview.chromium.org/2868044, this was done in |
| # create_base_image(). However, it could break the build if it is a clean |
| # build because vmlinuz_hd.vblock hasn't been created by build_kernel_image.sh |
| # In some builds that don't use vboot to verify the kernel, this file might |
| # not get created as part of the build, so only copy them if they were. |
| if [ -f "${FLAGS_output_dir}/vmlinuz_hd.vblock" ]; then |
| sudo cp "${FLAGS_output_dir}/vmlinuz_hd.vblock" \ |
| "${FLAGS_statefulfs_mountpoint}" |
| fi |
| |
| # Install the kernel to both slots A and B. |
| local koffset |
| koffset="$(partoffset "${image}" "${partition_num_kern_a}")" |
| sudo dd if="${FLAGS_output_dir}/${kern_a_image}" of="${image}" \ |
| conv=notrunc bs=512 seek="${koffset}" status=none |
| if [[ ${need_kern_b} -eq ${FLAGS_TRUE} ]]; then |
| koffset="$(partoffset "${image}" "${partition_num_kern_b}")" |
| sudo dd if="${FLAGS_output_dir}/${kern_b_image}" of="${image}" \ |
| conv=notrunc bs=512 seek="${koffset}" status=none |
| fi |
| |
| # Update the bootloaders. The EFI system partition will be updated. |
| local kernel_part= |
| |
| # We should update the esp in place in the image. |
| local partition_num_efi_system |
| partition_num_efi_system="$(get_layout_partition_number \ |
| "${FLAGS_image_type}" EFI-SYSTEM)" |
| local image_dev |
| image_dev=$(loopback_partscan "${image}") |
| loopback_detach_and_die() { |
| loopback_detach "${image_dev}" |
| unmount_image |
| die "cros_make_image_bootable failed." |
| } |
| trap loopback_detach_and_die EXIT |
| local bootloader_to="${image_dev}" |
| # Make this writable by the user, it will get deleted by losetup -d. |
| sudo chown "$(id -u)" "${bootloader_to}" "${bootloader_to}"p* |
| local esp_size |
| esp_size="$(partsize "${image}" "${partition_num_efi_system}")" |
| esp_size=$((esp_size * 512)) # sectors to bytes |
| |
| if [[ "${FLAGS_arch}" == "x86" || "${FLAGS_arch}" == "amd64" ]]; then |
| # Use the kernel partition to acquire configuration flags. |
| kernel_part=("--kernel_partition='${FLAGS_output_dir}/${kern_a_image}'") |
| # Install syslinux on the EFI System Partition. |
| kernel_part+=(--install_syslinux) |
| elif [[ "${FLAGS_arch}" == "arm64" ]]; then |
| # Use the kernel partition to acquire configuration flags. |
| kernel_part=("--kernel_partition='${FLAGS_output_dir}/${kern_a_image}'") |
| elif [[ "${FLAGS_arch}" == "arm" || "${FLAGS_arch}" == "mips" ]]; then |
| # These flags are not used for ARM / MIPS update_bootloaders.sh |
| kernel_part=() |
| fi |
| |
| # Force all of the file writes to complete, in case it's necessary for |
| # crbug.com/938958 |
| sync |
| |
| if [[ ${esp_size} -gt 0 ]]; then |
| # Update EFI partition |
| "${SCRIPTS_DIR}"/update_bootloaders.sh \ |
| --arch="${FLAGS_arch}" \ |
| --board="${BOARD}" \ |
| --image_type="${FLAGS_image_type}" \ |
| --to="${bootloader_to}" \ |
| --to_partition="${partition_num_efi_system}" \ |
| --from="${FLAGS_rootfs_mountpoint}"/boot \ |
| --vmlinuz="${VMLINUZ}" \ |
| --zimage="${ZIMAGE}" \ |
| "${kernel_part[@]}" |
| fi |
| |
| # We don't need to keep these files around anymore. |
| sudo rm -f "${FLAGS_rootfs_hash}" "${FLAGS_output_dir}/${kern_a_image}" \ |
| "${FLAGS_output_dir}/${kern_b_image}" \ |
| "${FLAGS_output_dir}/vmlinuz_hd.vblock" |
| |
| sudo losetup -d "${image_dev}" |
| unmount_image |
| |
| # Since the kern-b will be signed with another recovery key, need to make |
| # kern-b bootable. |
| # TODO(b/270262345) Remove it after updating GPT flags. |
| if [[ "${FLAGS_image_type}" == "factory_install" \ |
| && ${need_kern_b} -eq ${FLAGS_TRUE} ]] |
| then |
| sudo cgpt add -i "${partition_num_kern_b}" -P 15 -S 1 -T 15 "${IMAGE}" |
| fi |
| trap - EXIT |
| } |
| |
| verify_image_rootfs() { |
| local image=$1 |
| local partition_num_root_a |
| partition_num_root_a="$(get_layout_partition_number \ |
| "${FLAGS_image_type}" ROOT-A)" |
| local rootfs_offset |
| rootfs_offset="$(partoffset "${image}" "${partition_num_root_a}")" |
| |
| local rootfs_tmp_file |
| rootfs_tmp_file=$(mktemp) |
| # Immediately resolve the local variable for the trap. |
| # shellcheck disable=SC2064 |
| trap "rm '${rootfs_tmp_file}'" EXIT |
| sudo dd if="${image}" of="${rootfs_tmp_file}" bs=512 skip="${rootfs_offset}" \ |
| status=none |
| |
| # This flips the read-only compatibility flag, so that |
| # e2fsck does not complain about unknown file system capabilities. |
| enable_rw_mount "${rootfs_tmp_file}" |
| info "Running e2fsck to check root file system for errors" |
| sudo e2fsck -fn "${rootfs_tmp_file}" || |
| die "Root file system has errors, please ensure boot.desc and/or \ |
| command line parameters are correct" |
| } |
| |
| # Store output and temporary files next to image. |
| FLAGS_output_dir="${IMAGE_DIR}" |
| FLAGS_rootfs_hash="${IMAGE_DIR}/rootfs.hash" |
| FLAGS_rootfs_mountpoint="${IMAGE_DIR}/rootfs_dir" |
| FLAGS_statefulfs_mountpoint="${IMAGE_DIR}/stateful_dir" |
| FLAGS_espfs_mountpoint="${IMAGE_DIR}/esp" |
| |
| # Create the directories if they don't exist. |
| mkdir -p "${FLAGS_rootfs_mountpoint}" |
| mkdir -p "${FLAGS_statefulfs_mountpoint}" |
| mkdir -p "${FLAGS_espfs_mountpoint}" |
| |
| # base_image_utils.sh always places the kernel images in |
| # ${IMAGE_DIR}/boot_images. |
| declare -r VMLINUZ="${IMAGE_DIR}/boot_images/vmlinuz" |
| declare -r ZIMAGE="${IMAGE_DIR}/boot_images/zimage" |
| |
| make_image_bootable "${IMAGE}" |
| if type -p board_make_image_bootable; then |
| board_make_image_bootable "${IMAGE}" |
| fi |
| if [[ "${FLAGS_fsck_rootfs}" -eq "${FLAGS_TRUE}" ]]; then |
| verify_image_rootfs "${IMAGE}" |
| fi |
| |
| if [[ "${FLAGS_cleanup_dirs}" -eq "${FLAGS_TRUE}" ]]; then |
| # These paths are already cleaned up by make_image_bootable when unmounting |
| # the image. This is a fallback in case there are errors in that script. |
| for path in ${FLAGS_rootfs_mountpoint} ${FLAGS_statefulfs_mountpoint} \ |
| ${FLAGS_espfs_mountpoint}; do |
| if [[ -d "${path}" ]]; then |
| rmdir "${path}" |
| fi |
| done |
| fi |