mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-25 07:31:01 +02:00
crosutils: add a script to merge shim-type images
The design of Chromium OS disk image allows trying to boot with multiple partitions. This script can merge images with different kernels (even signed with different keys) into one single image. Useful for factory process which usually needs to deal with DEV/PVT/MP signed shims. BUG=chrome-os-partner:2888 TEST=./merge_shim_image.sh mp.bin pvt.bin # output image works for both PVT/MP devices Change-Id: I21d267bc74fab2d581ccbd0818160407aff35467 Reviewed-on: http://gerrit.chromium.org/gerrit/847 Reviewed-by: Nick Sanders <nsanders@chromium.org> Tested-by: Hung-Te Lin <hungte@chromium.org>
This commit is contained in:
parent
77f27827f1
commit
aceca1c085
165
merge_shim_image.sh
Executable file
165
merge_shim_image.sh
Executable file
@ -0,0 +1,165 @@
|
|||||||
|
#!/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="$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 "$@"
|
Loading…
x
Reference in New Issue
Block a user