mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-11 06:56:58 +02:00
The "merge_shim_image" does not work for recovery shims; and that makes the name confusing. This CL changed its name to a more slef-documenting one, "make_universal_factory_shim.sh". Also updated the comments in script file to describe its real behavior. BUG=chrome-os-partner:2888 TEST=none # no change in code except more comments Change-Id: I965c93b39021935c12e21e14b63ba04fce2f43e6 Reviewed-on: http://gerrit.chromium.org/gerrit/1035 Tested-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Nick Sanders <nsanders@chromium.org>
171 lines
4.7 KiB
Bash
Executable File
171 lines
4.7 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Copyright (c) 2011 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.
|
|
|
|
# Script to generate an universal factory install shim image, by merging
|
|
# multiple images signed by different keys.
|
|
# CAUTION: Recovery shim images are not supported yet because they require the
|
|
# kernel partitions to be laid out in a special way
|
|
|
|
SCRIPT="$0"
|
|
set -e
|
|
|
|
# CGPT Header: PMBR, header, table; sec_table, sec_header
|
|
CGPT_START_SIZE=$((1 + 1 + 32))
|
|
CGPT_END_SIZE=$((32 + 1))
|
|
CGPT_BS="512"
|
|
|
|
STATE_PARTITION="1"
|
|
LEGACY_PARTITIONS="8 9 10 11 12"
|
|
RESERVED_PARTITION="9"
|
|
|
|
die() {
|
|
echo "ERROR: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
# TODO(hungte) support parted if cgpt is not available
|
|
image_get_partition_offset() {
|
|
cgpt show -n -i "$2" -b "$1"
|
|
}
|
|
|
|
image_get_partition_size() {
|
|
cgpt show -n -i "$2" -s "$1"
|
|
}
|
|
|
|
image_get_partition_type() {
|
|
cgpt show -n -i "$2" -t "$1"
|
|
}
|
|
|
|
image_get_partition_label() {
|
|
cgpt show -n -i "$2" -l "$1"
|
|
}
|
|
|
|
image_enable_kernel() {
|
|
cgpt add -P 1 -S 1 -i "$2" "$1"
|
|
}
|
|
|
|
image_copy_partition() {
|
|
local from_image="$1"
|
|
local from_part="$2"
|
|
local to_image="$3"
|
|
local to_part="$4"
|
|
|
|
local from_offset="$(image_get_partition_offset "$from_image" "$from_part")"
|
|
local from_size="$(image_get_partition_size "$from_image" "$from_part")"
|
|
local to_offset="$(image_get_partition_offset "$to_image" "$to_part")"
|
|
local to_size="$(image_get_partition_size "$to_image" "$to_part")"
|
|
|
|
if [ "$from_size" -ne "$to_size" ]; then
|
|
die "Failed to copy partition: $from_image#$from_part -> $to_image#$to_part"
|
|
fi
|
|
|
|
# TODO(hungte) Speed up by increasing bs
|
|
dd if="$from_image" of="$to_image" bs="$CGPT_BS" conv=notrunc \
|
|
count=$from_size skip="$from_offset" seek="$to_offset"
|
|
}
|
|
|
|
images_get_total_size() {
|
|
local image=""
|
|
local total="0"
|
|
local index
|
|
|
|
# copy most partitions from first image
|
|
total="$((total + CGPT_START_SIZE + CGPT_END_SIZE))"
|
|
for index in $STATE_PARTITION $LEGACY_PARTITIONS; do
|
|
total="$((total + $(image_get_partition_size "$1" $index) ))"
|
|
done
|
|
|
|
for image in "$1" "$2" "$3"; do
|
|
if [ -z "$image" ]; then
|
|
total="$((total + $(image_get_partition_size "$1" $RESERVED_PARTITION)))"
|
|
total="$((total + $(image_get_partition_size "$1" $RESERVED_PARTITION)))"
|
|
continue
|
|
fi
|
|
total="$((total + $(image_get_partition_size "$image" 2)))"
|
|
total="$((total + $(image_get_partition_size "$image" 3)))"
|
|
done
|
|
echo "$total"
|
|
}
|
|
|
|
image_append_partition() {
|
|
local from_image="$1"
|
|
local to_image="$2"
|
|
local from_part="$3"
|
|
local last_part="$(cgpt show "$to_image" | grep Label | wc -l)"
|
|
local to_part="$((last_part + 1))"
|
|
echo "image_append_partition: $from_image#$from_part -> $to_image#$to_part"
|
|
|
|
local guid="$(image_get_partition_type "$from_image" "$from_part")"
|
|
local size="$(image_get_partition_size "$from_image" "$from_part")"
|
|
local label="$(image_get_partition_label "$from_image" "$from_part")"
|
|
local offset="$CGPT_START_SIZE"
|
|
|
|
if [ "$last_part" -gt 0 ]; then
|
|
offset="$(( $(image_get_partition_offset "$to_image" "$last_part") +
|
|
$(image_get_partition_size "$to_image" "$last_part") ))"
|
|
fi
|
|
|
|
echo cgpt add "$to_image" -t "$guid" -b "$offset" -s "$size" -l "$label"
|
|
cgpt add "$to_image" -t "$guid" -b "$offset" -s "$size" -l "$label"
|
|
image_copy_partition "$from_image" "$from_part" "$to_image" "$to_part"
|
|
}
|
|
|
|
main() {
|
|
local force=""
|
|
if [ "$1" = "-f" ]; then
|
|
shift
|
|
force="True"
|
|
fi
|
|
if [ "$#" -lt 2 -o "$#" -gt 4 ]; then
|
|
echo "Usage: $SCRIPT [-f] output shim_image_1 [shim_2 [shim_3]]"
|
|
exit 1
|
|
fi
|
|
|
|
local image=""
|
|
local output="$1"
|
|
local main_source="$2"
|
|
local index=""
|
|
local slots="0"
|
|
shift
|
|
|
|
if [ -f "$output" -a -z "$force" ]; then
|
|
die "Output file $output already exists. To overwrite the file, add -f."
|
|
fi
|
|
for image in "$@"; do
|
|
if [ ! -f "$image" ]; then
|
|
die "Cannot find input file $image."
|
|
fi
|
|
done
|
|
|
|
# build output
|
|
local total_size="$(images_get_total_size "$@")"
|
|
# echo "Total size from [$@]: $total_size"
|
|
truncate "$output" -s "$((total_size * CGPT_BS))"
|
|
cgpt create "$output"
|
|
cgpt boot -p "$output"
|
|
|
|
# copy most partitions from first image
|
|
image_append_partition "$main_source" "$output" $STATE_PARTITION
|
|
local kpart=2
|
|
local rootfs_part=3
|
|
for image in "$1" "$2" "$3"; do
|
|
if [ -z "$image" ]; then
|
|
image="$1"
|
|
kpart="$RESERVED_PARTITION"
|
|
rootfs_part="$RESERVED_PARTITION"
|
|
fi
|
|
image_append_partition "$image" "$output" "$kpart"
|
|
image_append_partition "$image" "$output" "$rootfs_part"
|
|
slots="$((slots + 1))"
|
|
image_enable_kernel "$output" "$((slots * 2))"
|
|
done
|
|
for index in $LEGACY_PARTITIONS; do
|
|
image_append_partition "$main_source" "$output" "$index"
|
|
done
|
|
}
|
|
|
|
main "$@"
|