mirror of
https://github.com/flatcar/scripts.git
synced 2026-05-05 12:16:41 +02:00
Merge pull request #329 from marineam/grub
Switch to GRUB for both BIOS and UEFI booting
This commit is contained in:
commit
77f164f1a0
@ -204,6 +204,7 @@ finish_image() {
|
||||
local disk_layout="$2"
|
||||
local root_fs_dir="$3"
|
||||
local image_contents="$4"
|
||||
local install_grub=0
|
||||
|
||||
local disk_img="${BUILD_DIR}/${image_name}"
|
||||
|
||||
@ -220,10 +221,10 @@ finish_image() {
|
||||
|
||||
# Only configure bootloaders if there is a boot partition
|
||||
if mountpoint -q "${root_fs_dir}"/boot; then
|
||||
install_grub=1
|
||||
${BUILD_LIBRARY_DIR}/configure_bootloaders.sh \
|
||||
--arch=${ARCH} \
|
||||
--disk_layout="${disk_layout}" \
|
||||
--disk_image="${disk_img}" \
|
||||
--boot_dir="${root_fs_dir}"/usr/boot \
|
||||
--esp_dir="${root_fs_dir}"/boot \
|
||||
--boot_args="${FLAGS_boot_args}"
|
||||
@ -249,4 +250,13 @@ finish_image() {
|
||||
rm -rf "${BUILD_DIR}"/configroot
|
||||
cleanup_mounts "${root_fs_dir}"
|
||||
trap - EXIT
|
||||
|
||||
# This script must mount the ESP partition differently, so run it after unmount
|
||||
if [[ "${install_grub}" -eq 1 ]]; then
|
||||
local target
|
||||
for target in i386-pc x86_64-efi; do
|
||||
${BUILD_LIBRARY_DIR}/grub_install.sh \
|
||||
--target="${target}" --disk_image="${disk_img}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@ DEFINE_string boot_args "" \
|
||||
"Additional boot arguments to pass to the commandline (Default: '')"
|
||||
DEFINE_string disk_layout "base" \
|
||||
"The disk layout type to use for this image."
|
||||
DEFINE_string disk_image "" "The disk image."
|
||||
|
||||
# Parse flags
|
||||
FLAGS "$@" || exit 1
|
||||
@ -52,6 +51,7 @@ SYSLINUX_DIR="${FLAGS_boot_dir}/syslinux"
|
||||
|
||||
# Build configuration files for pygrub/pvgrub
|
||||
configure_pvgrub() {
|
||||
info "Installing legacy PV-GRUB configuration"
|
||||
sudo mkdir -p "${GRUB_DIR}"
|
||||
|
||||
# Add hvc0 for hypervisors
|
||||
@ -68,18 +68,21 @@ title CoreOS B Root
|
||||
root (hd0,0)
|
||||
kernel /syslinux/vmlinuz.B ${grub_args} ${slot_b_args}
|
||||
EOF
|
||||
info "Emitted ${GRUB_DIR}/menu.lst.A"
|
||||
|
||||
sudo_clobber "${GRUB_DIR}/menu.lst.B" <<EOF
|
||||
default 1
|
||||
$(< "${GRUB_DIR}/menu.lst.A")
|
||||
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
|
||||
sudo cp "${GRUB_DIR}/menu.lst.A" "${GRUB_DIR}/menu.lst"
|
||||
|
||||
# menu.lst needs to go under boot/grub so pvgrub can find it reliably
|
||||
sudo mkdir -p "${FLAGS_esp_dir}/boot/grub"
|
||||
sudo cp "${GRUB_DIR}/menu.lst" "${FLAGS_esp_dir}/boot/grub"
|
||||
}
|
||||
|
||||
# Build configuration files for syslinux
|
||||
configure_syslinux() {
|
||||
info "Installing legacy SYSLINUX configuration"
|
||||
sudo mkdir -p "${SYSLINUX_DIR}"
|
||||
|
||||
# Add ttyS0 as a secondary console, useful for qemu -nographic
|
||||
@ -91,7 +94,6 @@ configure_syslinux() {
|
||||
fi
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/syslinux.cfg" <<EOF
|
||||
SERIAL 0 115200
|
||||
PROMPT 1
|
||||
# display boot: prompt for a half second
|
||||
TIMEOUT 5
|
||||
@ -109,22 +111,10 @@ include /syslinux/root.A.cfg
|
||||
# coreos.B
|
||||
include /syslinux/root.B.cfg
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/syslinux.cfg"
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg" <<EOF
|
||||
DEFAULT boot_kernel
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/default.cfg"
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg.A" <<EOF
|
||||
DEFAULT coreos.A
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/default.cfg.A"
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg.B" <<EOF
|
||||
DEFAULT coreos.B
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/default.cfg.B"
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg" <<<"DEFAULT boot_kernel"
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg.A" <<<"DEFAULT coreos.A"
|
||||
sudo_clobber "${SYSLINUX_DIR}/default.cfg.B" <<<"DEFAULT coreos.B"
|
||||
|
||||
# Different files are used so that the updater can only touch the file it
|
||||
# needs to for a given change. This will minimize any potential accidental
|
||||
@ -135,7 +125,6 @@ label boot_kernel
|
||||
kernel vmlinuz-boot_kernel
|
||||
append ${syslinux_args} ${gptprio_args}
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/boot_kernel.cfg"
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/root.A.cfg" <<EOF
|
||||
label coreos.A
|
||||
@ -143,7 +132,6 @@ label coreos.A
|
||||
kernel vmlinuz.A
|
||||
append ${syslinux_args} ${slot_a_args}
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/root.A.cfg"
|
||||
|
||||
sudo_clobber "${SYSLINUX_DIR}/root.B.cfg" <<EOF
|
||||
label coreos.B
|
||||
@ -151,25 +139,9 @@ label coreos.B
|
||||
kernel vmlinuz.B
|
||||
append ${syslinux_args} ${slot_b_args}
|
||||
EOF
|
||||
info "Emitted ${SYSLINUX_DIR}/root.B.cfg"
|
||||
}
|
||||
|
||||
# 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"
|
||||
|
||||
# Install UEFI bootloader
|
||||
sudo cp /usr/share/syslinux/efi64/ldlinux.e64 \
|
||||
"${FLAGS_esp_dir}/EFI/boot/ldlinux.e64"
|
||||
sudo cp /usr/share/syslinux/efi64/syslinux.efi \
|
||||
"${FLAGS_esp_dir}/EFI/boot/bootx64.efi"
|
||||
|
||||
# Stage all kernels with the only one we built.
|
||||
for kernel in syslinux/{vmlinuz-boot_kernel,vmlinuz.A,vmlinuz.B}
|
||||
do
|
||||
@ -177,28 +149,11 @@ copy_to_esp() {
|
||||
done
|
||||
}
|
||||
|
||||
# Install GRUB2 to the disk image
|
||||
install_grub() {
|
||||
# Install under boot/coreos/grub instead of boot/grub to prevent
|
||||
# more recent versions of pygrub that attempt to read grub2 configs
|
||||
# from finding it, pygrub and pvgrub must stick with using menu.lst
|
||||
sudo mkdir -p "${FLAGS_esp_dir}/coreos/grub"
|
||||
sudo grub-install \
|
||||
--target=i386-pc \
|
||||
--modules=part_gpt \
|
||||
--boot-directory="${FLAGS_esp_dir}/coreos" \
|
||||
"${FLAGS_disk_image}"
|
||||
sudo cp "${BUILD_LIBRARY_DIR}/grub.cfg" \
|
||||
"${FLAGS_esp_dir}/coreos/grub/grub.cfg"
|
||||
}
|
||||
|
||||
[[ -d "${FLAGS_esp_dir}" ]] || die_notrace "--esp_dir is required"
|
||||
[[ -f "${FLAGS_disk_image}" ]] || die_notrace "--disk_image is required"
|
||||
|
||||
if [[ "${FLAGS_arch}" = "x86" || "${FLAGS_arch}" = "amd64" ]]; then
|
||||
configure_pvgrub
|
||||
configure_syslinux
|
||||
copy_to_esp
|
||||
else
|
||||
error "No bootloader configuration for ${FLAGS_arch}"
|
||||
fi
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"blocks":"262144",
|
||||
"fs_type":"vfat",
|
||||
"mount":"/boot",
|
||||
"features": ["syslinux"]
|
||||
"features": ["hybrid"]
|
||||
},
|
||||
"2":{
|
||||
"label":"BIOS-BOOT",
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
# Use both default console and ttyS0
|
||||
# Load any and all video drivers.
|
||||
# Required under UEFI to boot Linux with a working console.
|
||||
insmod all_video
|
||||
|
||||
# Use both default text console and ttyS0
|
||||
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
|
||||
terminal_input console serial
|
||||
terminal_output console serial
|
||||
@ -6,4 +10,4 @@ terminal_output console serial
|
||||
# Re-use the existing syslinux configuration
|
||||
echo "Loading SYSLINUX configuration..."
|
||||
insmod syslinuxcfg
|
||||
syslinux_configfile -s /syslinux/syslinux.cfg
|
||||
syslinux_source -s /syslinux/syslinux.cfg
|
||||
|
||||
127
build_library/grub_install.sh
Executable file
127
build_library/grub_install.sh
Executable file
@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2014 The CoreOS Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Replacement script for 'grub-install' which does not detect drives
|
||||
# properly when partitions are mounted via individual loopback devices.
|
||||
|
||||
SCRIPT_ROOT=$(readlink -f $(dirname "$0")/..)
|
||||
. "${SCRIPT_ROOT}/common.sh" || exit 1
|
||||
|
||||
# We're invoked only by build_image, which runs in the chroot
|
||||
assert_inside_chroot
|
||||
|
||||
# Flags.
|
||||
DEFINE_string target "" \
|
||||
"The GRUB target to install such as i386-pc or x86_64-efi"
|
||||
DEFINE_string esp_dir "" \
|
||||
"Path to EFI System partition mount point."
|
||||
DEFINE_string disk_image "" \
|
||||
"The disk image containing the EFI System partition."
|
||||
|
||||
# Parse flags
|
||||
FLAGS "$@" || exit 1
|
||||
eval set -- "${FLAGS_ARGV}"
|
||||
switch_to_strict_mode
|
||||
|
||||
# Our GRUB lives under coreos/grub so new pygrub versions cannot find grub.cfg
|
||||
GRUB_DIR="coreos/grub/${FLAGS_target}"
|
||||
|
||||
# Assumes the ESP is the first partition, GRUB cannot search for it by type.
|
||||
GRUB_PREFIX="(,gpt1)/coreos/grub"
|
||||
|
||||
# Modules required to find and read everything else from ESP
|
||||
CORE_MODULES=( fat part_gpt gzio )
|
||||
|
||||
# Name of the core image, depends on target
|
||||
CORE_NAME=
|
||||
|
||||
case "${FLAGS_target}" in
|
||||
i386-pc)
|
||||
CORE_MODULES+=( biosdisk )
|
||||
CORE_NAME="core.img"
|
||||
;;
|
||||
x86_64-efi)
|
||||
CORE_NAME="core.efi"
|
||||
;;
|
||||
*)
|
||||
die_notrace "Unknown GRUB target ${FLAGS_target}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# In order for grub-setup-bios to properly detect the layout of the disk
|
||||
# image it expects a normal partitioned block device. For most of the build
|
||||
# disk_util maps individual loop devices to each partition in the image so
|
||||
# the kernel can automatically detach the loop devices on unmount. When
|
||||
# using a single loop device with partitions there is no such cleanup.
|
||||
# That's the story of why this script has all this goo for loop and mount.
|
||||
STAGE_DIR=
|
||||
ESP_DIR=
|
||||
LOOP_DEV=
|
||||
|
||||
cleanup() {
|
||||
if [[ -d "${STAGE_DIR}" ]]; then
|
||||
rm -rf "${STAGE_DIR}"
|
||||
fi
|
||||
if [[ -d "${ESP_DIR}" ]]; then
|
||||
if mountpoint -q "${ESP_DIR}"; then
|
||||
sudo umount "${ESP_DIR}"
|
||||
fi
|
||||
rm -rf "${ESP_DIR}"
|
||||
fi
|
||||
if [[ -b "${LOOP_DEV}" ]]; then
|
||||
sudo losetup --detach "${LOOP_DEV}"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
STAGE_DIR=$(mktemp --directory)
|
||||
mkdir -p "${STAGE_DIR}/${GRUB_DIR}"
|
||||
|
||||
info "Compressing modules in ${GRUB_DIR}"
|
||||
for file in "/usr/lib/grub/${FLAGS_target}"/*{.lst,.mod}; do
|
||||
out="${STAGE_DIR}/${GRUB_DIR}/${file##*/}"
|
||||
gzip --best --stdout "${file}" > "${out}"
|
||||
done
|
||||
|
||||
info "Generating ${GRUB_DIR}/${CORE_NAME}"
|
||||
grub-mkimage \
|
||||
--compression=auto \
|
||||
--format "${FLAGS_target}" \
|
||||
--prefix "${GRUB_PREFIX}" \
|
||||
--output "${STAGE_DIR}/${GRUB_DIR}/${CORE_NAME}" \
|
||||
"${CORE_MODULES[@]}"
|
||||
|
||||
info "Installing GRUB ${FLAGS_target} to ${FLAGS_disk_image##*/}"
|
||||
LOOP_DEV=$(sudo losetup --find --show --partscan "${FLAGS_disk_image}")
|
||||
ESP_DIR=$(mktemp --directory)
|
||||
sudo mount -t vfat "${LOOP_DEV}p1" "${ESP_DIR}"
|
||||
sudo cp -r "${STAGE_DIR}/." "${ESP_DIR}/."
|
||||
|
||||
# This script will get called a few times, no need to re-copy grub.cfg
|
||||
if [[ ! -f "${ESP_DIR}/coreos/grub/grub.cfg" ]]; then
|
||||
info "Installing grub.cfg"
|
||||
sudo cp "${BUILD_LIBRARY_DIR}/grub.cfg" "${ESP_DIR}/coreos/grub/grub.cfg"
|
||||
fi
|
||||
|
||||
# Now target specific steps to make the system bootable
|
||||
case "${FLAGS_target}" in
|
||||
i386-pc)
|
||||
info "Installing MBR and the BIOS Boot partition."
|
||||
sudo cp "/usr/lib/grub/i386-pc/boot.img" "${ESP_DIR}/${GRUB_DIR}"
|
||||
sudo grub-bios-setup --device-map=/dev/null \
|
||||
--directory="${ESP_DIR}/${GRUB_DIR}" "${LOOP_DEV}"
|
||||
;;
|
||||
x86_64-efi)
|
||||
info "Installing default x86_64 UEFI bootloader."
|
||||
sudo mkdir -p "${ESP_DIR}/EFI/boot"
|
||||
sudo cp "${STAGE_DIR}/${GRUB_DIR}/${CORE_NAME}" \
|
||||
"${ESP_DIR}/EFI/boot/bootx64.efi"
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanup
|
||||
trap - EXIT
|
||||
command_completed
|
||||
@ -20,7 +20,7 @@ Options:
|
||||
-c FILE Config drive as an iso or fat filesystem image.
|
||||
-a FILE SSH public keys for login access. [~/.ssh/id_{dsa,rsa}.pub]
|
||||
-p PORT The port on localhost to map to the VM's sshd. [2222]
|
||||
-s Safe settings: single simple cpu, ide disks.
|
||||
-s Safe settings: single simple cpu and no KVM.
|
||||
-h this ;-)
|
||||
|
||||
This script is a wrapper around qemu for starting CoreOS virtual machines.
|
||||
@ -131,11 +131,11 @@ fi
|
||||
|
||||
# Start assembling our default command line arguments
|
||||
if [ "${SAFE_ARGS}" -eq 1 ]; then
|
||||
disk_type="ide"
|
||||
# Disable KVM, for testing things like UEFI which don't like it
|
||||
set -- -machine accel=tcg "$@"
|
||||
else
|
||||
disk_type="virtio"
|
||||
# Emulate the host CPU closely in both features and cores.
|
||||
set -- -cpu host -smp "${VM_NCPUS}" "$@"
|
||||
set -- -machine accel=kvm -cpu host -smp "${VM_NCPUS}" "$@"
|
||||
fi
|
||||
|
||||
# ${CONFIG_DRIVE} or ${CONFIG_IMAGE} will be mounted in CoreOS as /media/configdrive
|
||||
@ -146,11 +146,11 @@ if [ -n "${CONFIG_DRIVE}" ]; then
|
||||
fi
|
||||
|
||||
if [ -n "${CONFIG_IMAGE}" ]; then
|
||||
set -- -drive if=${disk_type},file="${CONFIG_IMAGE}" "$@"
|
||||
set -- -drive if=virtio,file="${CONFIG_IMAGE}" "$@"
|
||||
fi
|
||||
|
||||
if [ -n "${VM_IMAGE}" ]; then
|
||||
set -- -drive if=${disk_type},file="${SCRIPT_DIR}/${VM_IMAGE}" "$@"
|
||||
set -- -drive if=virtio,file="${SCRIPT_DIR}/${VM_IMAGE}" "$@"
|
||||
fi
|
||||
|
||||
if [ -n "${VM_KERNEL}" ]; then
|
||||
@ -173,7 +173,6 @@ fi
|
||||
qemu-system-x86_64 \
|
||||
-name "$VM_NAME" \
|
||||
-m ${VM_MEMORY} \
|
||||
-machine accel=kvm:tcg \
|
||||
-net nic,vlan=0,model=virtio \
|
||||
-net user,vlan=0,hostfwd=tcp::"${SSH_PORT}"-:22,hostname="${VM_NAME}" \
|
||||
"$@"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user