diff --git a/bin/cros_make_image_bootable b/bin/cros_make_image_bootable index b9d9df44f8..405a3db053 100755 --- a/bin/cros_make_image_bootable +++ b/bin/cros_make_image_bootable @@ -154,24 +154,6 @@ make_image_bootable() { disable_rw_mount "$root_dev" fi - # We should update the esp in place in the image. - local bootloader_to="${image}" - local esp_offset="$(partoffset ${image} ${NUM_ESP})" - esp_offset=$((esp_offset * 512)) # sectors to bytes - local esp_size="$(partsize ${image} ${NUM_ESP})" - esp_size=$((esp_size * 512)) # sectors to bytes - local bootloader_to_flags="--to_offset=${esp_offset} --to_size=${esp_size}" - - # Update ESP partition - # NOTE: Boot kernel is identical to regular kernel for now - ${SCRIPTS_DIR}/update_bootloaders.sh \ - --arch=${FLAGS_arch} \ - --to="${bootloader_to}" \ - --from="${rootfs_mountpoint}"/boot \ - --vmlinuz_boot_kernel="${rootfs_mountpoint}"/boot/vmlinuz \ - --vmlinuz="${rootfs_mountpoint}"/boot/vmlinuz \ - ${bootloader_to_flags} - trap - EXIT ${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${rootfs_mountpoint}" \ -s "${statefulfs_mountpoint}" diff --git a/build_library/base_image_util.sh b/build_library/base_image_util.sh index 104a88f2fb..1757021b01 100755 --- a/build_library/base_image_util.sh +++ b/build_library/base_image_util.sh @@ -58,7 +58,8 @@ create_base_image() { ${BUILD_LIBRARY_DIR}/create_legacy_bootloader_templates.sh \ --arch=${ARCH} \ - --to="${root_fs_dir}"/boot \ + --boot_dir="${root_fs_dir}"/boot \ + --esp_dir="${root_fs_dir}"/boot/efi \ --boot_args="${FLAGS_boot_args}" # Zero all fs free space to make it more compressible so auto-update diff --git a/build_library/create_legacy_bootloader_templates.sh b/build_library/create_legacy_bootloader_templates.sh index 5fbd6bcb61..d205a374da 100755 --- a/build_library/create_legacy_bootloader_templates.sh +++ b/build_library/create_legacy_bootloader_templates.sh @@ -16,8 +16,10 @@ assert_inside_chroot # Flags. 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 boot_dir "/tmp/boot" \ + "Path to boot directory in root filesystem (Default: /tmp/boot)" +DEFINE_string esp_dir "" \ + "Path to ESP partition mount point (Default: none)" DEFINE_string boot_args "" \ "Additional boot arguments to pass to the commandline (Default: '')" @@ -33,18 +35,15 @@ switch_to_strict_mode common_args="console=tty0 ro noswap cros_legacy" common_args="${common_args} ${FLAGS_boot_args}" -# Populate the x86 rootfs to support legacy and EFI bios config templates. -# The templates are used by the installer to populate partition 12 with -# the correct bootloader configuration. -if [[ "${FLAGS_arch}" = "x86" || "${FLAGS_arch}" = "amd64" ]]; then - sudo mkdir -p ${FLAGS_to} +# Get partition UUIDs from the json config +ROOTA="PARTUUID=$(get_uuid ROOT-A)" +ROOTB="PARTUUID=$(get_uuid ROOT-B)" - # Get partition UUIDs from the json config - ROOTA="PARTUUID=$(get_uuid ROOT-A)" - ROOTB="PARTUUID=$(get_uuid ROOT-B)" +GRUB_DIR="${FLAGS_boot_dir}/grub" +SYSLINUX_DIR="${FLAGS_boot_dir}/syslinux" - # Build configuration files for pygrub/pvgrub - GRUB_DIR="${FLAGS_to}/grub" +# Build configuration files for pygrub/pvgrub +configure_grub() { sudo mkdir -p "${GRUB_DIR}" # Add hvc0 for hypervisors @@ -69,8 +68,10 @@ EOF sudo_append "${GRUB_DIR}/menu.lst.B" <"${GRUB_DIR}/menu.lst.A" info "Emitted ${GRUB_DIR}/menu.lst.B" sudo cp ${GRUB_DIR}/menu.lst.A ${GRUB_DIR}/menu.lst +} - SYSLINUX_DIR="${FLAGS_to}/syslinux" +# Build configuration files for syslinux +configure_syslinux() { sudo mkdir -p "${SYSLINUX_DIR}" # Add ttyS0 as a secondary console, useful for qemu -nographic @@ -119,8 +120,32 @@ label coreos.B append ${syslinux_args} root=${ROOTB} EOF info "Emitted ${SYSLINUX_DIR}/root.B.cfg" +} - exit 0 +# Copy configurations to the ESP, this is what is actually used to boot +copy_to_esp() { + if ! mountpoint -q "${FLAGS_esp_dir}"; then + die "${FLAGS_esp_dir} is not a mount point." + fi + + sudo mkdir -p "${FLAGS_esp_dir}"/{syslinux,boot/grub,EFI/boot} + sudo cp -r "${GRUB_DIR}/." "${FLAGS_esp_dir}/boot/grub" + sudo cp -r "${SYSLINUX_DIR}/." "${FLAGS_esp_dir}/syslinux" + + # Stage all kernels with the only one we built. + for kernel in syslinux/{vmlinuz-boot_kernel,vmlinuz.A,vmlinuz.B} \ + EFI/boot/bootx64.efi + do + sudo cp "${FLAGS_boot_dir}/vmlinuz" "${FLAGS_esp_dir}/${kernel}" + done +} + +if [[ "${FLAGS_arch}" = "x86" || "${FLAGS_arch}" = "amd64" ]]; then + configure_grub + configure_syslinux + if [[ -n "${FLAGS_esp_dir}" ]]; then + copy_to_esp + fi +else + error "No bootloader configuration for ${FLAGS_arch}" fi - -info "The target platform does not use bootloader templates." diff --git a/update_bootloaders.sh b/update_bootloaders.sh deleted file mode 100755 index 41092cfd7a..0000000000 --- a/update_bootloaders.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/bash - -# 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. - -# Helper script that generates the legacy/efi bootloader partitions. -# It does not populate the templates, but can update a loop device. - -SCRIPT_ROOT=$(dirname $(readlink -f "$0")) -. "${SCRIPT_ROOT}/common.sh" || exit 1 - -# Need to be inside the chroot to load chromeos-common.sh -assert_inside_chroot - -# Load functions and constants for chromeos-install -. /usr/lib/installer/chromeos-common.sh || exit 1 - -# Flags. -DEFINE_string arch "x86" \ - "The boot architecture: arm or x86. (Default: x86)" -DEFINE_string from "/tmp/boot" \ - "Path the legacy bootloader templates are copied from. (Default /tmp/boot)" -DEFINE_string to "/tmp/esp.img" \ - "Path to esp image (Default: /tmp/esp.img)" -DEFINE_integer to_offset 0 \ - "Offset in bytes into 'to' if it is a file (Default: 0)" -DEFINE_integer to_size -1 \ - "Size in bytes of 'to' to use if it is a file. -1 is ignored. (Default: -1)" -DEFINE_string vmlinuz "/tmp/vmlinuz" \ - "Path to the vmlinuz file to use (Default: /tmp/vmlinuz)" -DEFINE_string vmlinuz_boot_kernel "/tmp/vmlinuz-boot_kernel" \ - "Path to the vmlinuz-boot_kernel file to use (Default: /tmp/vmlinuz)" - -# Parse flags -FLAGS "$@" || exit 1 -eval set -- "${FLAGS_ARGV}" -switch_to_strict_mode - -part_index_to_uuid() { - local image="$1" - local index="$2" - cgpt show -i "$index" -u "$image" -} - -ESP_DEV= -if [[ ! -e "${FLAGS_to}" ]]; then - error "The ESP doesn't exist" - # This shouldn't happen. - info "Creating a new esp image at ${FLAGS_to}" anyway. - # Create EFI System Partition to boot stock EFI BIOS (but not ChromeOS EFI - # BIOS). ARM uses this space to determine which partition is bootable. - # NOTE: The size argument for mkfs.vfat is in 1024-byte blocks. - # We'll hard-code it to 16M for now. - ESP_BLOCKS=16384 - /usr/sbin/mkfs.vfat -C "${FLAGS_to}" ${ESP_BLOCKS} - ESP_DEV=$(sudo losetup --show -f "${FLAGS_to}") - if [ -z "${ESP_DEV}" ]; then - die "No free loop devices." - fi -else - if [[ -f "${FLAGS_to}" ]]; then - esp_offset="--offset ${FLAGS_to_offset}" - esp_size="--sizelimit ${FLAGS_to_size}" - if [ ${FLAGS_to_size} -lt 0 ]; then - esp_size= - fi - ESP_DEV=$(sudo losetup --show -f ${esp_offset} ${esp_size} "${FLAGS_to}") - if [ -z "${ESP_DEV}" ]; then - die "No free loop devices." - fi - else - # If it is a block device or something else, try to mount it anyway. - ESP_DEV="${FLAGS_to}" - fi -fi - -ESP_FS_DIR=$(mktemp -d /tmp/esp.XXXXXX) -cleanup() { - set +e - if ! safe_umount "${ESP_FS_DIR}"; then - # There is a race condition possible on some ubuntu setups - # with mounting and unmounting a device very quickly - # Doing a quick sleep/retry as a temporary workaround - warn "Initial unmount failed. Possibly crosbug.com/23443. Retrying" - sleep 5 - safe_umount "${ESP_FS_DIR}" - fi - if [[ -n "${ESP_DEV}" && -z "${ESP_DEV//\/dev\/loop*}" ]]; then - sudo losetup -d "${ESP_DEV}" - fi - rm -rf "${ESP_FS_DIR}" -} -trap cleanup EXIT -sudo mount "${ESP_DEV}" "${ESP_FS_DIR}" - -if [[ "${FLAGS_arch}" = "x86" || "${FLAGS_arch}" = "amd64" ]]; then - # Copy over the grub configurations for cloud machines and the - # kernel into both the A and B slot - sudo mkdir -p "${ESP_FS_DIR}"/boot/grub - sudo cp -r "${FLAGS_from}"/grub/. "${ESP_FS_DIR}"/boot/grub - sudo cp -r "${FLAGS_from}"/grub/menu.lst.A "${ESP_FS_DIR}"/boot/grub/menu.lst - - # Prepopulate the syslinux directories too and update for verified boot values - # after the rootfs work is done. - sudo mkdir -p "${ESP_FS_DIR}"/syslinux - sudo cp -r "${FLAGS_from}"/syslinux/. "${ESP_FS_DIR}"/syslinux - - # Stage both kernels with the only one we built. - sudo cp -f "${FLAGS_vmlinuz_boot_kernel}" "${ESP_FS_DIR}"/syslinux/vmlinuz-boot_kernel - sudo cp -f "${FLAGS_vmlinuz}" "${ESP_FS_DIR}"/syslinux/vmlinuz.A - sudo cp -f "${FLAGS_vmlinuz}" "${ESP_FS_DIR}"/syslinux/vmlinuz.B - - # create the EFI directory tree as a fall-back for UEFI builds and put a copy - # of the kernel in there. - sudo mkdir -p "${ESP_FS_DIR}"/EFI/boot - sudo cp -f "${FLAGS_vmlinuz}" "${ESP_FS_DIR}"/EFI/boot/bootx64.efi - - safe_umount "${ESP_FS_DIR}" - sudo syslinux -d /syslinux "${ESP_DEV}" - # mount again for cleanup to free resource gracefully - sudo mount -o ro "${ESP_DEV}" "${ESP_FS_DIR}" -else - die "Unknown arch ${FLAGS_arch}" -fi - -set +e