mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-19 05:21:23 +02:00
Merge pull request #92 from marineam/images
Lots of image building updates
This commit is contained in:
commit
63713f2eee
@ -95,14 +95,6 @@ DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \
|
||||
"Default all bootloaders to NOT use kernel-based root fs integrity checking."
|
||||
DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \
|
||||
"Default all bootloaders to NOT use bootcache."
|
||||
DEFINE_integer verity_error_behavior 3 \
|
||||
"Kernel verified boot error behavior (0: I/O errors, 1: reboot, 2: nothing)"
|
||||
DEFINE_integer verity_max_ios -1 \
|
||||
"Number of outstanding I/O operations dm-verity caps at."
|
||||
DEFINE_string verity_algorithm "sha1" \
|
||||
"Cryptographic hash algorithm used for kernel vboot."
|
||||
DEFINE_string verity_salt "" \
|
||||
"Salt for rootfs hash tree."
|
||||
|
||||
DEFINE_string keys_dir "/usr/share/vboot/devkeys" \
|
||||
"Directory containing the signing keys."
|
||||
@ -141,15 +133,11 @@ DEFINE_boolean enable_squashfs ${FLAGS_FALSE} \
|
||||
DEFINE_string squash_sort_file "" \
|
||||
"Specify the priority of files when squashing the rootfs."
|
||||
|
||||
DEFINE_string enable_serial "" \
|
||||
"Enable serial port for printks. Example values: ttyS0"
|
||||
|
||||
# Parse the boot.desc and any overrides
|
||||
eval set -- "${BOOT_DESC} ${FLAG_OVERRIDES}"
|
||||
FLAGS "${@}" || exit 1
|
||||
|
||||
[ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt)
|
||||
|
||||
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
|
||||
|
||||
# Only now can we die on error. shflags functions leak non-zero error codes,
|
||||
|
@ -29,10 +29,6 @@ DEFINE_string disk_layout "default" \
|
||||
"The disk layout type to use for this image."
|
||||
DEFINE_boolean standard_backdoor ${FLAGS_TRUE} \
|
||||
"Install standard backdoor credentials for testing"
|
||||
DEFINE_string usb_disk /dev/sdb4 \
|
||||
"Path syslinux should use to do a usb boot. Default: /dev/sdb4"
|
||||
DEFINE_string enable_serial "" \
|
||||
"Enable serial port for printks. Example values: ttyS0"
|
||||
|
||||
# include upload options
|
||||
. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
. "${SRC_ROOT}/platform/dev/toolchain_utils.sh" || exit 1
|
||||
|
||||
# Overlays are parts of the disk that live on the stateful partition
|
||||
# Overlays are parts of the disk that live on the state partition
|
||||
ROOT_OVERLAYS=(var opt srv home usr/local)
|
||||
|
||||
cleanup_mounts() {
|
||||
@ -28,10 +28,15 @@ cleanup_mounts() {
|
||||
|
||||
echo "Cleaning up mounts"
|
||||
safe_umount_tree "${root_fs_dir}"
|
||||
safe_umount_tree "${stateful_fs_dir}"
|
||||
safe_umount_tree "${state_fs_dir}"
|
||||
safe_umount_tree "${esp_fs_dir}"
|
||||
safe_umount_tree "${oem_fs_dir}"
|
||||
|
||||
if [[ -n "${loop_dev}" ]]; then
|
||||
sudo losetup -d "${loop_dev}"
|
||||
loop_dev=
|
||||
fi
|
||||
|
||||
# Turn die on error back on.
|
||||
set -e
|
||||
}
|
||||
@ -40,14 +45,10 @@ create_base_image() {
|
||||
local image_name=$1
|
||||
local rootfs_verification_enabled=$2
|
||||
local bootcache_enabled=$3
|
||||
local image_type="usb"
|
||||
local image_type="base"
|
||||
|
||||
if [[ "${FLAGS_disk_layout}" != "default" ]]; then
|
||||
image_type="${FLAGS_disk_layout}"
|
||||
else
|
||||
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
|
||||
image_type="factory_install"
|
||||
fi
|
||||
fi
|
||||
|
||||
check_valid_layout "base"
|
||||
@ -56,43 +57,40 @@ create_base_image() {
|
||||
info "Using image type ${image_type}"
|
||||
|
||||
root_fs_dir="${BUILD_DIR}/rootfs"
|
||||
stateful_fs_dir="${BUILD_DIR}/stateful"
|
||||
state_fs_dir="${BUILD_DIR}/state"
|
||||
esp_fs_dir="${BUILD_DIR}/esp"
|
||||
oem_fs_dir="${BUILD_DIR}/oem"
|
||||
|
||||
trap "cleanup_mounts && delete_prompt" EXIT
|
||||
cleanup_mounts &> /dev/null
|
||||
|
||||
local root_fs_label="ROOT-A"
|
||||
local root_fs_num=$(get_num ${image_type} ${root_fs_label})
|
||||
local root_fs_img="${BUILD_DIR}/rootfs.image"
|
||||
local root_fs_bytes=$(get_filesystem_size ${image_type} ${root_fs_num})
|
||||
|
||||
local stateful_fs_label="STATE"
|
||||
local stateful_fs_num=$(get_num ${image_type} ${stateful_fs_label})
|
||||
local stateful_fs_img="${BUILD_DIR}/stateful.image"
|
||||
local stateful_fs_bytes=$(get_filesystem_size ${image_type} ${stateful_fs_num})
|
||||
local stateful_fs_uuid=$(uuidgen)
|
||||
|
||||
local esp_fs_label="EFI-SYSTEM"
|
||||
local esp_fs_num=$(get_num ${image_type} ${esp_fs_label})
|
||||
local esp_fs_img="${BUILD_DIR}/esp.image"
|
||||
local esp_fs_bytes=$(get_filesystem_size ${image_type} ${esp_fs_num})
|
||||
|
||||
local oem_fs_label="OEM"
|
||||
local oem_fs_num=$(get_num ${image_type} ${oem_fs_label})
|
||||
local oem_fs_img="${BUILD_DIR}/oem.image"
|
||||
local oem_fs_bytes=$(get_filesystem_size ${image_type} ${oem_fs_num})
|
||||
local oem_fs_uuid=$(uuidgen)
|
||||
write_partition_table "${image_type}" "${BUILD_DIR}/${image_name}"
|
||||
loop_dev=$(sudo losetup -P -f --show "${BUILD_DIR}/${image_name}")
|
||||
|
||||
local fs_block_size=$(get_fs_block_size)
|
||||
|
||||
local root_fs_label="ROOT-A"
|
||||
local root_fs_num=$(get_num ${image_type} ${root_fs_label})
|
||||
local root_fs_dev="${loop_dev}p${root_fs_num}"
|
||||
local root_fs_bytes=$(get_filesystem_size ${image_type} ${root_fs_num})
|
||||
local root_fs_blocks=$((root_fs_bytes / fs_block_size))
|
||||
|
||||
local state_fs_label="STATE"
|
||||
local state_fs_num=$(get_num ${image_type} ${state_fs_label})
|
||||
local state_fs_dev="${loop_dev}p${state_fs_num}"
|
||||
|
||||
local esp_fs_label="EFI-SYSTEM"
|
||||
local esp_fs_num=$(get_num ${image_type} ${esp_fs_label})
|
||||
local esp_fs_dev="${loop_dev}p${esp_fs_num}"
|
||||
|
||||
local oem_fs_label="OEM"
|
||||
local oem_fs_num=$(get_num ${image_type} ${oem_fs_label})
|
||||
local oem_fs_dev="${loop_dev}p${oem_fs_num}"
|
||||
|
||||
# Build root FS image.
|
||||
info "Building ${root_fs_img}"
|
||||
truncate --size="${root_fs_bytes}" "${root_fs_img}"
|
||||
/sbin/mkfs.ext2 -F -q -b ${fs_block_size} "${root_fs_img}" \
|
||||
"$((root_fs_bytes / fs_block_size))"
|
||||
/sbin/tune2fs -L "${root_fs_label}" \
|
||||
info "Building ROOT filesystem"
|
||||
sudo mkfs.ext2 -F -q -b ${fs_block_size} "${root_fs_dev}" "${root_fs_blocks}"
|
||||
sudo tune2fs -L "${root_fs_label}" \
|
||||
-U clear \
|
||||
-T 20091119110000 \
|
||||
-c 0 \
|
||||
@ -100,57 +98,56 @@ create_base_image() {
|
||||
-m 0 \
|
||||
-r 0 \
|
||||
-e remount-ro \
|
||||
"${root_fs_img}"
|
||||
"${root_fs_dev}"
|
||||
mkdir -p "${root_fs_dir}"
|
||||
sudo mount -o loop "${root_fs_img}" "${root_fs_dir}"
|
||||
sudo mount "${root_fs_dev}" "${root_fs_dir}"
|
||||
|
||||
df -h "${root_fs_dir}"
|
||||
|
||||
# Build stateful FS disk image.
|
||||
info "Building ${stateful_fs_img}"
|
||||
truncate --size="${stateful_fs_bytes}" "${stateful_fs_img}"
|
||||
/sbin/mkfs.ext4 -F -q "${stateful_fs_img}"
|
||||
/sbin/tune2fs -L "${stateful_fs_label}" -U "${stateful_fs_uuid}" \
|
||||
-c 0 -i 0 "${stateful_fs_img}"
|
||||
mkdir -p "${stateful_fs_dir}"
|
||||
sudo mount -o loop "${stateful_fs_img}" "${stateful_fs_dir}"
|
||||
# Build state FS disk image.
|
||||
info "Building STATE filesystem"
|
||||
sudo mkfs.ext4 -F -q "${state_fs_dev}"
|
||||
sudo tune2fs -L "${state_fs_label}" \
|
||||
-c 0 \
|
||||
-i 0 \
|
||||
"${state_fs_dev}"
|
||||
mkdir -p "${state_fs_dir}"
|
||||
sudo mount "${state_fs_dev}" "${state_fs_dir}"
|
||||
|
||||
# Build ESP disk image.
|
||||
info "Building ${esp_fs_img}"
|
||||
truncate --size="${esp_fs_bytes}" "${esp_fs_img}"
|
||||
/usr/sbin/mkfs.vfat "${esp_fs_img}"
|
||||
info "Building ESP filesystem"
|
||||
sudo mkfs.vfat "${esp_fs_dev}"
|
||||
|
||||
# Build OEM FS disk image.
|
||||
info "Building ${oem_fs_img}"
|
||||
truncate --size="${oem_fs_bytes}" "${oem_fs_img}"
|
||||
/sbin/mkfs.ext4 -F -q "${oem_fs_img}"
|
||||
/sbin/tune2fs -L "${oem_fs_label}" -U "${oem_fs_uuid}" \
|
||||
-c 0 -i 0 "${oem_fs_img}"
|
||||
info "Building OEM filesystem"
|
||||
sudo mkfs.ext4 -F -q "${oem_fs_dev}"
|
||||
sudo tune2fs -L "${oem_fs_label}" \
|
||||
-c 0 \
|
||||
-i 0 \
|
||||
"${oem_fs_dev}"
|
||||
mkdir -p "${oem_fs_dir}"
|
||||
sudo mount -o loop "${oem_fs_img}" "${oem_fs_dir}"
|
||||
sudo mount "${oem_fs_dev}" "${oem_fs_dir}"
|
||||
|
||||
# Prepare stateful partition with some pre-created directories.
|
||||
# Prepare state partition with some pre-created directories.
|
||||
for i in ${ROOT_OVERLAYS}; do
|
||||
sudo mkdir -p "${stateful_fs_dir}/overlays/$i"
|
||||
sudo mkdir -p "${state_fs_dir}/overlays/$i"
|
||||
sudo mkdir -p "${root_fs_dir}/$i"
|
||||
sudo mount --bind "${stateful_fs_dir}/overlays/$i" "${root_fs_dir}/$i"
|
||||
sudo mount --bind "${state_fs_dir}/overlays/$i" "${root_fs_dir}/$i"
|
||||
done
|
||||
|
||||
sudo mkdir -p "${stateful_fs_dir}/overlays/usr/local"
|
||||
sudo mkdir -p "${state_fs_dir}/overlays/usr/local"
|
||||
|
||||
# Create symlinks so that /usr/local/usr based directories are symlinked to
|
||||
# /usr/local/ directories e.g. /usr/local/usr/bin -> /usr/local/bin, etc.
|
||||
setup_symlinks_on_root "${stateful_fs_dir}/overlays/usr/local" \
|
||||
"${stateful_fs_dir}/overlays/var" \
|
||||
"${stateful_fs_dir}"
|
||||
setup_symlinks_on_root "${state_fs_dir}/overlays/usr/local" \
|
||||
"${state_fs_dir}/overlays/var" \
|
||||
"${state_fs_dir}"
|
||||
|
||||
# Perform binding rather than symlinking because directories must exist
|
||||
# on rootfs so that we can bind at run-time since rootfs is read-only.
|
||||
info "Binding directories from stateful partition onto the rootfs"
|
||||
info "Binding directories from state partition onto the rootfs"
|
||||
|
||||
# Setup the dev image for developer tools
|
||||
sudo mkdir -p "${root_fs_dir}/usr/local"
|
||||
sudo mount --bind "${stateful_fs_dir}/overlays/usr/local" "${root_fs_dir}/usr/local"
|
||||
sudo mount --bind "${state_fs_dir}/overlays/usr/local" "${root_fs_dir}/usr/local"
|
||||
|
||||
# TODO(bp): remove these temporary fixes for /mnt/stateful_partition going moving
|
||||
sudo mkdir -p "${root_fs_dir}/mnt/stateful_partition/"
|
||||
@ -212,10 +209,11 @@ create_base_image() {
|
||||
# trim the image size as much as possible.
|
||||
emerge_to_image --root="${root_fs_dir}" ${BASE_PACKAGE}
|
||||
|
||||
# Record directories installed to the stateful partition.
|
||||
sudo "${SCRIPTS_DIR}/gen_tmpfiles.py" --root="${root_fs_dir}" \
|
||||
# Record directories installed to the state partition.
|
||||
# Ignore /var/tmp, systemd covers this entry.
|
||||
sudo "${BUILD_LIBRARY_DIR}/gen_tmpfiles.py" --root="${root_fs_dir}" \
|
||||
--output="${root_fs_dir}/usr/lib/tmpfiles.d/base_image.conf" \
|
||||
"${root_fs_dir}/var"
|
||||
--ignore=/var/tmp "${root_fs_dir}/var"
|
||||
|
||||
# Set /etc/lsb-release on the image.
|
||||
"${BUILD_LIBRARY_DIR}/set_lsb_release" \
|
||||
@ -227,12 +225,6 @@ create_base_image() {
|
||||
# cros_make_image_bootable.
|
||||
create_boot_desc "${image_type}"
|
||||
|
||||
# Write out the GPT creation script.
|
||||
# This MUST be done before writing bootloader templates else we'll break
|
||||
# the hash on the root FS.
|
||||
write_partition_script "${image_type}" \
|
||||
"${root_fs_dir}/${PARTITION_SCRIPT_PATH}"
|
||||
|
||||
# Populates the root filesystem with legacy bootloader templates
|
||||
# appropriate for the platform. The autoupdater and installer will
|
||||
# use those templates to update the legacy boot partition (12/ESP)
|
||||
@ -268,25 +260,15 @@ create_base_image() {
|
||||
# Clean up symlinks so they work on a running target rooted at "/".
|
||||
# Here development packages are rooted at /usr/local. However, do not
|
||||
# create /usr/local or /var on host (already exist on target).
|
||||
setup_symlinks_on_root "/usr/local" "/var" "${stateful_fs_dir}"
|
||||
setup_symlinks_on_root "/usr/local" "/var" "${state_fs_dir}"
|
||||
|
||||
# Zero all fs free space to make it more compressible so auto-update
|
||||
# payloads become smaller, not fatal since it won't work on linux < 3.2
|
||||
sudo fstrim "${root_fs_dir}" || true
|
||||
sudo fstrim "${stateful_fs_dir}" || true
|
||||
sudo fstrim "${state_fs_dir}" || true
|
||||
|
||||
cleanup_mounts
|
||||
|
||||
# Create the GPT-formatted image.
|
||||
build_gpt "${BUILD_DIR}/${image_name}" \
|
||||
"${root_fs_img}" \
|
||||
"${stateful_fs_img}" \
|
||||
"${esp_fs_img}" \
|
||||
"${oem_fs_img}"
|
||||
|
||||
# Clean up temporary files.
|
||||
rm -f "${root_fs_img}" "${stateful_fs_img}" "${esp_fs_img}" "{oem_fs_img}"
|
||||
|
||||
# Emit helpful scripts for testers, etc.
|
||||
emit_gpt_scripts "${BUILD_DIR}/${image_name}" "${BUILD_DIR}"
|
||||
|
||||
|
@ -104,7 +104,6 @@ create_boot_desc() {
|
||||
enable_bootcache_flag=--enable_bootcache
|
||||
fi
|
||||
|
||||
[ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt)
|
||||
cat <<EOF > ${BUILD_DIR}/boot.desc
|
||||
--board=${BOARD}
|
||||
--image_type=${image_type}
|
||||
@ -112,8 +111,6 @@ create_boot_desc() {
|
||||
--keys_dir="${DEVKEYSDIR}"
|
||||
--boot_args="${FLAGS_boot_args}"
|
||||
--nocleanup_dirs
|
||||
--verity_algorithm=sha1
|
||||
--enable_serial="${FLAGS_enable_serial}"
|
||||
${enable_rootfs_verification_flag}
|
||||
${enable_bootcache_flag}
|
||||
EOF
|
||||
|
@ -3,10 +3,10 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import uuid
|
||||
from optparse import OptionParser
|
||||
@ -93,41 +93,6 @@ def LoadPartitionConfig(filename):
|
||||
return config
|
||||
|
||||
|
||||
def GetTableTotals(config, partitions):
|
||||
"""Calculates total sizes/counts for a partition table.
|
||||
|
||||
Args:
|
||||
config: Partition configuration file object
|
||||
partitions: List of partitions to process
|
||||
Returns:
|
||||
Dict containing totals data
|
||||
"""
|
||||
|
||||
ret = {
|
||||
'expand_count': 0,
|
||||
'expand_min': 0,
|
||||
'block_count': START_SECTOR * config['metadata']['block_size']
|
||||
}
|
||||
|
||||
# Total up the size of all non-expanding partitions to get the minimum
|
||||
# required disk size.
|
||||
for partition in partitions:
|
||||
if 'features' in partition and 'expand' in partition['features']:
|
||||
ret['expand_count'] += 1
|
||||
ret['expand_min'] += partition['blocks']
|
||||
else:
|
||||
ret['block_count'] += partition['blocks']
|
||||
|
||||
# At present, only one expanding partition is permitted.
|
||||
# Whilst it'd be possible to have two, we don't need this yet
|
||||
# and it complicates things, so it's been left out for now.
|
||||
if ret['expand_count'] > 1:
|
||||
raise InvalidLayout('1 expand partition allowed, %d requested'
|
||||
% ret['expand_count'])
|
||||
|
||||
ret['min_disk_size'] = ret['block_count'] + ret['expand_min']
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def GetPartitionTable(options, config, image_type):
|
||||
@ -241,77 +206,72 @@ def GetPartitionTableFromConfig(options, layout_filename, image_type):
|
||||
|
||||
return partitions
|
||||
|
||||
def GetScriptShell():
|
||||
"""Loads and returns the skeleton script for our output script.
|
||||
|
||||
Returns:
|
||||
A string containg the skeleton script
|
||||
"""
|
||||
|
||||
script_shell_path = os.path.join(os.path.dirname(__file__), 'cgpt_shell.sh')
|
||||
with open(script_shell_path, 'r') as f:
|
||||
script_shell = ''.join(f.readlines())
|
||||
|
||||
# Before we return, insert the path to this tool so somebody reading the
|
||||
# script later can tell where it was generated.
|
||||
script_shell = script_shell.replace('@SCRIPT_GENERATOR@', script_shell_path)
|
||||
|
||||
return script_shell
|
||||
|
||||
|
||||
def WriteLayoutFunction(options, sfile, func_name, image_type, config):
|
||||
"""Writes a shell script function to write out a given partition table.
|
||||
def WritePartitionTable(options, image_type, layout_filename, disk_filename):
|
||||
"""Writes the given partition table to a disk image or device.
|
||||
|
||||
Args:
|
||||
options: Flags passed to the script
|
||||
sfile: File handle we're writing to
|
||||
func_name: Function name to write out for specified layout
|
||||
image_type: Type of image eg base/test/dev/factory_install
|
||||
config: Partition configuration file object
|
||||
layout_filename: Path to partition configuration file
|
||||
disk_filename: Path to disk image or device file
|
||||
"""
|
||||
|
||||
def Cgpt(*args):
|
||||
subprocess.check_call(['cgpt'] + [str(a) for a in args])
|
||||
|
||||
config = LoadPartitionConfig(layout_filename)
|
||||
partitions = GetPartitionTable(options, config, image_type)
|
||||
partition_totals = GetTableTotals(config, partitions)
|
||||
disk_block_count = START_SECTOR * config['metadata']['block_size']
|
||||
|
||||
sfile.write('%s() {\ncreate_image $1 %d %s\n' % (
|
||||
func_name, partition_totals['min_disk_size'],
|
||||
config['metadata']['block_size']))
|
||||
|
||||
sfile.write('CURR=%d\n' % START_SECTOR)
|
||||
sfile.write('$GPT create $1\n')
|
||||
|
||||
# Pass 1: Set up the expanding partition size.
|
||||
for partition in partitions:
|
||||
partition['var'] = partition['blocks']
|
||||
disk_block_count += partition['blocks']
|
||||
|
||||
if partition['type'] != 'blank':
|
||||
if partition['num'] == 1:
|
||||
if 'features' in partition and 'expand' in partition['features']:
|
||||
sfile.write('if [ -b $1 ]; then\n')
|
||||
sfile.write('STATEFUL_SIZE=$(( $(numsectors $1) - %d))\n' %
|
||||
partition_totals['block_count'])
|
||||
sfile.write('else\n')
|
||||
sfile.write('STATEFUL_SIZE=%s\n' % partition['blocks'])
|
||||
sfile.write('fi\n')
|
||||
partition['var'] = '$STATEFUL_SIZE'
|
||||
sector = START_SECTOR
|
||||
Cgpt('create', '-c', '-s', disk_block_count, disk_filename)
|
||||
|
||||
sfile.write('STATEFUL_SIZE=$((STATEFUL_SIZE-(STATEFUL_SIZE %% %d)))\n' %
|
||||
config['metadata']['fs_block_size'])
|
||||
|
||||
# Pass 2: Write out all the cgpt add commands.
|
||||
for partition in partitions:
|
||||
if partition['type'] != 'blank':
|
||||
sfile.write('$GPT add -i %d -b $CURR -s %s -t %s -l %s -u %s $1 && ' % (
|
||||
partition['num'], str(partition['var']), partition['type'],
|
||||
partition['label'], partition['uuid']))
|
||||
Cgpt('add', '-i', partition['num'],
|
||||
'-b', sector,
|
||||
'-s', partition['blocks'],
|
||||
'-t', partition['type'],
|
||||
'-l', partition['label'],
|
||||
'-u', partition['uuid'],
|
||||
disk_filename)
|
||||
|
||||
sector += partition['blocks']
|
||||
|
||||
Cgpt('show', disk_filename)
|
||||
|
||||
|
||||
def WriteMbrBoot(options, image_type, layout_filename,
|
||||
disk_filename, mbr_filename):
|
||||
"""Writes the protective MBR with the given boot code.
|
||||
|
||||
The EFI System Partition will be marked as the 'boot' partition.
|
||||
|
||||
Args:
|
||||
options: Flags passed to the script
|
||||
image_type: Type of image eg base/test/dev/factory_install
|
||||
layout_filename: Path to partition configuration file
|
||||
disk_filename: Path to disk image or device file
|
||||
mbr_filename: Path to boot code, usually gptmbr.bin from syslinux.
|
||||
"""
|
||||
|
||||
config = LoadPartitionConfig(layout_filename)
|
||||
partitions = GetPartitionTable(options, config, image_type)
|
||||
|
||||
esp_number = None
|
||||
for partition in partitions:
|
||||
if partition['type'] == 'efi':
|
||||
sfile.write('$GPT boot -p -b $2 -i %d $1\n' % partition['num'])
|
||||
esp_number = partition['num']
|
||||
break
|
||||
if esp_number is None:
|
||||
raise InvalidLayout('Table does not include an EFI partition.')
|
||||
|
||||
# Increment the CURR counter ready for the next partition.
|
||||
sfile.write('CURR=$(( $CURR + %s ))\n' % partition['var'])
|
||||
|
||||
sfile.write('$GPT show $1\n')
|
||||
sfile.write('}\n')
|
||||
subprocess.check_call(['cgpt', 'boot', '-p', '-b', mbr_filename,
|
||||
'-i', str(partition['num']), disk_filename])
|
||||
|
||||
|
||||
def GetPartitionByNumber(partitions, num):
|
||||
@ -350,26 +310,6 @@ def GetPartitionByLabel(partitions, label):
|
||||
raise PartitionNotFound('Partition not found')
|
||||
|
||||
|
||||
def WritePartitionScript(options, image_type, layout_filename, sfilename):
|
||||
"""Writes a shell script with functions for the base and requested layouts.
|
||||
|
||||
Args:
|
||||
options: Flags passed to the script
|
||||
image_type: Type of image eg base/test/dev/factory_install
|
||||
layout_filename: Path to partition configuration file
|
||||
sfilename: Filename to write the finished script to
|
||||
"""
|
||||
|
||||
config = LoadPartitionConfig(layout_filename)
|
||||
|
||||
with open(sfilename, 'w') as f:
|
||||
script_shell = GetScriptShell()
|
||||
f.write(script_shell)
|
||||
|
||||
WriteLayoutFunction(options, f, 'write_base_table', 'base', config)
|
||||
WriteLayoutFunction(options, f, 'write_partition_table', image_type, config)
|
||||
|
||||
|
||||
def GetBlockSize(options, layout_filename):
|
||||
"""Returns the partition table block size.
|
||||
|
||||
@ -549,9 +489,14 @@ def DoParseOnly(options, image_type, layout_filename):
|
||||
|
||||
def main(argv):
|
||||
action_map = {
|
||||
'write': {
|
||||
'usage': ['<image_type>', '<partition_config_file>', '<script_file>'],
|
||||
'func': WritePartitionScript,
|
||||
'write_gpt': {
|
||||
'usage': ['<image_type>', '<partition_config_file>', '<disk_image>'],
|
||||
'func': WritePartitionTable,
|
||||
},
|
||||
'write_mbr': {
|
||||
'usage': ['<image_type>', '<partition_config_file>', '<disk_image>',
|
||||
'<mbr_boot_code>'],
|
||||
'func': WriteMbrBoot,
|
||||
},
|
||||
'readblocksize': {
|
||||
'usage': ['<partition_config_file>'],
|
||||
|
@ -1,38 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2012 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 is automatically generated by @SCRIPT_GENERATOR@
|
||||
# Do not edit!
|
||||
|
||||
if ! type numsectors >/dev/null 2>&1; then
|
||||
if [ -f "/usr/sbin/chromeos-common.sh" ]; then
|
||||
. "/usr/sbin/chromeos-common.sh"
|
||||
else
|
||||
echo "Can't load chromeos-common.sh, dying!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
locate_gpt
|
||||
|
||||
# Usage: create_image <device> <min_disk_size> <block_size>
|
||||
# If <device> is a block device, wipes out the GPT
|
||||
# If it's not, it creates a new file of the requested size
|
||||
create_image() {
|
||||
local dev=$1
|
||||
local min_disk_size=$2
|
||||
local block_size=$3
|
||||
if [ -b "${dev}" ]; then
|
||||
# Zap any old partitions (otherwise gpt complains).
|
||||
dd if=/dev/zero of="${dev}" conv=notrunc bs=512 count=32
|
||||
dd if=/dev/zero of="${dev}" conv=notrunc bs=512 \
|
||||
seek=$((${min_disk_size} - 1 - 33)) count=33
|
||||
else
|
||||
if [ ! -e "${dev}" ]; then
|
||||
dd if=/dev/zero of="${dev}" bs=${block_size} count=1 \
|
||||
seek=$((${min_disk_size} - 1))
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
@ -18,19 +18,12 @@ DEFINE_string arch "x86" \
|
||||
"The boot architecture: arm or x86. (Default: x86)"
|
||||
DEFINE_string to "/tmp/boot" \
|
||||
"Path to populate with bootloader templates (Default: /tmp/boot)"
|
||||
DEFINE_string usb_disk /dev/sdb3 \
|
||||
"Path syslinux should use to do a usb boot. Default: /dev/sdb3"
|
||||
DEFINE_string boot_args "" \
|
||||
"Additional boot arguments to pass to the commandline (Default: '')"
|
||||
DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \
|
||||
"Default all bootloaders to NOT use boot cache."
|
||||
DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \
|
||||
"Controls if verity is used for root filesystem checking (Default: false)"
|
||||
DEFINE_integer verity_error_behavior 3 \
|
||||
"Verified boot error behavior [0: I/O errors, 1: reboot, 2: nothing] \
|
||||
(Default: 3)"
|
||||
DEFINE_integer verity_max_ios -1 \
|
||||
"Optional number of outstanding I/O operations. (Default: 1024)"
|
||||
|
||||
# Parse flags
|
||||
FLAGS "$@" || exit 1
|
||||
|
@ -17,7 +17,7 @@ install_dev_packages() {
|
||||
trap "unmount_image ; delete_prompt" EXIT
|
||||
|
||||
mount_image "${BUILD_DIR}/${image_name}" "${root_fs_dir}" \
|
||||
"${stateful_fs_dir}" "${esp_fs_dir}"
|
||||
"${state_fs_dir}" "${esp_fs_dir}"
|
||||
|
||||
# Determine the root dir for developer packages.
|
||||
local root_dev_dir="${root_fs_dir}/usr/local"
|
||||
@ -90,7 +90,7 @@ EOF
|
||||
|
||||
# Zero all fs free space, not fatal since it won't work on linux < 3.2
|
||||
sudo fstrim "${root_fs_dir}" || true
|
||||
sudo fstrim "${stateful_fs_dir}" || true
|
||||
sudo fstrim "${state_fs_dir}" || true
|
||||
|
||||
info "Developer image built and stored at ${image_name}"
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
CGPT_PY="${BUILD_LIBRARY_DIR}/cgpt.py"
|
||||
PARTITION_SCRIPT_PATH="usr/sbin/write_gpt.sh"
|
||||
|
||||
cgpt_py() {
|
||||
if [[ -n "${FLAGS_adjust_part-}" ]]; then
|
||||
@ -20,7 +19,6 @@ cgpt_py() {
|
||||
|
||||
get_disk_layout_path() {
|
||||
DISK_LAYOUT_PATH="${BUILD_LIBRARY_DIR}/legacy_disk_layout.json"
|
||||
local partition_script_path=$(tempfile)
|
||||
for overlay in $(cros_list_overlays --board "$BOARD"); do
|
||||
local disk_layout="${overlay}/scripts/disk_layout.json"
|
||||
if [[ -e ${disk_layout} ]]; then
|
||||
@ -29,23 +27,9 @@ get_disk_layout_path() {
|
||||
done
|
||||
}
|
||||
|
||||
write_partition_script() {
|
||||
write_partition_table() {
|
||||
local image_type=$1
|
||||
local partition_script_path=$2
|
||||
get_disk_layout_path
|
||||
|
||||
local temp_script_file=$(mktemp)
|
||||
|
||||
sudo mkdir -p "$(dirname "${partition_script_path}")"
|
||||
|
||||
cgpt_py write "${image_type}" "${DISK_LAYOUT_PATH}" \
|
||||
"${temp_script_file}"
|
||||
sudo mv "${temp_script_file}" "${partition_script_path}"
|
||||
}
|
||||
|
||||
run_partition_script() {
|
||||
local outdev=$1
|
||||
local root_fs_img=$2
|
||||
local outdev=$2
|
||||
|
||||
local pmbr_img
|
||||
case ${ARCH} in
|
||||
@ -61,13 +45,10 @@ run_partition_script() {
|
||||
;;
|
||||
esac
|
||||
|
||||
if is_mounted "${root_fs_dir}"; then
|
||||
safe_umount "${root_fs_dir}"
|
||||
fi
|
||||
sudo mount -o loop "${root_fs_img}" "${root_fs_dir}"
|
||||
. "${root_fs_dir}/${PARTITION_SCRIPT_PATH}"
|
||||
write_partition_table "${outdev}" "${pmbr_img}"
|
||||
safe_umount "${root_fs_dir}"
|
||||
get_disk_layout_path
|
||||
cgpt_py write_gpt "${image_type}" "${DISK_LAYOUT_PATH}" "${outdev}"
|
||||
cgpt_py write_mbr \
|
||||
"${image_type}" "${DISK_LAYOUT_PATH}" "${outdev}" "${pmbr_img}"
|
||||
}
|
||||
|
||||
get_fs_block_size() {
|
||||
@ -131,9 +112,6 @@ check_valid_layout() {
|
||||
|
||||
get_disk_layout_type() {
|
||||
DISK_LAYOUT_TYPE="base"
|
||||
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
|
||||
DISK_LAYOUT_TYPE="factory_install"
|
||||
fi
|
||||
}
|
||||
|
||||
emit_gpt_scripts() {
|
||||
@ -204,7 +182,7 @@ build_gpt() {
|
||||
local oem_img="$5"
|
||||
|
||||
get_disk_layout_type
|
||||
run_partition_script "${outdev}" "${rootfs_img}"
|
||||
write_partition_table "${DISK_LAYOUT_TYPE}" "${outdev}"
|
||||
|
||||
local sudo=
|
||||
if [ ! -w "$outdev" ] ; then
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
'''Scan an existing directory tree and record installed directories.
|
||||
|
||||
During build a number of directories under /var are created in the stateful
|
||||
During build a number of directories under /var are created in the state
|
||||
partition. We want to make sure that those are always there so create a record
|
||||
of them using systemd's tempfiles config format so they are recreated during
|
||||
boot if they go missing for any reason.
|
||||
@ -19,6 +19,8 @@ def main():
|
||||
parser = optparse.OptionParser(description=__doc__)
|
||||
parser.add_option('--root', help='Remove root prefix from output')
|
||||
parser.add_option('--output', help='Write output to the given file')
|
||||
parser.add_option('--ignore', action='append', default=[],
|
||||
help='Ignore one or more paths (use multiple times)')
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
if opts.root:
|
||||
@ -56,6 +58,9 @@ def main():
|
||||
else:
|
||||
stripped = path
|
||||
|
||||
if stripped in opts.ignore:
|
||||
continue
|
||||
|
||||
info = os.stat(path)
|
||||
assert stat.S_ISDIR(info.st_mode)
|
||||
mode = stat.S_IMODE(info.st_mode)
|
@ -23,7 +23,7 @@
|
||||
"label":"ROOT-A",
|
||||
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"4194304",
|
||||
"blocks":"2097152",
|
||||
"fs_blocks":"262144"
|
||||
},
|
||||
{
|
||||
@ -31,7 +31,7 @@
|
||||
"label":"ROOT-B",
|
||||
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"4194304",
|
||||
"blocks":"2097152",
|
||||
"fs_blocks":"262144"
|
||||
},
|
||||
{
|
||||
@ -63,73 +63,10 @@
|
||||
"num": 9,
|
||||
"label":"STATE",
|
||||
"type":"data",
|
||||
"blocks":"2097152",
|
||||
"features":["expand"]
|
||||
}
|
||||
],
|
||||
"usb": [
|
||||
{
|
||||
"num": 3,
|
||||
"label":"ROOT-A",
|
||||
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"2539520",
|
||||
"fs_blocks":"262144"
|
||||
},
|
||||
{
|
||||
"num": 4,
|
||||
"label":"ROOT-B",
|
||||
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"1"
|
||||
}
|
||||
],
|
||||
"factory_install": [
|
||||
{
|
||||
"num": 1,
|
||||
"label":"EFI-SYSTEM",
|
||||
"type":"efi",
|
||||
"blocks":"65536"
|
||||
},
|
||||
{
|
||||
"num": 3,
|
||||
"label":"ROOT-A",
|
||||
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"860160",
|
||||
"fs_blocks":"102400"
|
||||
},
|
||||
{
|
||||
"num": 4,
|
||||
"label":"ROOT-B",
|
||||
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"1"
|
||||
},
|
||||
{
|
||||
"num": 9,
|
||||
"label":"STATE",
|
||||
"type":"data",
|
||||
"blocks":"286720"
|
||||
"blocks":"2097152"
|
||||
}
|
||||
],
|
||||
"vm": [
|
||||
{
|
||||
"num": 3,
|
||||
"label":"ROOT-A",
|
||||
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"2097152",
|
||||
"fs_blocks":"262144"
|
||||
},
|
||||
{
|
||||
"num": 4,
|
||||
"label":"ROOT-B",
|
||||
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"2097152",
|
||||
"fs_blocks":"262144"
|
||||
},
|
||||
{
|
||||
"num": 9,
|
||||
"label":"STATE",
|
||||
|
@ -180,14 +180,8 @@ unpack_source_disk() {
|
||||
cp --sparse=always "${alternate_state_image}" "${TEMP_STATE}"
|
||||
fi
|
||||
|
||||
TEMP_PMBR="${VM_TMP_DIR}"/pmbr
|
||||
dd if="${VM_SRC_IMG}" of="${TEMP_PMBR}" bs=512 count=1
|
||||
|
||||
info "Initializing new partition table..."
|
||||
TEMP_PARTITION_SCRIPT="${VM_TMP_DIR}/partition_script.sh"
|
||||
write_partition_script "${disk_layout}" "${TEMP_PARTITION_SCRIPT}"
|
||||
. "${TEMP_PARTITION_SCRIPT}"
|
||||
write_partition_table "${VM_TMP_IMG}" "${TEMP_PMBR}"
|
||||
write_partition_table "${disk_layout}" "${VM_TMP_IMG}"
|
||||
}
|
||||
|
||||
resize_state_partition() {
|
||||
@ -197,10 +191,10 @@ resize_state_partition() {
|
||||
local original_size=$(stat -c%s "${TEMP_STATE}")
|
||||
|
||||
if [[ "${original_size}" -gt "${size_in_bytes}" ]]; then
|
||||
die "Cannot resize stateful image to smaller than original."
|
||||
die "Cannot resize state image to smaller than original."
|
||||
fi
|
||||
|
||||
info "Resizing stateful partition to ${size_in_mb}MB"
|
||||
info "Resizing state partition to ${size_in_mb}MB"
|
||||
/sbin/e2fsck -pf "${TEMP_STATE}"
|
||||
/sbin/resize2fs "${TEMP_STATE}" "${size_in_sectors}s"
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ if [ -z "${FLAGS_board}" ] ; then
|
||||
die_notrace "--board is required."
|
||||
fi
|
||||
|
||||
BOARD="$FLAGS_board"
|
||||
# Loaded after flags are parsed because board_options depends on --board
|
||||
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
|
||||
|
||||
|
||||
IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}"
|
||||
# Default to the most recent image
|
||||
|
@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2010 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 verify integrity of root file system for a GPT-based image
|
||||
|
||||
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
|
||||
. "${SCRIPT_ROOT}/common.sh" || exit 1
|
||||
|
||||
# Load functions and constants for chromeos-install
|
||||
[ -f /usr/lib/installer/chromeos-common.sh ] && \
|
||||
INSTALLER_ROOT=/usr/lib/installer || \
|
||||
INSTALLER_ROOT=$(dirname "$(readlink -f "$0")")
|
||||
|
||||
. "${INSTALLER_ROOT}/chromeos-common.sh" || exit 1
|
||||
|
||||
# Needed for partoffset and partsize calls
|
||||
locate_gpt
|
||||
|
||||
# Script must be run inside the chroot.
|
||||
restart_in_chroot_if_needed "$@"
|
||||
|
||||
DEFINE_string image "" "Device or an image path. Default: (empty)."
|
||||
|
||||
# Parse command line.
|
||||
FLAGS "$@" || exit 1
|
||||
eval set -- "${FLAGS_ARGV}"
|
||||
|
||||
if [ -z $FLAGS_image ] ; then
|
||||
die_notrace "Use --image to specify a device or an image file."
|
||||
fi
|
||||
|
||||
# Turn path into an absolute path.
|
||||
FLAGS_image=$(eval readlink -f ${FLAGS_image})
|
||||
|
||||
# Abort early if we can't find the image
|
||||
if [ ! -b ${FLAGS_image} ] && [ ! -f $FLAGS_image ] ; then
|
||||
die_notrace "No image found at $FLAGS_image"
|
||||
fi
|
||||
|
||||
switch_to_strict_mode
|
||||
|
||||
get_partitions() {
|
||||
if [ -b ${FLAGS_image} ] ; then
|
||||
KERNEL_IMG=$(make_partition_dev "${FLAGS_image}" 2)
|
||||
ROOTFS_IMG=$(make_partition_dev "${FLAGS_image}" 3)
|
||||
return
|
||||
fi
|
||||
|
||||
KERNEL_IMG=$(mktemp)
|
||||
ROOTFS_IMG=$(mktemp)
|
||||
local kernel_offset=$(partoffset "${FLAGS_image}" 2)
|
||||
local kernel_count=$(partsize "${FLAGS_image}" 2)
|
||||
local rootfs_offset=$(partoffset "${FLAGS_image}" 3)
|
||||
local rootfs_count=$(partsize "${FLAGS_image}" 3)
|
||||
|
||||
# TODO(tgao): use loop device to save 1GB in temp space
|
||||
dd if="${FLAGS_image}" of=${KERNEL_IMG} bs=512 skip=${kernel_offset} \
|
||||
count=${kernel_count} &>/dev/null
|
||||
dd if="${FLAGS_image}" of=${ROOTFS_IMG} bs=512 skip=${rootfs_offset} \
|
||||
count=${rootfs_count} &>/dev/null
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
for i in ${KERNEL_IMG} ${ROOTFS_IMG}; do
|
||||
if [ ! -b ${i} ]; then
|
||||
rm -f ${i}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
get_partitions
|
||||
|
||||
# Logic below extracted from src/platform/installer/chromeos-setimage
|
||||
DUMP_KERNEL_CONFIG=/usr/bin/dump_kernel_config
|
||||
KERNEL_CONFIG=$(sudo "${DUMP_KERNEL_CONFIG}" "${KERNEL_IMG}")
|
||||
kernel_cfg="$(echo "${KERNEL_CONFIG}" | sed -e 's/.*dm="\([^"]*\)".*/\1/g' |
|
||||
cut -f2- -d,)"
|
||||
rootfs_sectors=$(echo ${kernel_cfg} | cut -f2 -d' ')
|
||||
verity_algorithm=$(echo ${kernel_cfg} | cut -f8 -d' ')
|
||||
|
||||
# Compute the rootfs hash tree
|
||||
VERITY=/bin/verity
|
||||
# First argument to verity is reserved/unused and MUST be 0
|
||||
table="vroot none ro,"$(sudo "${VERITY}" create 0 \
|
||||
"${verity_algorithm}" \
|
||||
"${ROOTFS_IMG}" \
|
||||
$((rootfs_sectors / 8)) \
|
||||
/dev/null)
|
||||
|
||||
expected_hash=$(echo ${kernel_cfg} | cut -f9 -d' ')
|
||||
generated_hash=$(echo ${table} | cut -f2- -d, | cut -f9 -d' ')
|
||||
|
||||
cleanup
|
||||
|
||||
if [ "${expected_hash}" != "${generated_hash}" ]; then
|
||||
warn "expected hash = ${expected_hash}"
|
||||
warn "actual hash = ${generated_hash}"
|
||||
die_notrace "Root filesystem has been modified unexpectedly!"
|
||||
else
|
||||
info "Root filesystem checksum match!"
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user