Building a custom GRUB image feels risky until you realise grub-mkimage only ever writes a file: it does not install a bootloader or touch a disk. This guide builds a standalone x86_64 EFI image, preloads a small set of modules, gives it a prefix for its runtime files, and checks the result is a genuine EFI application.
Allow about 10 minutes. You need Linux with the grub-mkimage command and its platform files installed. These examples use GRUB 2.12-1ubuntu7.3 from Ubuntu's grub-common package. Run the build as an ordinary user in a writable directory, and save elevated privileges for a later, separately planned installation step.
Check the installed version and the formats this copy supports. The format is never inferred from the output filename, so choose it explicitly with --format:
grub-mkimage --version
grub-mkimage --help | sed -n '1,70p'
On the tested machine the first command reports grub-mkimage (GRUB) 2.12-1ubuntu7.3. The local help lists x86_64-efi, i386-efi, BIOS and several other platform formats. Pick the one that matches the firmware or loader that will actually consume the image: an EFI image is not a BIOS image just because both are GRUB images.
Create a destination outside the boot path. This command targets a 64-bit UEFI machine and embeds the normal and linux modules; the prefix tells GRUB where its runtime files, normally including grub.cfg, will be when the image runs:
mkdir -p "$HOME/grub-image-test"
grub-mkimage \
--format=x86_64-efi \
--output="$HOME/grub-image-test/grubx64-test.efi" \
--prefix=/boot/grub \
normal linux
--output is the safe choice here because it names the generated file explicitly. Omit it and the manpage says output defaults to standard output, which is easy to redirect to the wrong place. The trailing module names are positional arguments separated by spaces; do not copy a module list from another platform without checking those files exist in the selected GRUB directory.
Verify the file without running it:
file "$HOME/grub-image-test/grubx64-test.efi"
stat -c '%n %s bytes' "$HOME/grub-image-test/grubx64-test.efi"
Expect file to identify it as a PE32+ executable (EFI application) x86-64 with a non-zero size. The exact byte count varies with the installed modules and package build. If file says the path does not exist, look at the preceding command rather than guessing at a module name.
The prefix is a GRUB path, not necessarily a Linux one. --prefix=/boot/grub tells the generated image where to look for files it loads once its embedded code starts; it does not copy /boot/grub/grub.cfg into the image itself. Set a matching prefix if the image will live in a different layout.
--directory=DIR changes where grub-mkimage reads platform images and modules from. Its default is /usr/lib/grub/<platform>, where <platform> follows from your chosen target. Use it when building from a staged GRUB tree or an explicitly selected module directory:
grub-mkimage \
--directory=/usr/lib/grub/x86_64-efi \
--format=x86_64-efi \
--output="$HOME/grub-image-test/grubx64-test.efi" \
--prefix=/boot/grub \
normal linux
Only use this override when the directory genuinely contains the target's images and modules. A command can succeed and still hand you an unusable boot image if the directory belongs to another platform or release.
Use --config=FILE when a small configuration needs to run before GRUB finds its ordinary one, which suits a controlled test or a layout where the real configuration is not immediately reachable. The file is copied into the image at build time, so changing the source afterwards does nothing to an image already built:
cat > "$HOME/grub-image-test/early.cfg" <<'EOF'
set timeout=0
EOF
grub-mkimage \
--format=x86_64-efi \
--output="$HOME/grub-image-test/grubx64-early-config.efi" \
--prefix=/boot/grub \
--config="$HOME/grub-image-test/early.cfg" \
normal linux
The command should complete silently and create a second non-empty EFI image. Verify both type and size:
file "$HOME/grub-image-test/grubx64-early-config.efi"
stat -c '%n %s bytes' "$HOME/grub-image-test/grubx64-early-config.efi"
Keep the early configuration deliberately small while testing; it is not a substitute for a full, reviewed GRUB configuration. The upstream manual calls this embedded file an early configuration: after it runs, GRUB can load the normal module and read the regular configuration from the prefix.
--compression=xz, --compression=none and --compression=auto choose compression for the core image. Start with the default unless you have a measured reason to change it: a smaller image is not automatically a more compatible one.
--pubkey=FILE embeds a public key for signature checking. Treat that as part of a verified boot design, not a cosmetic option, and confirm which key and policy the target platform expects before relying on the image for boot.
Warning: do not reach for --disable-shim-lock just to silence a boot failure. It disables the shim lock verifier and weakens a security control; investigate the signing, shim and platform trust configuration first. --memdisk=FILE similarly embeds a memdisk and changes the prefix to (memdisk)/boot/grub unless a later prefix option overrides it, which changes the image's runtime layout and needs its own testing.
Replacing an existing EFI file can make a machine unbootable if another boot entry depends on it. Do not point --output at a file under the active EFI System Partition until you have a recovery path, a known-good fallback entry, and a tested copy of the old file. This guide deliberately writes only under $HOME/grub-image-test. Recovery: to undo its state change, remove that test directory after checking its contents:
find "$HOME/grub-image-test" -maxdepth 1 -type f -print
rm -r -- "$HOME/grub-image-test"
rm -r is destructive. Run it only after confirming the printed path is the disposable test directory, not a boot directory.
--prefix=/boot/grub or another prefix matching the image's intended layout. The local binary can reject a build without one even when format and modules are valid.--format against the formats printed by --help. Platform names are exact, underscores and hyphens included.--directory. Do not fix it by copying files from a different GRUB installation.--output path and inspect it with file.grub-mkimage --version identified the installed GRUB release.--help output.file recognises its expected EFI type.