# Copyright 2016 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.

# Notes:
# (1) Usage: This script gets used as a "library" from other parts of the
#     build scripts.  Specifically, the board_specific_setup.sh script sources
#     this script as part of the board_make_image_bootable() function.  The
#     "cros_make_image_bootable" script calls the board_make_image_bootable()
#     function.
# (2) In order to install GRUB2 on GPT-partitioned disks, there must be a
#     designated "BIOS boot partition".
#
#     On MBR-only disks, the disk sectors immediately following the MBR are
#     used for storing "stage 2" of GRUB2.  On GPT disks, the sectors
#     immediately after MBR are used up to hold the actual partition table.
#     In such case, a well-known GUID can be used to mark a partition as the
#     BIOS boot partition, which the grub-install command uses to store the
#     second stage of the bootloader.  For more details on BIOS boot partition,
#     see https://en.wikipedia.org/wiki/BIOS_boot_partition.
#
#     The disk layout of Lakitu is inherited from the ChromeOS disk layout,
#     which has a partition 11 for firmware and a partition 12 for legacy
#     bootloader configurations.  Since Lakitu doesn't use a custom firmware,
#     we can reuse partition 11 as the BIOS boot partition without having to
#     change the disk layout.  We continue to use partition 12 for storing
#     bootloader configurations.

IMAGE=
GRUB_DIR="boot/grub"
GRUB_TARGET="i386-pc"
GRUB_MODULES="part_gpt gptpriority test fat ext2 normal boot chain configfile
linux search search_fs_uuid search_label terminal memdisk echo biosdisk serial"

# Use partition #11 (originally meant for firmware RW) as BIOS Boot Partition.
BIOS_PART_NUM="11"
# See https://www.gnu.org/software/grub/manual/html_node/BIOS-installation.html
# for the UUID.
BIOS_PART_UUID="21686148-6449-6E6F-744E-656564454649"

ESP_DIR=""
LOOP_DEV=

cleanup() {
  if [[ -d "${ESP_DIR}" ]]; then
    if mountpoint -q "${ESP_DIR}"; then
      sudo umount "${ESP_DIR}"
    fi
    # ESP_DIR should be empty after the umount, so rmdir should work.
    rmdir "${ESP_DIR}"
  fi

  if [[ -b "${LOOP_DEV}" ]]; then
    sudo losetup --detach "${LOOP_DEV}"
  fi
}

# Installs bootloaderes on the given disk image.
#
# Args:
#   $1: absolute path to the disk image.
bootloader_install() {
  trap cleanup EXIT
  IMAGE="$1"

  info "Installing bootloaders on ${IMAGE}"

  LOOP_DEV="$(sudo losetup --find --show --partscan "${IMAGE}")"

  if ! sudo udevadm settle --timeout=10; then
    warn "Error running 'udevadm settle'"
  fi

  local -r esp_node=${LOOP_DEV}p12
  # Wait till udevd finishes the work.
  for i in {1..10}; do
    info "Probing ${esp_node}"
    if [[ -b "${esp_node}" ]]; then
      break
    fi
    sleep 1
    sudo blockdev --rereadpt "${LOOP_DEV}"
  done
  if [[ ! -b "${esp_node}" ]]; then
    error "EFI partition ${esp_node} not available"
    return 1
  fi

  ESP_DIR="$(mktemp --directory)"
  if ! sudo mount -t vfat "${esp_node}" "${ESP_DIR}"; then
    error "Could not mount EFI partition"
    return 1
  fi

  info "Installing GRUB2 ${GRUB_TARGET} on ${IMAGE}"

  if ! sudo mkdir -p "${ESP_DIR}/${GRUB_DIR}"; then
    error "Could not create dir for grub config"
    return 1
  fi

  if [[ ! -f ${ESP_DIR}/efi/boot/grub.cfg ]]; then
    error "Could not find grub.cfg from EFI installation."
    return 1
  fi

  if ! sudo sed -i -e 's|/sbin/init|/usr/lib/systemd/systemd|' \
                -e '/^set timeout=/s|=.*|=0|' \
                "${ESP_DIR}/efi/boot/grub.cfg"; then
    error "Failed to update grub configuration file."
    return 1
  fi

  # Create a minimal grub.cfg that sets up environment variables and loads the
  # configuration from EFI installation.
  cat <<EOF | sudo dd of="${ESP_DIR}/${GRUB_DIR}/grub.cfg" 2>/dev/null
# The configuration relies on |grubdisk| environment variable to find the GPT
# disk.  When booting with EFI, the efidisk module exports the env var.  In case
# of BIOS, we need to hard-code it and export.
set grubdisk=hd0
export grubdisk
configfile /efi/boot/grub.cfg
EOF

  # Mark the firmware partition as the BIOS boot partition.
  # Note that this must be done prior to running grub-install, or else the
  # grub-install command will fail.
  info "Setting BIOS boot partition ..."
  if ! sudo cgpt add -i "${BIOS_PART_NUM}" \
                     -t "${BIOS_PART_UUID}" "${LOOP_DEV}"; then
    error "Error running cgpt"
    return 1
  fi

  info "Running grub-install ..."
  if ! sudo grub-install --target="${GRUB_TARGET}" \
          --boot-directory="${ESP_DIR}/boot" \
          --modules="${GRUB_MODULES}" \
          "${LOOP_DEV}"; then
    error "Error running grub-install"
    return 1
  fi

  info "Successfully installed GRUB2 ${GRUB_TARGET} on ${IMAGE}"

  info "Setting up UEFI booting on ${IMAGE}"
  # Directory for GSetup data.
  sudo mkdir -p "${ESP_DIR}/EFI/Google/GSetup"
  # Boot sequence.
  echo "\\efi\\boot\\shimx64.efi" | \
      sudo tee "${ESP_DIR}/EFI/Google/GSetup/Boot" > /dev/null
  info "Successfully set up UEFI booting on ${IMAGE}"

  cleanup
  trap - EXIT
  info "Successfully installed bootloaders on ${IMAGE}"
}
