blob: 8b302d8a1a4f309ef597c07d2d76d66334889a67 [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script takes a path to a rootfs.ext2 which was generated by
# build_image.sh and generates an image that can be used for auto
# update.
set -e
if [ -z "$2" -o -z "$1" ]; then
echo "usage: $0 path/to/kernel_partition_img path/to/rootfs_partition_img"
exit 1
fi
if [ $(whoami) = "root" ]; then
echo "running $0 as root which is unneccessary"
fi
KPART="$1"
ROOT_PART="$2"
KPART_SIZE=$(stat -c%s "$KPART")
# Sanity check size.
if [ "$KPART_SIZE" -gt $((16 * 1024 * 1024)) ]; then
echo "Kernel partition size ($KPART_SIZE bytes) greater than 16 MiB."
echo "That's too big."
exit 1
fi
FINAL_OUT_FILE=$(dirname "$1")/update.gz
UNCOMPRESSED_OUT_FILE="$FINAL_OUT_FILE.uncompressed"
# First, write size of kernel partition in big endian as uint64 to out file
# printf converts it to a number like 00000000003d0900. sed converts it to:
# \\x00\\x00\\x00\\x00\\x00\\x3d\\x09\\x00, then xargs converts it to binary
# with echo.
printf %016x "$KPART_SIZE" | \
sed 's/\([0-9a-f][0-9a-f]\)/\\\\x\1/g' | \
xargs echo -ne > "$UNCOMPRESSED_OUT_FILE"
# Next, write kernel partition to the out file
cat "$KPART" >> "$UNCOMPRESSED_OUT_FILE"
# Sanity check size of output file now
if [ $(stat -c%s "$UNCOMPRESSED_OUT_FILE") -ne $((8 + $KPART_SIZE)) ]; then
echo "Kernel partition changed size during image generation. Aborting."
exit 1
fi
# Copy rootfs aside
TMP_ROOTFS=$(mktemp)
cp "$ROOT_PART" "$TMP_ROOTFS"
ORIGINAL_LABEL=$(/sbin/e2label "$TMP_ROOTFS")
NEW_LABEL="A${ORIGINAL_LABEL}"
/sbin/tune2fs -L "$NEW_LABEL" "$TMP_ROOTFS"
# TODO(adlr): Sign TMP_ROOTFS w/ OS vendor's private key
# Put rootfs into the out file
cat "$TMP_ROOTFS" >> "$UNCOMPRESSED_OUT_FILE"
rm "$TMP_ROOTFS"
# compress and hash
CS_AND_RET_CODES=$(gzip -c "$UNCOMPRESSED_OUT_FILE" | \
tee "$FINAL_OUT_FILE" | openssl sha1 -binary | \
openssl base64 | tr '\n' ' '; \
echo ${PIPESTATUS[*]})
EXPECTED_RET_CODES="0 0 0 0 0"
set -- $CS_AND_RET_CODES
CALC_CS="$1"
shift
RET_CODES="$@"
if [ "$RET_CODES" != "$EXPECTED_RET_CODES" ]; then
echo compression/hash failed. $RET_CODES
exit 1
fi
rm "$UNCOMPRESSED_OUT_FILE"
echo Success. hash is "$CALC_CS"