trusty-boot-key

· Codeberg.org

20 min read Original article ↗

"Submitted for your approval, a Trusty Boot Key—with all GPL¹ code…"—Rod Serling

Need a "trusty boot key" to load operating systems? A USB flash-drive for troubleshooting and experimentation? Read on.

Once installed, you'll have a trusty drive, where you can download operating system images (usually in .iso format), bootable utilities (memtest86, EFI shell, etc), and carry them around conveniently on a keychain thumb drive, ready for any situation. All available to load from a nifty menu. No need to obliterate a complete drive for each .iso file!

What does it look like? (See Themes section below for customization.)

GRUB Theme Preview  GRUB Theme Preview SlazeGRUB Theme Preview GalaxyGRUB Theme Preview Stones

[1] If you're one of those folks that worries about the GPL—no need. This is an application and does not effect other projects.

Rationale

We were quite impressed with the ease of use of Ventoy, but dismayed by its security posture, especially in light of the not-so recent xz backdoor fiasco. No bad news as of yet, but its hard to imagine a better way to install low-level malware across the globe. :-/

While looking around for a "Safe-Toy" alternative, we found a number of projects attempting to bring comparable ease of use to a GRUB multi-boot system on a similar removable drive.

But the projects were hard to grok. Complicated menus, clunky, redundant code, abandoned/archived repos, and tons of info about BIOS this, MBR, GRUB .96, and 16-bit that…

Huh, what is this 1996?  That's a list of tech already hitting limits during the Clinton Administration, haha.

Support

  • UEFI (firmware)
  • GPT partition table
  • amd64 architecture

That's it. A.k.a. a modern P.C.

Details

To simplify development and docs we've removed everything related to ancient BIOS, MBR, and <= 32-bit architectures. Yes—it's been about twenty years since we had one of those in the house. There's still a late 2013 MBP running acceptably here, with UEFI and 64-bit support, currently pushing thirteen years old.

If you're a vintage computing enthusiast on a souped-up 486/DX9, fine—this project isn't for you. Otherwise, there are likely free computers offered thru your local craigstlist meeting the ~2010 specs listed above, sometimes even left on a sidewalk or trash-bins in larger cities. If you're willing to spend upwards of perhaps… ~$250? One could probably find something more formidable from the last decade.

ARM, R-V?

While it's possible we could support ARM64 or even RISC-V systems in the future, there are none of those laying around handy at the moment. Oh wait, there is an RPi 4 in a drawer nearby… Unsure how to get started on that however, and there's still a lot to do.

Operating Systems

Everything Linux seems to work, although on older images you may have to write some kernel parameters into a support file. We've done that work for loopback.cfg-compatibles and a few very popular other distros, but will need your help for the more obscure ones. See contributing below.

Windows, BSD?

These aren't able to work from a .iso loopback device. Some folks say that creating a partition and unpacking the .iso there works.

Update: Tried Windows 10 and the installer starts up, although with an error. See the customization section later on.

How does it work?


First, we'll help you create a removable drive with a layout like so:
╭───────┬──────────────────╮
│  ESP  │  Data Zone --->  │
╰───────┴──────────────────╯

