1 #!/bin/bash -ex 2 usage () { 3 echo "Create a Mixed Build archive with the given system and device archives." 4 echo 5 echo "Usage: $0 [-v <vendor_version>] [-m <modify_system_image_path>]" 6 echo " [-t <prebuilt_otatools_path>] [-p <override_vbmeta_image_path>]" 7 echo " [-b <override_boot_image_path>]" 8 echo " [-s] system_build_dir device_build_dir out_dir [check_tool]" 9 echo 10 echo "Options -v, -m, -t, -p, -b, -s must precede positional arguments." 11 echo 12 echo "vendor_version is the version of the vendor image when Keymaster v3" 13 echo " related modifications to the system image is necessary. Optional." 14 echo " eg. 8.1.0 for a mixed build of GSI and O-MR1 vendor image." 15 echo "modify_system_image_path is the path to the script that modifies the" 16 echo " system image, needed for Keymaster v3. Optional." 17 echo "prebuilt_otatools_path is the path to otatools.zip file that has all" 18 echo " required host binaries to modify system image. Optional." 19 echo "override_vbmeta_image_path is the path to a vbmeta.img to use" 20 echo " to override the existing vbmeta.img of device. Optional." 21 echo "override_boot_image_path is the path to a boot imgage to use to" 22 echo " override the existing boot.img of device. Optional." 23 echo "-s is used to fetch and flash both product.img and system.img from" 24 echo " the system_build_dir for devices with a product partition." 25 echo " product.img will be removed if system_build_dir does not have" 26 echo " product.img when -s option is declared." 27 echo " By default, only system.img is flashed to the target device for" 28 echo " independent system update. No parameter required. Optional" 29 echo "system_build_dir is the path to the system build" 30 echo " eg. aosp_arm64_ab-userdebug." 31 echo "device_build_dir is the path to the device build" 32 echo " eg. sailfish-user." 33 echo "out_dir is the path to where the new build will be placed." 34 echo "check_tool is the path to the checkvintf executable that will be" 35 echo " used to verify the compatibility of the given images. Optional." 36 } 37 38 # Print error message and exit. 39 # Usage: exit_badparam message 40 # 41 # message is a string to be displayed before exit. 42 exit_badparam () { 43 echo "ERROR: $1" >&2 44 usage 45 exit 1 46 } 47 48 cleanup_and_exit () { 49 readonly result="$?" 50 rm -rf "$TEMP_DIR" 51 exit "$result" 52 } 53 54 trap cleanup_and_exit EXIT 55 56 while getopts :v:m:p:b:t:s opt; do 57 case "$opt" in 58 v) 59 readonly VENDOR_VERSION="$OPTARG" 60 ;; 61 m) 62 readonly MODIFY_SYSTEM_SCRIPT="$OPTARG" 63 ;; 64 p) 65 readonly OVERRIDE_VBMETA_IMAGE_PATH="$OPTARG" 66 ;; 67 b) 68 readonly OVERRIDE_BOOT_IMAGE_PATH="$OPTARG" 69 ;; 70 t) 71 readonly OTATOOLS_ZIP="$OPTARG" 72 ;; 73 s) 74 readonly INCLUDE_PRODUCT=true 75 ;; 76 \?) 77 exit_badparam "Invalid options: -"$OPTARG"" 78 ;; 79 :) 80 exit_badparam "Option -"$OPTARG" requires an argument." 81 ;; 82 esac 83 done 84 85 if [[ -z "${VENDOR_VERSION+x}" && ! -z "${MODIFY_SYSTEM_SCRIPT+x}" ]] || [[ ! -z "${VENDOR_VERSION+x}" && -z "${MODIFY_SYSTEM_SCRIPT+x}" ]]; then 86 exit_badparam "Options -v and -m must be set together." 87 fi 88 89 shift "$((OPTIND-1))" 90 91 if [[ $# -lt 3 ]]; then 92 exit_badparam "Unexpected number of arguments" 93 fi 94 95 readonly SYSTEM_DIR="$1" 96 readonly DEVICE_DIR="$2" 97 readonly DIST_DIR="$3" 98 readonly CHECK_TOOL="$4" 99 readonly TEMP_DIR="$(mktemp -d /tmp/"$(basename $0)"_XXXXXXXX)" 100 101 readonly SYSTEM_TARGET_FILES_ARCHIVE="$(find "$SYSTEM_DIR" -name "*-target_files-*.zip" -print)" 102 if [[ ! -f "$SYSTEM_TARGET_FILES_ARCHIVE" ]]; then 103 exit_badparam "Could not find system target files archive in $SYSTEM_DIR." 104 fi 105 106 readonly DEVICE_ARCHIVE="$(find "$DEVICE_DIR" -name "*-img-*.zip" -print)" 107 if [[ ! -f "$DEVICE_ARCHIVE" ]]; then 108 exit_badparam "Could not find device img archive in $DEVICE_DIR." 109 fi 110 111 readonly DEVICE_TARGET_FILES_ARCHIVE="$(find "$DEVICE_DIR" -name "*-target_files-*.zip" -print)" 112 if [[ ! -f "$DEVICE_TARGET_FILES_ARCHIVE" ]]; then 113 exit_badparam "Could not find device target_files archive in $DEVICE_DIR." 114 fi 115 116 if [[ ! -z "${MODIFY_SYSTEM_SCRIPT+x}" && ! -f "$MODIFY_SYSTEM_SCRIPT" ]]; then 117 exit_badparam "Script not found: "$MODIFY_SYSTEM_SCRIPT"" 118 fi 119 120 if [[ ! -z "${OVERRIDE_VBMETA_IMAGE_PATH+x}" && ! -f "$OVERRIDE_VBMETA_IMAGE_PATH" ]]; then 121 exit_badparam "Specified vbmeta.img not found: "$OVERRIDE_VBMETA_IMAGE_PATH"" 122 fi 123 124 if [[ ! -z "${OVERRIDE_BOOT_IMAGE_PATH+x}" && ! -f "$OVERRIDE_BOOT_IMAGE_PATH" ]]; then 125 exit_badparam "Specified boot image not found: "$OVERRIDE_BOOT_IMAGE_PATH"" 126 fi 127 128 readonly DEVICE_ARTIFACTS_DIR="$TEMP_DIR"/device_archive_artifacts 129 readonly DEVICE_IMAGES_DIR="$DEVICE_ARTIFACTS_DIR"/IMAGES 130 readonly SYSTEM_ARTIFACTS_DIR="$TEMP_DIR"/system_artifacts 131 readonly SYSTEM_IMAGES_DIR="$SYSTEM_ARTIFACTS_DIR"/IMAGES 132 readonly OTATOOLS_DIR="$TEMP_DIR"/otatools 133 134 readonly SPL_PROPERTY_NAME="ro.build.version.security_patch" 135 readonly SYSTEM_BUILD_PROP="SYSTEM/build.prop" 136 137 ### 138 # Uncompress the archives. 139 declare -a EXTRACT_FILE_LIST 140 EXTRACT_FILE_LIST=( 141 IMAGES/system.img \ 142 IMAGES/vbmeta.img \ 143 META/system_matrix.xml \ 144 META/system_manifest.xml \ 145 "$SYSTEM_BUILD_PROP" \ 146 ) 147 148 if [[ "$INCLUDE_PRODUCT" == true ]]; then 149 unzip -l "$SYSTEM_TARGET_FILES_ARCHIVE" | grep -q IMAGES/product.img && 150 EXTRACT_FILE_LIST+=(IMAGES/product.img) 151 fi 152 153 mkdir -p "$SYSTEM_ARTIFACTS_DIR" 154 # Get the system images and meta data. 155 # ${EXTRACT_FILE_LIST[*]} cannot be quoted to list each file for unzipping 156 unzip "$SYSTEM_TARGET_FILES_ARCHIVE" ${EXTRACT_FILE_LIST[*]} -d "$SYSTEM_ARTIFACTS_DIR" 157 158 mkdir -p "$DEVICE_IMAGES_DIR" 159 # Get the device images. 160 unzip "$DEVICE_ARCHIVE" -d "$DEVICE_IMAGES_DIR" 161 # Get the device meta data. 162 unzip "$DEVICE_TARGET_FILES_ARCHIVE" \ 163 META/vendor_matrix.xml META/vendor_manifest.xml "$SYSTEM_BUILD_PROP" \ 164 -d "$DEVICE_ARTIFACTS_DIR" 165 166 if [[ -f "$OTATOOLS_ZIP" ]]; then 167 # Uncompress otatools 168 mkdir -p "$OTATOOLS_DIR" 169 unzip "$OTATOOLS_ZIP" bin/* lib64/* -d "$OTATOOLS_DIR" 170 # Set paths for using prebuilt host binaries. 171 export PATH="$OTATOOLS_DIR"/bin:"$PATH" 172 export LD_LIBRARY_PATH="$OTATOOLS_DIR"/lib64:"$LD_LIBRARY_PATH" 173 fi 174 175 ### 176 # Check compatibility between the system and device. 177 if [[ -f "$CHECK_TOOL" ]]; then 178 chmod 755 "$CHECK_TOOL" 179 "$CHECK_TOOL" \ 180 "$DEVICE_ARTIFACTS_DIR"/META/vendor_manifest.xml \ 181 "$SYSTEM_ARTIFACTS_DIR"/META/system_matrix.xml 182 "$CHECK_TOOL" \ 183 "$SYSTEM_ARTIFACTS_DIR"/META/system_manifest.xml \ 184 "$DEVICE_ARTIFACTS_DIR"/META/vendor_matrix.xml 185 fi 186 187 ### 188 # Modify system.img if vendor version is provided. 189 if [[ ! -z "${VENDOR_VERSION+x}" ]]; then 190 # Create copy of system target files package that can be modified 191 # since the original $SYSTEM_TARGET_FILES_ARCHIVE is a symlink to 192 # prebuilt files in cache 193 cp "$SYSTEM_TARGET_FILES_ARCHIVE" "$TEMP_DIR" 194 readonly COPY_SYSTEM_TARGET_FILES_ARCHIVE="$TEMP_DIR"/"$(basename "$SYSTEM_TARGET_FILES_ARCHIVE")" 195 196 # Check compatibility of security patch level 197 readonly SYSTEM_SPL=$(sed -n -r "s/^"$SPL_PROPERTY_NAME"=(.*)$/\1/p" "$SYSTEM_ARTIFACTS_DIR"/"$SYSTEM_BUILD_PROP") 198 readonly VENDOR_SPL=$(sed -n -r "s/^"$SPL_PROPERTY_NAME"=(.*)$/\1/p" "$DEVICE_ARTIFACTS_DIR"/"$SYSTEM_BUILD_PROP") 199 declare -a args 200 args=(-v "$VENDOR_VERSION" "$COPY_SYSTEM_TARGET_FILES_ARCHIVE") 201 if [[ "$SYSTEM_SPL" != "$VENDOR_SPL" ]]; then 202 echo "Security patch level mismatch detected..." 203 echo " SPL of system: "$SYSTEM_SPL"" 204 echo " SPL of vendor: "$VENDOR_SPL"" 205 args+=("$VENDOR_SPL") 206 fi 207 "$MODIFY_SYSTEM_SCRIPT" "${args[@]}" 208 # Replace system.img with newly modified system.img 209 unzip -o "$COPY_SYSTEM_TARGET_FILES_ARCHIVE" IMAGES/system.img -d "$SYSTEM_ARTIFACTS_DIR" 210 fi 211 212 ### 213 # Overwrite artifacts in the device archive to create the Mixed Build artifacts. 214 cp "$SYSTEM_IMAGES_DIR"/system.img "$DEVICE_IMAGES_DIR"/ 215 if [[ "$INCLUDE_PRODUCT" == true ]]; then 216 if [[ -f "$SYSTEM_IMAGES_DIR"/product.img ]]; then 217 cp "$SYSTEM_IMAGES_DIR"/product.img "$DEVICE_IMAGES_DIR"/ 218 else 219 rm -f "$DEVICE_IMAGES_DIR"/product.img 220 # Removed product partition from required partition list 221 sed -i "/partition-exists=product$/d" "$DEVICE_IMAGES_DIR"/android-info.txt 222 fi 223 fi 224 225 # Only override vbmeta if it is already present since fastboot update will try 226 # to flash whatever is in the archive. 227 if [[ -f "$DEVICE_IMAGES_DIR"/vbmeta.img ]]; then 228 readonly VBMETA_IMAGE_PATH="${OVERRIDE_VBMETA_IMAGE_PATH:-"$SYSTEM_IMAGES_DIR"/vbmeta.img}" 229 cp "$VBMETA_IMAGE_PATH" "$DEVICE_IMAGES_DIR"/ 230 fi 231 232 # Override boot.img with the provided boot image file since fastboot update cmd 233 # will try to flash boot.img in the archive. 234 if [[ ! -z "${OVERRIDE_BOOT_IMAGE_PATH+x}" && -f "$DEVICE_IMAGES_DIR"/boot.img ]]; then 235 cp "$OVERRIDE_BOOT_IMAGE_PATH" "$DEVICE_IMAGES_DIR"/boot.img 236 fi 237 238 ### 239 # Create the Mixed Build archive. 240 ( 241 cd "$DEVICE_IMAGES_DIR" 242 zip -r mixed.zip ./* 243 ) 244 245 ### 246 # Archive the artifacts. 247 if [ -n "$DIST_DIR" ]; then 248 mkdir -p "$DIST_DIR" || true 249 fi 250 # Archive all the device artifacts. 251 rsync --archive --verbose --copy-links --exclude='logs' \ 252 "$DEVICE_DIR"/* "$DIST_DIR" 253 # Overwrite the image archive with the Mixed Build archive. 254 OUT_ARCHIVE="$DIST_DIR"/"$(basename $DEVICE_ARCHIVE)" 255 cp "$DEVICE_IMAGES_DIR"/mixed.zip "$OUT_ARCHIVE" 256 # Overwrite android-info.txt with the updated one. 257 cp "$DEVICE_IMAGES_DIR"/android-info.txt "$DIST_DIR"/ 258