diff options
Diffstat (limited to 'projects/grub/grub-helper')
-rwxr-xr-x | projects/grub/grub-helper | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/projects/grub/grub-helper b/projects/grub/grub-helper new file mode 100755 index 00000000..dd069290 --- /dev/null +++ b/projects/grub/grub-helper @@ -0,0 +1,212 @@ +#!/usr/bin/env bash + +# Copyright (C) 2017 Andrew Robbins <contact@andrewrobbins.info> +# +# 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 <http://www.gnu.org/licenses/>. + +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" +} |