What you see above is a disk diagram, cut in two (or more) parts. (Well, a unit of storage perhaps—they don't look like frisbees internally any longer.)

We can divide a storage device into sections according to function, each optimized for its needs. In this situation each section is called a "partition," and nearly always contains a "file-system" to catalog the files. These different filesystems have tradeoffs of their own, typically relating to both functionality and compatibility.

The first partition above is the "E.S.P.," a recursive acronym that expands to the "E.F.I" System Partition standard. It uses the venerable and simplistic FAT filesystem, that just about any operating system since the 80s can read. This is a standard for boot partitions that gives much more flexibility than the old-fashioned boot sector.

We'll help you create the partitions and install "GRUB" up in there. That is GNU GRUB, a slender operating system masquerading as a boot loader. Interesting in that we thought we done with it, moving several desktops to systemd-boot in recent years. UEFI machines generally don't need all that functionality any more, it comes standard. But the flexibility of ol' grub here is of great benefit to mounting and running .iso files for a "trusty boot key."

"High-way to the data zone…"

The second partition should be much larger and where you're gonna drop those phat eye-soes or "boot images", in other words. These might load a number of operating systems temporarily as well as for permanent installation. Supported binaries (think memtest86) and .efi files should work as well.

Currently, we are using the ext4 filesystem for the data partition. This is a tough one to decide on, as each of the main choices has significant drawbacks:

  • FAT32 - most compatible, but no files larger than 4GB, ruling out many .iso files.

  • Exfat - very compatible, though the Ubuntu family doesn't support booting from it.

  • UDF - widely compatible, though obscure and often forgotten. The Bluehat family doesn't support booting from it. No Apple support inside a partition.

  • Ext4 - compatible with all Linux (except debian netinst), permissions a minor annoyance on a removable drive. Not typically supported elsewhere.

It seemed that exfat was the best choice at first, but as mentioned the Ubuntu family doesn't support booting from it. Ext4 is a good choice for a Linux-centric user, but you may want to change it back to exfat if you'll be using it often with Windows machines or Macs. (See the "customization" section later on for instructions.)

(There is a third optional partition however, so one could pick their two favorites if necessary.)

Install


This project should be currently considered BETA quality. However, there's been a lot of work put in to make these scripts robust and avoid errors to the extent Bash and grub-script allows—including the use of shellcheck, defensive programming, extensive error checking and avoidance, and plenty of testing.

There still could be an issue or two lurking however—the code has been changing—no warranty expressed or implied. Recommend starting with a throwaway key, and reading everything the installer below tells you closely.

Get TBK:

Near the top right of the page ⤴, you'll see a git repo URL to clone from:

    git clone https://codeberg.org/aol/trusty-boot-key.git
    # or
    git clone ssh://git@codeberg.org/aol/trusty-boot-key.git

No git? Well, next to that is a link with a [⋯] icon, click on that to download an archive from the menu, and then unpack it.

The scripts inside currently need these packages to run, it's best to install them beforehand:

  • Adwaita mono - fedora:adwaita-mono-fonts, arch:adwaita-fonts, debian: not-available - uses DejaVu mono instead.
  • dosfstools
  • grub2 grub2-efi-x64-modules - arch:grub
  • parted
  • udevadm - from systemd so probably have it
  • udisks2
  • optionally exfatprogs ntfsprogs, etc for other filesystems.

It's also a good idea to put yourself in the disks group, so you don't have to run sudo for the update script:

    sudo usermod -aG disk $USER
    # You can log out and back in to reload groups or run:
    exec su -l $USER
About Linux Device Names:

Linux removable disk device names have the format: /dev/sdXN

This means in the /dev/ device folder there's a file where the first part of the name is sd, which stood for "SCSI disks" in the old days. Then another lower-case letter for the particular drive (here X), and an optional partition number at the end (here N). i.e.:

    /dev/sda    # whole device
    /dev/sda1   # first part

The GNOME Disks, GParted, or KDE partition manager are helpful to see what is connected to your system. The first one is useful while installing TBK, in that it reacts to changes happening live as you work, allowing a birds-eye view.

To install to the drive itself:

Beware! Setup-drive.sh will carve up and format your disk.

Note: The X below represents a removable drive, likely a or b, but potentially a later letter. Do not give a partition number at the end—this one wants the whole device:

    cd ./trusty-boot-key  # this repo, ¡importante!

    ./setup-drive.sh DEVICE  # aka /dev/sdX  - no number

Then follow instructions, which is basically to hit the "y" key and hit ENTER several times.

If successful, the setup-drive script will do the full grub-update steps mentioned below as well. So if you completed setup, no need to do it again below. (Good idea to read however.)

Install Optional Tools:

What are tools? Currently they consist of an open-source UEFI Shell, as well as the MemTest86plus utility.

Would you like these handy on your TBK? They are already installed inside many .iso's, so no big deal. But if you'd like them up front and center, run this command:

    ./get-tools.sh  # -e, -m, or --all

The script above will attempt to download the tools, unpack them if necessary, and copy the binaries to your TBK on the first partition at Trusty-Boot:/grub-tbk/tools. If successful, they'll also be added to the Utilities… entry available from the main menu.

(This tool is simpler than the update-tbk.sh script (detailed below) currently, and expects the ESP to be mounted already at its typical automount location with the configured volume/label name.)

Additionally, if you'd rather grab these yourself, they can be obtained manually and dropped into the Data partition under Trusty-Zone:/os-images, where they'll be listed in the menu automatically.

Updating


To update the config files there is another convenience script.

An update will be needed if you've done a git pull for the latest version of TBK, updated the config file, or you've written some custom "grub script" yourself.

Note1: This is for updating the main menus or defaults. The "OS Images" menu list will look for boot images on the second partition every time, live. No need to "update config" just for that!

Note2: This one wants to update the ESP, so do give a partition number at the end—which should be 1. X will be the same lower letter of the alphabet used above:

    ./update-tbk.sh DEVICE_NUM  # aka /dev/sdX1 - include part. num 1

On rarer occasions you may want to rebuild and upgrade grub itself or the font it uses. Adding a grub module as a built-in requires this, and external module additions are conveniently installed as well:

    ./update-tbk.sh -g DEVICE_NUM  # aka /dev/sdaN

Use


When setup is done, drop some images into the `/os-images` folder (of the second partition of the removable drive), pop it in the target, and restart! You may have to hit F2, F12, or another key at startup time to select the boot drive. (Consult your system documentation.)

Secure boot—not supported yet! Not sure that we will as it's a pain in the rear. Can you help?

Sorting the OS Images Menu

Despite excessive functionality in other areas, GRUB is only able to sort menu entries though some very hacked-up grub script, and just barely. We were able to implement a bubble sort, though there is no list or array type, so item-swap is done through string operations. Very low performance! Not been a problem so far with a dozen images or so. Twenty might be doable on a fast machine? Dunno, we'll see how that plays out. For this reason, sort can be turned off for now, see below.

If one moves the files off the drive and then returns them the operation typically will be performed in alphabetical order, meaning they'll be sorted on disk. If not, try rsync. This should speed up the sorting performance as well. Better yet, copy them manually in the order of use. e.g. most used image copied first, second second etc. Then turn off sorting.

Customization

You can easily place custom entries into the menu by placing grub-script into a file at the following location:

    $prefix/custom.cfg

Prefix is grub-speak for the main grub folder, currently at Trusty-Boot:/grub-tbk. In this case, at the root of the ESP partition of your removable drive. The first and smaller partition.

If this file is found, the contents inside will be evaluated. Make sure it is syntactically correct or it will break things afterward. Starting very simply and building from there is the best way.
grub-script-check custom.cfg is your friend.

_config.sh

One can also edit the _config.sh file in the repo when ready to get serious with customization. The default localization for example, (currently limited to a few western languages due to font restrictions).

You can also add additional grub modules, change labels and the theme, the size of the first partition, and even the filesystem of the second (or third!) partition, among other things.

Themes

There are three levels of quality. A VGA-style text-mode interface is available in a pinch with the Escape key pressed at early boot time. Called "" (empty-string, a.k.a. none) in _config.sh.

We're using the 'simple' theme by default, which has HD resolution, a unicode font, and some color.

The graphical version includes a lightly-modified Slaze theme by adi1090x/uGRUB, Galaxy, and Stones. Choose in _config.sh and remember to run update with the -g option once to build additional grub graphical theme modules and install them:

./update-tbk.sh -g /dev/sdX1

Themes then need to be copied to ESP:/grub-tbk/themes/$THEME_NAME. The theme file currently must be named theme.txt. Then write the folder name into _config.sh under GRUB_THEME=.

Help and Utils menus

There's a help menu that has a few useful entries for someone not that familiar with GRUB or PC technology in general, but is interested in learning.

Support modules, such as a serial console or additional filesystem support can be loaded as well, all from the Utilities and Drivers menu.

Troubleshooting

By default this starts up in graphics mode at 1920x1080 resolution with and a medium-large font. Which should be the bare minimum these days. However, maybe you're in a pinch, hacking on a machine in the closet with a relic of a monitor and that's not gonna work.

Well, at startup up you can hold down the shift key to skip the graphics term and use the standard monochrome (GOP? VGA?) console instead. (One sacrifice we make to the ancients.)

Update: that functionality with the keystatus --shift key doesn't seem to work on our UEFI EDK2 machine. So we're using the sleep command instead, and you'll need to hit the Escape key instead, quickly at first boot to bypass graphics mode!

Graphics modes

The videoinfo command might be your friend in this case, it will list supported modes and you can go back down to a fallback resolution with the following incantation:

    set gfxmode="1024x768x32,auto"

Which was a fancy resolution in the early years. ;-) Now that I think of it, staying in the monochrome console probably makes more sense in that case. But, if you've read this far then you've learned how to handle other situations, like if the text is too big, or way too small on your 8k!  Then save it to _config.sh.

