# Red Bear OS — GRUB Boot Manager # # Builds GRUB for the HOST machine (not the Redox target). # GRUB is a build tool that produces standalone EFI binaries. # The resulting grub.efi chainloads the Redox bootloader. # # Output: /usr/lib/boot/grub.efi, /usr/lib/boot/grub.cfg # Required local source: ../grub-redoxfs/src/{redoxfs.c,redoxfs.h,seahash.c} # # Build: make r.grub # Install into image (Phase 1): ./local/scripts/install-grub.sh build/x86_64/harddrive.img # Install into image (Phase 2): make all CONFIG_NAME=redbear-full-grub # # Requires: gcc, make, bison, flex, autoconf, automake on host [source] tar = "https://ftp.gnu.org/gnu/grub/grub-2.12.tar.xz" blake3 = "13c48453f9becf4a6e49618749dc7cb83a2c4a0d7600eeeadc6c7c2772c0b877" [build] template = "custom" script = """ # GRUB must be built for the HOST machine, not the Redox target. # It is a build tool that produces EFI binaries for bare-metal boot. # Override cookbook cross-compilation environment. # Force HOST compiler — cookbook sets CC to Redox cross-compiler. # GRUB is a host build tool, not a Redox binary. unset CC CXX CPP LD AR NM RANLIB OBJCOPY STRIP PKG_CONFIG unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS # Verify host tools are available before starting the build. for tool in gcc make bison flex; do if ! command -v "${tool}" &>/dev/null; then echo "ERROR: Required host tool '${tool}' not found" >&2 exit 1 fi done # We patch Makefile.core.def for local RedoxFS support. Regenerate autotools # files once to avoid version-skew failures in incremental rebuild rules. for tool in autoreconf automake aclocal autoconf; do if ! command -v "${tool}" &>/dev/null; then echo "ERROR: Required host autotools component '${tool}' not found" >&2 exit 1 fi done # Out-of-tree build (GRUB requires this for some configurations) mkdir -p "${COOKBOOK_BUILD}/grub-build" || exit 1 cd "${COOKBOOK_BUILD}/grub-build" || exit 1 # GRUB release tarballs miss extra_deps.lst (normally generated by autogen.sh) touch "${COOKBOOK_SOURCE}/grub-core/extra_deps.lst" || exit 1 # Inject local RedoxFS GRUB module source from sibling tree: ../grub-redoxfs RBOS_ROOT="$(cd "${COOKBOOK_RECIPE}/../../../.." && pwd)" GRUB_REDOXFS_ROOT="${RBOS_ROOT}/../grub-redoxfs" GRUB_REDOXFS_SRC="${GRUB_REDOXFS_ROOT}/src" for f in redoxfs.c redoxfs.h seahash.c; do if [ ! -f "${GRUB_REDOXFS_SRC}/${f}" ]; then echo "ERROR: missing ${GRUB_REDOXFS_SRC}/${f}" >&2 echo "grub-redoxfs source tree must exist at: ${GRUB_REDOXFS_ROOT}" >&2 exit 1 fi done cp "${GRUB_REDOXFS_SRC}/redoxfs.c" "${COOKBOOK_SOURCE}/grub-core/fs/redoxfs.c" cp "${GRUB_REDOXFS_SRC}/seahash.c" "${COOKBOOK_SOURCE}/grub-core/fs/seahash.c" cp "${GRUB_REDOXFS_SRC}/redoxfs.h" "${COOKBOOK_SOURCE}/grub-core/fs/redoxfs.h" mkdir -p "${COOKBOOK_SOURCE}/include/grub" cp "${GRUB_REDOXFS_SRC}/redoxfs.h" "${COOKBOOK_SOURCE}/include/grub/redoxfs.h" echo "Injected GRUB RedoxFS sources from ${GRUB_REDOXFS_SRC}" MAKEFILE_CORE_DEF="${COOKBOOK_SOURCE}/grub-core/Makefile.core.def" if ! grep -q "name = redoxfs;" "${MAKEFILE_CORE_DEF}"; then cat >> "${MAKEFILE_CORE_DEF}" <<'EOF' module = { name = redoxfs; common = fs/redoxfs.c; cflags = '-DGRUB_BUILD'; }; EOF echo "Registered redoxfs module in Makefile.core.def" fi ( cd "${COOKBOOK_SOURCE}" autoreconf -fiv ) # Configure for host, targeting x86_64 EFI platform output. # --target=x86_64 means "produce boot images for x86_64" # --with-platform=efi means "EFI platform output" # We intentionally do NOT set --host (it should be the build machine). echo "Configuring GRUB for x86_64 EFI..." "${COOKBOOK_SOURCE}/configure" \ --target=x86_64 \ --with-platform=efi \ --disable-werror \ --disable-nls \ --disable-grub-mkfont \ --disable-grub-themes \ --disable-grub-mount \ --disable-device-mapper \ --disable-libzfs \ --prefix="${COOKBOOK_STAGE}/usr" || exit 1 echo "Building GRUB..." make -j "${COOKBOOK_MAKE_JOBS}" || exit 1 # Create output directory mkdir -p "${COOKBOOK_STAGE}/usr/lib/boot" # Locate GRUB modules directory. # In an out-of-tree build, modules are in grub-core/ under the build dir. MOD_DIR="" for d in grub-core .; do if [ -f "${d}/part_gpt.mod" ]; then MOD_DIR="${d}" break fi done if [ -z "${MOD_DIR}" ]; then echo "ERROR: Cannot find GRUB modules directory" >&2 echo "Looked in: grub-core/ ." >&2 find . -name "part_gpt.mod" 2>/dev/null || true exit 1 fi echo "Found GRUB modules in: ${MOD_DIR}" # Build standalone EFI image with a broad module set. # -O x86_64-efi: output format # -d MOD_DIR: module search directory # -p /EFI/BOOT: prefix for GRUB config search path # The resulting image is self-contained (no external module files needed). has_mod() { local name="$1" [ -f "${MOD_DIR}/${name}.mod" ] } add_mod() { local name="$1" if has_mod "${name}"; then SELECTED_MODULES+=("${name}") else echo "WARN: GRUB module not found, skipping: ${name}" >&2 fi } # Keep this list broad for first-class multi-filesystem support. # Missing modules are skipped with a warning so builds stay resilient. SELECTED_MODULES=() for m in \ part_gpt part_msdos \ normal configfile search search_fs_uuid search_label \ echo test ls cat halt reboot chain \ fat ext2 btrfs xfs jfs reiserfs udf iso9660 ntfs ntfscomp hfs hfsplus zfs \ gzio xzio lzopio lzma; do add_mod "${m}" done if has_mod "redoxfs"; then SELECTED_MODULES+=("redoxfs") else echo "ERROR: redoxfs.mod was not produced by GRUB build" >&2 echo "Expected at: ${MOD_DIR}/redoxfs.mod" >&2 exit 1 fi if [ "${#SELECTED_MODULES[@]}" -eq 0 ]; then echo "ERROR: No GRUB modules selected for grub-mkimage" >&2 exit 1 fi echo "Creating standalone GRUB EFI image..." ./grub-mkimage \ -O x86_64-efi \ -d "${MOD_DIR}" \ -o "${COOKBOOK_STAGE}/usr/lib/boot/grub.efi" \ -p /EFI/BOOT \ "${SELECTED_MODULES[@]}" || exit 1 # Verify output if [ ! -f "${COOKBOOK_STAGE}/usr/lib/boot/grub.efi" ]; then echo "ERROR: grub.efi was not created" >&2 exit 1 fi GRUB_SIZE=$(stat -c%s "${COOKBOOK_STAGE}/usr/lib/boot/grub.efi" 2>/dev/null || echo "unknown") echo "GRUB EFI image size: ${GRUB_SIZE} bytes" # Copy default GRUB configuration from recipe directory. # grub.cfg lives alongside recipe.toml, not in the extracted source tarball. if [ -f "${COOKBOOK_RECIPE}/grub.cfg" ]; then cp "${COOKBOOK_RECIPE}/grub.cfg" "${COOKBOOK_STAGE}/usr/lib/boot/grub.cfg" echo "Installed grub.cfg" else echo "ERROR: grub.cfg not found in ${COOKBOOK_RECIPE}" >&2 echo "The grub.cfg file must exist alongside recipe.toml." >&2 exit 1 fi echo "GRUB recipe complete." echo "Install with: ./local/scripts/install-grub.sh build/x86_64/harddrive.img" """