#!/usr/bin/env bash # Copyright (C) 2017 Andrew Robbins # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ARCH='arch' CONFIG='config' FONTS='fonts' FONT_FILE='font-file' FONT_PROJECT='font-project' FORMAT='format' MODMIN='modules-minimal' PLATFORM='platform' PREFIX='prefix' SIZE='size' grub_arch() { project_file_contents "${project}" "${CONFIGS}" "${ARCH}" "$@" } grub_font_file() { project_file_contents "${project}" "${CONFIGS}" "${FONT_FILE}" "$@" } grub_font_project() { project_file_contents "${project}" "${CONFIGS}" "${FONT_PROJECT}" "$@" } grub_format() { project_file_contents "${project}" "${CONFIGS}" "${FORMAT}" "$@" } grub_platform() { project_file_contents "${project}" "${CONFIGS}" "${PLATFORM}" "$@" } grub_prefix() { project_file_contents "${project}" "${CONFIGS}" "${PREFIX}" "$@" } grub_size() { project_file_contents "${project}" "${CONFIGS}" "${SIZE}" "$@" } grub_config_path() { project_file_path "${project}" "${CONFIGS}" "${CONFIG}" "$@" } grub_modmin_path() { project_file_path "${project}" "${CONFIGS}" "${MODMIN}" "$@" } grub_copy_modules() { local grub_module_dir="${sources_path}/grub-core" local keep_dir="${build_path}/$(grub_format "${target}" "$@")" mkdir -p "${keep_dir}" cp -a "${grub_module_dir}"/*.@(mod|lst) "${keep_dir}" } grub_build_font() { # Font project-specific filenames and paths local font_file="$(grub_font_file "${FONTS}" "$@")" local font_project="$(grub_font_project "${FONTS}" "$@")" local font_build_dir="${root}/${BUILD}/${font_project}" local grub_mkfont="${sources_path}/grub-mkfont" # GRUB font directory for outputting the built PF2 file mkdir -p "${build_path}/${FONTS}" "${grub_mkfont}" --output="${build_path}/${FONTS}/${font_file%.*}.pf2" \ "${font_build_dir}/${font_file}" } grub_build_utils() { ( # If arch and/or platform files don't exist, # the configure script will pick a reasonable default local arch="$(grub_arch "${target}" "$@")" local platform="$(grub_platform "${target}" "$@")" cd "${sources_path}" || return if git_project_check "${repository}"; then ./autogen.sh fi ./configure --target="${arch}" --with-platform="${platform}" make -j"${TASKS}" ) } grub_build_layout() { local raw_layout="${1##*/}" local raw_layout_path="$1" local keymap_out_path="${build_path}/keymaps" local grub_mklayout="${sources_path}/grub-mklayout" local grub_kbd_layout="${keymap_out_path}/${raw_layout}.gkb" if ! [[ -e "${keymap_out_path}" ]]; then mkdir -p "${keymap_out_path}" elif ! [[ -d "${keymap_out_path}" ]]; then printf '\n%s\n' "Error: File ${keymap_out_path} is not a directory" 1>&2 return 1 fi "${grub_mklayout}" --output="${grub_kbd_layout}" --input="${raw_layout_path}" } grub_build_bootable_image() { local arch="$(grub_arch "${target}" "$@")" local format="$(grub_format "${target}" "$@")" local prefix="$(grub_prefix "${target}" "$@")" local config_path="$(grub_config_path "${target}" "$@")" local grub_mkimage="${sources_path}/grub-mkimage" local grub_module_dir="${sources_path}/grub-core" local grubimg="${build_path}/grub.img" local grub_bootimg="${grub_module_dir}/boot.img" local grub_bootable_img="${build_path}/grub2" "${grub_mkimage}" \ --config="${config_path}" \ --directory="${grub_module_dir}" \ --output="${grubimg}" \ --format="${format}" \ --prefix="${prefix}" \ cbfs configfile cat "${grub_bootimg}" "${grubimg}" > "${grub_bootable_img}" rm -f "${grubimg}" } grub_build_floppy_image() { local grubimg="${build_path}/grub2" local tempfile="${build_path}/temp.file" if ! grub_build_bootable_image "$@"; then printf '\n%s\n\n' "Error: Failed to build a GRUB image" 1>&2 return 1 fi local size="$(grub_size "${target}" "$@")" # Pre-allocate a floppy-sized image # SeaBIOS requires floppy images to have a "correct" size if ! [[ -e "${tempfile}" ]]; then dd if=/dev/zero of="${tempfile}" bs=1024 count="${size:-160}" else printf '\n%s\n\n' "Error: File ${tempfile} already exists!" 1>&2 return 1 fi local -i grubimg_size="$(stat -c %s "${grubimg}")" local -i floppy_size="$((${size:-160} * 1024))" # Graft the GRUB image onto the blank floppy image if ((grubimg_size <= floppy_size)); then dd if="${grubimg}" of="${tempfile}" bs=1 conv=notrunc rm -f "${grubimg}" mv "${tempfile}" "${grubimg}" else printf '\n%s' "Error: Image ${grubimg##*/} is too large; " 1>&2 printf '%s\n\n' "it must be less than ${size}KiB in size" 1>&2 return 1 fi } grub_build_standalone_image() { local arch="$(grub_arch "${target}" "$@")" local format="$(grub_format "${target}" "$@")" local prefix="$(grub_prefix "${target}" "$@")" local config_path="$(grub_config_path "${target}" "$@")" local grubimg="${build_path}/grub2" local grub_mkimage="${sources_path}/grub-mkimage" local grub_mkstandalone="${sources_path}/grub-mkstandalone" local grub_module_dir="${sources_path}/grub-core" "${grub_mkstandalone}" \ --grub-mkimage="${grub_mkimage}" \ --fonts='' \ --themes='' \ --locales='' \ --install-modules='cbfs configfile' \ --directory="${grub_module_dir}" \ --format="${format}" \ --output="${grubimg}" \ /boot/grub/grub.cfg="${config_path}" }