Tested

This has been tested installing from:

  • Fedora 44
  • Arch 26.07
  • Ubuntu 26.04 (Adwaita mono not packaged, uses DejaVu instead. Also need to install additional grub locales if desired.)

So far. Doesn't use many fancy features so should run in older versions, but we'll see.

Has been tested with these images, that have loaded successfully:

  • .iso files
  • .efi files
  • memtest86 binaries that use the linux boot protocol.

Windows

Not currently working. It loads but install fails with a "Needs media driver error."

What we tried…

The .iso is a no-go however, so here's how to (not-quite) get it working with TBK.

Now that you understand _config.sh and custom.cfg, you'll want to edit _config and choose a filesystem or two, depending if you are a dabbler or a devotee…

Dabbler:

  1. Recommend making a third partition. Fat32 or exfat is probably easiest, we also tried NTFS with compression enabled.

  2. Find VOL2_END and change it to 80%, $SIZE - 10GB, or whatever leaves enough space for the .iso contents and your needs. Select the filesystems for both second and third partitions.

  3. Let setup-drive.sh carve up and format the disk.

  4. Unpack the .iso into the third partition. (7zip can handle as well if your mounter is not working.)

  5. Copy ./grub/examples/windows.cfg from this repo to Trusty-Boot:/grub-tbk/custom.cfg, edit/augment as desired.

  6. Run ./update-tbk.sh DEVICE_NUM, use -g also only if you've changed the module list/font after setup.

  7. Boot and load the TBK menu. Load ntfs and/or ntfscomp from the Utils menu first if need be.

