cros_generate_update_payload: Use patched kernel A if kernel B is empty. When generating a delta payload, the source image may not have a normally signed kernel in slot B if it's older. If that's the case, use the kernel in slot A and patch it with the vblock from the stateful partition. BUG=chromium:417072 TEST=Tryjob, manual testing. Change-Id: I047fc331f7bbbc08bb8e6024531d6473bb54aee6 Reviewed-on: https://chromium-review.googlesource.com/219573 Reviewed-by: Gabe Black <gabeblack@chromium.org> Commit-Queue: Gabe Black <gabeblack@chromium.org> Tested-by: Gabe Black <gabeblack@chromium.org>
diff --git a/host/cros_generate_update_payload b/host/cros_generate_update_payload index 5799b3b..5e19b2f 100755 --- a/host/cros_generate_update_payload +++ b/host/cros_generate_update_payload
@@ -260,6 +260,23 @@ echo "Generating $PAYLOAD_TYPE update" +patch_kernel() { + local IMAGE="$1" + local KERN_FILE="$2" + + echo "Patching kernel" $KERN_FILE + echo " into" $IMAGE + # Keep `local` decl split from assignment so return code is checked. + local offset + offset=$(partoffset "${IMAGE}" 1) + : $(( offset *= 512 )) + STATE_MNT=$(mktemp -d --tmpdir="${FLAGS_work_dir}" state.XXXXXX) + sudo mount -o ro,loop,offset=$offset "$IMAGE" "$STATE_MNT" + dd if="$STATE_MNT"/vmlinuz_hd.vblock of="$KERN_FILE" conv=notrunc 2>/dev/null + umount_and_rmdir "$STATE_MNT" + STATE_MNT="" +} + # Sanity check that the real generator exists: GENERATOR="$(which delta_generator)" [ -x "$GENERATOR" ] || die "can't find delta_generator" @@ -269,6 +286,13 @@ if [ "$FLAGS_full_kernel" -eq "$FLAGS_FALSE" ]; then SRC_KERNEL=$(extract_partition_to_temp_file "$FLAGS_src_image" 4 \ "$FLAGS_src_kern_path") + if $(cmp /dev/zero "${SRC_KERNEL}" -n 65536 -s); then + echo "Source kernel B is empty, patching kernel A." + rm -rf "$SRC_KERNEL" + SRC_KERNEL=$(extract_partition_to_temp_file "$FLAGS_src_image" 2 \ + "$FLAGS_src_kern_path") + patch_kernel "$FLAGS_src_image" "$SRC_KERNEL" + fi echo md5sum of src kernel: md5sum "$SRC_KERNEL" else @@ -283,6 +307,13 @@ DST_KERNEL=$(extract_partition_to_temp_file "$FLAGS_image" 4 \ "$FLAGS_kern_path") +if $(cmp /dev/zero "${DST_KERNEL}" -n 65536 -s); then + echo "Destination kernel B is empty, patching kernel A." + rm -rf "$DST_KERNEL" + DST_KERNEL=$(extract_partition_to_temp_file "$FLAGS_image" 2 \ + "$FLAGS_kern_path") + patch_kernel "$FLAGS_image" "$DST_KERNEL" +fi DST_ROOT=$(extract_partition_to_temp_file "$FLAGS_image" 3 \ "$FLAGS_root_path")