blob: 5bd669f4c368afca1bc39bff7e4385368303917a [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
# --- 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=(/usr/lib/crosutils $(dirname "$(readlink -f "$0")"))
local path
SCRIPT_ROOT=
for path in "${common_paths[@]}"; do
if [ -r "${path}/common.sh" ]; then
SCRIPT_ROOT=${path}
break
fi
done
}
find_common_sh
. "${SCRIPT_ROOT}/common.sh" || { echo "Unable to load common.sh"; exit 1; }
# --- END COMMON.SH BOILERPLATE ---
# Load functions designed for image processing
if ! . "${SCRIPT_ROOT}/lib/cros_image_common.sh"; then
echo "ERROR: Cannot load required library: lib/cros_image_common.sh; Abort."
exit 1
fi
# We need 2-3 non-zero parameters.
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ] || [ -z "$1" ] || [ -z "$2" ]; then
echo "
Usage: $0 kernel_partition_img[:index] rootfs_partition_img[:index] [output_dir]
Input parameters may be either a simple partition image file, or a
disk image file name followed by ':' and target partition index number
If output_dir is omitted, the folder of kernel_partition_img will be
use.
Examples:
$0 part_2 part_3
$0 chromiumos_image.bin:2 part3
$0 chromiumos_image.bin:2 otherimage.bin:3 /tmp/myoutput
"
exit 1
fi
if [ "$CROS_GENERATE_UPDATE_PAYLOAD_CALLED" != "1" ]; then
echo "WARNING:"
echo " This script should only be called from cros_generate_update_payload"
echo " Please run that script with --help to see how to use it."
fi
if ! image_has_command pigz; then
(echo "WARNING:"
echo " Your system does not have pigz (parallel gzip) installed."
echo " COMPRESSING WILL BE VERY SLOW. It is recommended to install pigz"
if image_has_command apt-get; then
echo " by 'sudo apt-get install pigz'."
elif image_has_command emerge; then
echo " by 'sudo emerge pigz'."
fi) >&2
fi
if [ $(whoami) = "root" ]; then
echo "running $0 as root which is unneccessary"
fi
# Usage: load_partition_file VARIABLE_NAME_PREFIX partition_file
# Writes VARIABLE_NAME_PREFIX[, _OFFSE, _SIZE, _SECTORS] by parsing
# partition_file, which can be a simple file or image:partno.
load_partition_file() {
local var_prefix="$1"
local var="$2"
local var_offset=""
local var_size=""
local var_sectors=""
local part_no="${var##*:}"
# test if var is in image:partno format.
if [ "$part_no" != "$var" ]; then
var="${var%:*}"
else
part_no=""
fi
if [ -z "$part_no" ]; then
var_offset=0
var_size="$(stat -c"%s" "$var")" ||
image_die "Invalid file: $var"
var_sectors="$((var_size / 512))"
else
var_offset="$(image_part_offset "$var" "$part_no")" ||
image_die "Cannot retieve offset for partition $var:$part_no"
var_sectors="$(image_part_size "$var" "$part_no")" ||
image_die "Cannot retieve size for partition $var:$part_no"
var_size=$((var_sectors * 512))
fi
# publish the values
eval "${var_prefix}"="$var"
eval "${var_prefix}_OFFSET"="$var_offset"
eval "${var_prefix}_SIZE"="$var_size"
eval "${var_prefix}_SECTORS"="$var_sectors"
}
load_partition_file KPART "$1"
load_partition_file ROOTFS "$2"
# 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
if [ "$#" = "3" ]; then
FINAL_OUT_DIR="$(readlink -f $3)"
else
FINAL_OUT_DIR="$(dirname "$(readlink -f $1)")"
fi
FINAL_OUT_FILE="$FINAL_OUT_DIR/update.gz"
echo "Output: $FINAL_OUT_FILE"
# Update payload format:
# [kernel_size: big-endian uint64][kernel_blob][rootfs_blob]
# Prepare kernel_size by using printf as a number like 00000000003d0900, then
# sed to convert as: \x00\x00\x00\x00\x00\x3d\x09\x00, finally echo -e to
# convert into binary.
KPART_SIZE_SIGNATURE="$(printf "%016x" "$KPART_SIZE" |
sed 's/\([0-9a-f][0-9a-f]\)/\\x\1/g')"
# Build the blob!
CS_AND_RET_CODES="$(
(echo -en "$KPART_SIZE_SIGNATURE"
echo "Compressing kernel..." >&2
image_dump_partial_file "$KPART" "$KPART_OFFSET" "$KPART_SECTORS"
echo "Compressing rootfs..." >&2
image_dump_partial_file "$ROOTFS" "$ROOTFS_OFFSET" "$ROOTFS_SECTORS") |
image_gzip_compress -c -9 |
tee "$FINAL_OUT_FILE" |
openssl sha1 -binary |
openssl base64 |
tr '\n' ' '
echo ${PIPESTATUS[*]})"
EXPECTED_RET_CODES="0 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
echo Success. hash is "$CALC_CS"