Devotee:

  • Consider one big second partition with a "native" filesystem.

    (Windows may not install from a folder.)

  • Move the ntfs modules to the _GRUB_BUILTINS list as you will likely be using them often, to avoid having to load manually every time.

Was not able to get this to work and pointed to: https://askubuntu.com/questions/1227291/grub-boot-from-windows-iso/1525482

Might work for you.

FreeBSD

We understand the process is quite likely similar to the Windows section above, substituting UFS2 or ZFS for NTFS. Haven't yet tried it. Let us know if it works.

Links

  • Arch - Up to date desktop, rolling

  • Fedora - Up to date desktop, every 6-month release

  • Mint - Long-term support (LTS) desktop, 2-year release

  • Tails - Anonymity

  • Kali - Forensics, pentesting

  • Memtest86 - RAM tester

  • UEFI Shell - The shellx64.efi works.

  • Mosby - looked interesting.

For memtest you can download the "Binary Files" link, unpack the archive and copy the *_x86_64 file to the /os-images folder on the data partition of the removable drive. See the get-tools.sh script to handle this automatically.

Inspiration and Thanks

We found these docs very helpful:

Also cribbed a number of grub scripting techniques from these similar projects:

Not to mention looking at the grub.cfg of the many ISO images themselves.

Dev Guide

Contributing Support Files

Need support for your favorite distro? Please make a merge request with your menuentry stanza in a name.cfg file under the support folder of this repo. The script filename must match the prefix of the boot image filename, up until the first dash or period -., with a .cfg extension at the end. e.g.: foobar-123.iso --> ./support/foobar.cfg

I suggest getting started by looking in the last two repos linked above for example boot commands and arguments for your product of choice. Also, mount your .iso file of interest as a loopback drive or open with an archiver. Looking around the folders will give quite a bit of information, such as the proper paths to the kernel etc.

Then, refactor the script using the guidelines below.

Repo Tour

