diff --git a/build_library/base_image_util.sh b/build_library/base_image_util.sh index d06610a306..00c659ede1 100755 --- a/build_library/base_image_util.sh +++ b/build_library/base_image_util.sh @@ -227,12 +227,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) diff --git a/build_library/cgpt.py b/build_library/cgpt.py index 7bf4d52e65..2176cf258e 100755 --- a/build_library/cgpt.py +++ b/build_library/cgpt.py @@ -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 @@ -206,61 +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) disk_block_count = START_SECTOR * config['metadata']['block_size'] for partition in partitions: disk_block_count += partition['blocks'] - sfile.write('%s() {\ncreate_image $1 %d %s\n' % ( - func_name, disk_block_count, - config['metadata']['block_size'])) - - sfile.write('CURR=%d\n' % START_SECTOR) - sfile.write('$GPT create $1\n') + sector = START_SECTOR + Cgpt('create', '-c', '-s', disk_block_count, disk_filename) 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['blocks']), 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['blocks']) - - 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): @@ -299,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. @@ -498,9 +489,14 @@ def DoParseOnly(options, image_type, layout_filename): def main(argv): action_map = { - 'write': { - 'usage': ['', '', ''], - 'func': WritePartitionScript, + 'write_gpt': { + 'usage': ['', '', ''], + 'func': WritePartitionTable, + }, + 'write_mbr': { + 'usage': ['', '', '', + ''], + 'func': WriteMbrBoot, }, 'readblocksize': { 'usage': [''], diff --git a/build_library/cgpt_shell.sh b/build_library/cgpt_shell.sh deleted file mode 100644 index dedd0542aa..0000000000 --- a/build_library/cgpt_shell.sh +++ /dev/null @@ -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 -# If 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 -} - diff --git a/build_library/disk_layout_util.sh b/build_library/disk_layout_util.sh index 1808603e82..0cb9888eeb 100644 --- a/build_library/disk_layout_util.sh +++ b/build_library/disk_layout_util.sh @@ -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() { @@ -204,7 +185,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 diff --git a/build_library/vm_image_util.sh b/build_library/vm_image_util.sh index f39a6d38d3..b034ae4a37 100644 --- a/build_library/vm_image_util.sh +++ b/build_library/vm_image_util.sh @@ -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() { diff --git a/image_to_vm.sh b/image_to_vm.sh index 3957b626ff..2664257083 100755 --- a/image_to_vm.sh +++ b/image_to_vm.sh @@ -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