In addition to the two main scripts mentioned already, additional descriptions follow:

  • Root folder - besides setup and update, it also includes these Bash support scripts:

    • setup-drive.sh - carves up the flash drive, destroyer of worlds.

    • update-tbk.sh - updates the settings and menus of GRUB, optionally GRUB itself and/or its fonts.

    • generate-cfg.sh - builds the grub/options.cfg using a template.

    • get-tools.sh - downloads and installs latest support tools.

    • _config.sh - numerous customization variables are here

    • _error_checks.sh - looks for issues before allowing setup- and update- to proceed.

    • _lib.sh - assorted clean up and output routines.

  • ./docs - contains several text files, explaining various topics.

  • ./grub - the folder where the main .cfg files are located, copied to the drive at update time.

    • grub.cfg - main entry point. Loads the rest, some at startup, others on demand.

    • lib.cfg - library functions, init graphics, calendar, sort, etc.

    • options.cfg - file to hold settings received from Bash.

    • search.cfg - the main loop that looks for files under /os-images

    • utils.cfg - where the utility submenu entries are

    • help.cfg - where the help entries are

  • ./grub/support/ - Where we place .cfg files that either directly apply to an .iso file, or if they apply to a group they can be named with an underscore at the front.

  • ./grub/examples Experiments from before we learned about loopback.cfg, good coding examples of grub-script.

Guidelines

  • Use defensive scripting (test -f, etc), though keep in mind we've already validated the existence of the image file, or we wouldn't have made it to your script.

  • Use existing files for style guidelines, Remove redundant code.

  • A comment on what obscure boot parameters do and when they are required is helpful. Since you're validating the entry, it is a good time to experiment.

  • Use plenty of whitespace—we're not running out on the these short files. Four space indents, and single blank lines between significant, dense, or commands of differing functionality.

    Long boot options are probably better indented on their own lines, using a backslash to continue the line is supported in grub script.

  • If a number of complicated parameter combos are recognized, you may want to create a submenu for several entries to be chosen.

  • Use a unicode character in front of the entry title as an icon.

    Currently using ◎ for recognized isos, ⟳ for loopback.cfg support, ⌁ for executable binaries like .efi, and ⏵ for sub-menus. Ⓔ is given for yet unrecognized files that need to use the "e" key for the script to be written to successfully boot.

    These are themed using variables such as $char_foo, depending on whether a Unicode font is loaded or not. See ./grub/lib.cfg @ function set_chars

    If there is a cool looking character that matches even better that's fine as well, however note that the font is currently limited to points <= 0xFFFF, and does not support everything under that, which eliminates most Asian writing systems, emojis, and more. #TODO

  • Use the mkloop function (from search.cfg) to make your loop device. When used, and you 1) return from an internal image menu, or 2) there is an error and you are thrown back to the main menu, the next choice will avoid the "device already exists!" error.

Variables

In your script, you'll have the following variables at your disposal:

  • $P1 - Grub-style path to the first partition of the removable drive.

  • $P2 - Grub-style path to the second partition of the removable drive.

  • $root - Grub-style path to the ESP of the removable drive.

  • $prefix - the folder typically at/called $root/grub-tbk

  • $full_path - Full grub-style path to the current image file, including (drive,) notation.

  • $path - Unix-style /absolute/path to the file, without drive notation.

  • $filename - The whole filename, without any path.

  • $basename - The alpha-numeric front of the filename, up to the first dash or period -.. Would call it a prefix, but that name is taken. :-/

Tools

Please use these tools before submission:

  • shellcheck *.sh, for bash and
  • grub*-script-check, for .cfg files, for example:

find . -name '*.cfg' -print -exec grub-script-check '{}' ';'

You will find them annoying and helpful.

Standard?

Wouldn't it be great if there were a standard for booting these things and we did not have to make a custom loader script for almost every one?

If anyone knows anything about that or would like to start one, let's hear it. Oh—well:

Loopback.cfg

Looking thru the eye-sos, we found several references to a loopback.cfg and finally an URL. That wiki seems to be down, but did dig the page up from the wayback: loopback.cfg

The loopback.cfg file must be found at the path /boot/grub/loopback.cfg.

That is the case, except for Blue Hat distros which use grub2. :-/ Ok, found a way around that. Support could be better.

Trustworthy Technology

That's all folks! Learn more about this project, and what inspired it, at trustworthy.technology.