# void-mklive: building Void Linux live images and root filesystems

> void-mklive is the shell-script toolchain behind the Void Linux live images, with separate scripts for x86 live ISOs, root filesystem tarballs, platform filesystems for ARM, netboot archives and the x86 installer. The Makefile drives the whole matrix of architectures, flavours and output formats.

**void-linux/void-mklive** — The Void Linux live image maker

- Repository: https://github.com/void-linux/void-mklive
- Website: https://voidlinux.org
- Stars: 525 · Forks: 279
- Language: Shell
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/void-linux-void-mklive

## Seven scripts for four different kinds of output

The repository is titled the Void Linux live image/rootfs generator and installer, and it holds several utilities rather than one.

mklive.sh is the Void Linux live image generator for x86. mkiso.sh is a wrapper script to generate bootable and installable live images for i686, x86_64 and aarch64. mkrootfs.sh is the Void Linux rootfs generator for all platforms. mkplatformfs.sh is the filesystem tool to produce a rootfs for a particular platform. mkimage.sh is the image generator for ARM platforms. mknet.sh generates netboot tarballs for Void. installer.sh is the Void Linux el-cheapo installer for x86. And release.sh interacts with GitHub CI to generate and sign images for releases.

That last item is worth pausing on. A script that talks to GitHub CI to generate and sign images means the release pipeline is a repository concern rather than something that happens on a maintainer's machine, which is the difference between a build you can reproduce and one you cannot.

The four output types are genuinely different things and the README separates them clearly.

A live ISO is a bootable image you write to a USB stick. A ROOTFS tarball contains a basic Void Linux root filesystem without a kernel, and the README says these can be useful for doing a chroot install or for chroots and containers. A PLATFORMFS tarball contains a basic root filesystem including a kernel, and these are commonly used for bootstrapping ARM systems or other environments that require platform-specific kernels, like Raspberry Pis. And an ARM image contains a basic filesystem layout with / and /boot partitions, ready to be copied to the target drive with dd, which are not live images and do not need installation like live ISOs.

The ordering is the workflow. To get an ARM image you first create a PLATFORMFS for the desired platform and then use mkimage.sh. To get a PLATFORMFS you first create a ROOTFS for the desired architecture. To get a ROOTFS you use mkrootfs.sh. It reads like a pipeline, and it is one.

The primary language is Shell, the default branch is master, and there are no GitHub releases. The homepage is voidlinux.org, and the licence is a custom one GitHub cannot classify, with a COPYING file at the root.

## Live ISO flavours, and what the wrapper adds

There are two ways to make a live ISO and the distinction is the difference between a working appliance and a starting point.

To generate a live ISO like the officially-published ones, use mkiso.sh. To generate a more basic live ISO, which does not include things like void-installer, use mklive.sh.

So mklive.sh is the underlying generator and mkiso.sh is the wrapper that adds void-installer and other helpful utilities to the generated images. The mkiso.sh help text says as much: it is a wrapper script around mklive.sh for several standard flavors of live images, and it adds void-installer and other helpful utilities.

The flavour list is the interesting part of the mkiso.sh options, and it is longer than most people expect from a Linux live image.

```
  -b <variant>  One of base, enlightenment, xfce, mate, cinnamon, gnome, kde,
               lxde, lxqt, or xfce-wayland (default: base). May be specified multiple times
               to build multiple variants
```

Ten desktop environments plus base, with xfce-wayland sitting alongside xfce as a separate variant rather than a flag on it. That the default is base rather than a desktop is a reasonable choice for a script that also has to run unattended in CI.

The other mkiso.sh options are the ones you would expect from a release build script: -a for architecture, -d to override the datestamp in YYYYMMDD format, and -t for an arch-date-variant shorthand that sets all three at once. The -t option is the one to reach for when reproducing a specific published image.

The -r option selects the XBPS repository and may be specified multiple times, and the README's example of that is in the Makefile rather than the help text.

```
XBPS_REPOSITORY := -r $(REPOSITORY) -r $(REPOSITORY)/musl -r $(REPOSITORY)/aarch64
```

That single line shows the whole approach to multi-arch builds: the same repository URL is reused with a musl and an aarch64 suffix, so one set of options pulls from the three trees rather than needing three separate invocations.

Options for mklive.sh itself can be passed through mkiso.sh after a -- separator, which is the standard trick for keeping a wrapper's own flags distinct from the ones it forwards.

## The mklive.sh options, and the knobs that matter most

mklive.sh has its own help text, and it is the most detailed document in the repository because it is where the real work happens.

It generates a basic live ISO image of Void Linux that can be written to a CD/DVD-ROM or any USB stick.

```
  -a <arch>          Set XBPS_ARCH in the ISO image
  -b <system-pkg>    Set an alternative base package (default: base-system)
  -r <repo>          Use this XBPS repository. May be specified multiple times
  -c <cachedir>      Use this XBPS cache directory (default: ./xbps-cachedir-<arch>)
  -H <host_cachedir> Use this Host XBPS cache directory (default: ./xbps-cachedir-<host_arch>)
  -k <keymap>        Default keymap to use (default: us)
  -l <locale>        Default locale to use (default: en_US.UTF-8)
  -i <lz4|gzip|bzip2|xz>
                    Compression type for the initramfs image (default: xz)
  -s <gzip|lzo|xz>   Compression type for the squashfs image (default: xz)
  -o <file>          Output file name for the ISO image (default: automatic)
  -p "<pkg> ..."     Install additional packages in the ISO image
  -g "<pkg> ..."     Ignore packages when building the ISO image
```

The -p and -g options are the pair to understand first. They add packages to the image and ignore packages when building it, and together they are how you take a published flavour and adjust it, adding a tool here and dropping a heavy default there.

The compression options are split across two artefacts, and the distinction is not cosmetic. The initramfs compression is -i, accepting lz4, gzip, bzip2 or xz with xz as the default, while the squashfs image compression is -s, accepting gzip, lzo or xz with xz as the default. The initramfs is what the kernel unpacks at boot, so its format affects boot time, while the squashfs is the main filesystem and its format affects the image size and how the live system reads files.

Two options are for customisation that goes beyond packages. The -I option includes a directory structure under a given path in the ROOTFS, and the -x option takes a path to a postsetup script to run before generating the initramfs, receiving the path to the ROOTFS as an argument. Between them they cover the two common cases: files you want in the image, and configuration you want applied during the build.

The -S option enables services in the ISO image, which matters because a live image does not run a service manager by default, and -C adds arbitrary kernel command line arguments.

The last option is the one to note for the ARM builds: -P takes a platform and the available values are pinebookpro and x13s, for platforms to enable for aarch64 EFI ISO images. The -e option sets the default shell of the root user and must be an absolute path, and the -T option modifies the bootloader title, which defaults to Void Linux. And -v installs a custom Linux version, accepting the linux metapackage or linux metapackages such as linux-mainline and linux-lts, while -K keeps the build directory instead of removing it, which is the option you want when you are debugging a build.

The -K flag deserves more attention than its one-line description suggests. A build that removes its own intermediate directory on failure gives you nothing to inspect, and for a script that assembles a filesystem from a package manager's output, the intermediate state is where the interesting failures live.

## The kernel command line interface of a live system

The README documents the kernel command-line parameters that void-mklive-based live images support, and this is one of the more useful pieces of documentation in the repository because it describes the finished system's behaviour rather than the build.

live.autologin will skip the initial login screen on tty1. live.user will change the username of the non-root user from the default anon, and the password remains voidlinux. live.shell sets the default shell for the non-root user in the live environment. live.accessibility enables accessibility features like the console screenreader espeakup in the live environment.

The console parameter can be set to ttyS0, hvc0 or hvsi0 to enable agetty on that serial console, which is how you get a usable login on a board with no display. locale.LANG will set the LANG environment variable and defaults to en_US.UTF-8. vconsole.keymap will set the console keymap and defaults to us.

The examples section combines them, and the combinations are more instructive than the individual flags.

```
live.autologin live.user=foo live.shell=/bin/bash
console=ttyS0 vconsole.keymap=cf
locale.LANG=fr_CA.UTF-8
```

The first creates the user foo with the default shell /bin/bash and logs them in automatically on tty1. The second enables ttyS0 and sets the keymap in the console to cf. The third sets the live system's language to fr_CA.UTF-8.

These are the parameters you pass at boot, so they work with a live USB and with a copied ARM image, which makes them the mechanism for making an image behave the way a particular deployment needs without rebuilding it. For an ARM board with a serial console, the console and vconsole.keymap pair is the difference between a device you can log into and one you cannot.

The live.user and live.shell pair is also how you control what a shared or kiosk-style machine presents, since the default anon user with the fixed password voidlinux is deliberately generic.

## Dependencies, and the architectures the Makefile targets

The dependencies section is short and carries a warning that deserves attention.

Note that void-mklive is not guaranteed to work on distributions other than Void Linux, or in containers.

That is a strong statement and it is the correct one, because the scripts use XBPS-specific commands throughout, the package names and repository layout in the options are XBPS concepts, and the initramfs is built with dracut configured for Void. The container exclusion is about the build environment rather than the target: the tools need to manipulate filesystems and mount images, which a container usually cannot do without privileges.

The dependency list itself is short: a compression type for the initramfs image, by default liblz4 for lz4 and xz, xbps at 0.45 or newer, qemu-user-static binaries for mkrootfs, and bash.

The qemu-user-static dependency is the interesting one. mkrootfs generates a root filesystem for any platform, and to do that on your x86 machine for an aarch64 target it needs to run aarch64 binaries, which is what qemu-user-static provides. That is what makes a single build host able to produce all the architectures in the Makefile matrix.

The Makefile shows the scope of that matrix.

```
T_LIVE_ARCHS=i686 x86_64{,-musl} aarch64{,-musl} asahi{,-musl}

T_PLATFORMS=rpi-{armv{6,7}l,aarch64}{,-musl} GCP{,-musl} pinebookpro{,-musl} asahi{,-musl}
```

Live ISOs are built for i686, x86_64, aarch64 and asahi, each with a musl variant. Platform-specific builds cover the Raspberry Pi armv6 and armv7 boards and aarch64, Google Cloud, the pinebookpro and asahi. The output targets go further still, with separate sets for single board computer images, cloud images, PXE netboot archives and WSL images.

The naming convention follows from that, and it is worth learning because the filenames tell you what a file is. Live ISOs are named void-live-<arch>-<date>-<flavour>.iso. ROOTFS tarballs are void-<arch>-ROOTFS-<date>.tar.xz. PLATFORMFS tarballs are void-<platform>-PLATFORMFS-<date>.tar.xz. Single board computer images are void-<platform>-<date>.img.xz, cloud images are void-<cloud>-<date>.tar.gz, netboot archives are void-<arch>-NETBOOT-<date>.tar.gz, and WSL archives are void-<arch>-<date>.wsl.

The WSL target is a recent addition and worth noting for anyone who develops against Void on Windows, since a WSL root filesystem is a different artefact from a chroot tarball.

One detail in the tree explains how the README stays accurate. There is a README.md.in file and the Makefile regenerates README.md from it along with the script help texts, and the file starts with a DO NOT EDIT comment saying it is generated by make README.md. That is why the help text you read in the README is guaranteed to match the scripts.

## Where void-mklive is the wrong tool

There are three limits, and the first is the one the README states in one sentence.

The first is that these scripts build Void Linux, specifically, and the warning that void-mklive is not guaranteed to work on distributions other than Void Linux or in containers is a statement about the design rather than about a rough edge. If you want a live image of Debian, Fedora, Alpine or anything else, this is the wrong repository, and no amount of flag tweaking will change that.

The second is the operational weight of a full ISO build. Even the basic mklive.sh path needs xbps, a working repository configuration, and enough time to fetch and install a base system, then compress an initramfs and a squashfs image. That is fine as a one-off and unpleasant as a step in a CI pipeline that runs on every commit. The dependencies also include qemu-user-static binaries for cross-architecture work, which is a heavyweight thing to require on a build machine.

There is a related point about what you actually need. A great many of the outputs here are not live images at all. The ROOTFS tarball is a root filesystem without a kernel, and for a chroot or a container that is all you need, and mkrootfs.sh alone is much cheaper than building an ISO. The PLATFORMFS tarball adds a kernel for the ARM and cloud cases. Reaching for the full live ISO when you need a root filesystem means booting the thing, installing it, and rebuilding the image you did not need.

The third is the coupling to the release pipeline. release.sh interacts with GitHub CI to generate and sign images for releases, and the signing keys live in the keys/ directory of the tree. That arrangement is right for the project and wrong for you if you want to produce signed images yourself, because the tooling is oriented towards the project's own CI rather than a general-purpose release system.

The honest alternative for most of these jobs is not another live image builder, it is using the official images and customizing at a different layer. The published Void live ISOs cover the desktop flavours, and the released ROOTFS and PLATFORMFS artefacts cover the server and ARM cases, so building your own is only worth it when you need a package set or a configuration the published images do not have, or when you need a specific old release built from source.

For a fully custom system, the standard Linux tooling is the better answer: debootstrap and a chroot for the root filesystem, dracut for the initramfs, and xorriso or the distribution's own ISO tooling for the image. You give up Void's package selection and its installer integration, and you gain a workflow you can reason about.

What void-mklive offers that those do not is coherence. The generated image boots into the same environment the project ships, with the same repository layout and the same installer, and the kernel command-line parameters for the live user, shell, locale, keymap and serial console are already wired up. For a maintainer building the official images, or for a team that wants a Void image that behaves exactly like the official one, that coherence is the entire value.

## Conclusion

Adopt void-mklive if you need to build Void Linux images yourself rather than download them, which covers custom desktop flavours, ARM boards, netboot archives and reproducible internal builds. Do not adopt it if you want a general purpose ISO builder, because these scripts are tied to XBPS, dracut and Void's package repositories. Before you run anything, note the README warns that void-mklive is not guaranteed to work outside Void Linux or in containers, and the last push was on 2026-10-17.

## FAQ

### What is void-mklive and what does it produce?

It is the Void Linux live image and rootfs generator, a set of shell scripts: mklive.sh for x86 live images, mkiso.sh as a wrapper for installable images, mkrootfs.sh for ROOTFS tarballs, mkplatformfs.sh for kernel-bearing platform filesystems, mkimage.sh for ARM images, mknet.sh for netboot tarballs, installer.sh for the x86 installer and release.sh for CI-driven signed releases.

### How do I build a Void Linux live ISO?

Use mkiso.sh for a complete image like the officially-published ones, or mklive.sh for a more basic one without void-installer. The wrapper takes -a for architecture, -b for a variant such as base, xfce, gnome or kde, -d for a YYYYMMDD datestamp and -t for an arch-date-variant shorthand, and options after -- are passed through to mklive.sh.

### What is the difference between a ROOTFS and a PLATFORMFS in void-mklive?

A ROOTFS tarball is a basic Void Linux root filesystem without a kernel, useful for chroot installs and for chroots and containers. A PLATFORMFS tarball is a root filesystem that includes a kernel, and these are commonly used for bootstrapping ARM systems or environments that need platform-specific kernels such as Raspberry Pis.

### Which kernel command line options does a void-mklive live image support?

live.autologin skips the login screen on tty1, live.user changes the non-root username from the default anon while the password stays voidlinux, live.shell sets that user's shell, live.accessibility enables features like the espeakup screenreader, console can be set to ttyS0, hvc0 or hvsi0 for a serial console, locale.LANG sets the locale and vconsole.keymap sets the keymap.

### What does void-mklive need to run?

A compression type for the initramfs image, by default liblz4 for lz4 and xz, xbps 0.45 or newer, qemu-user-static binaries for mkrootfs, and bash. The README also warns that void-mklive is not guaranteed to work on distributions other than Void Linux or in containers.

## Sources

- [Issues](https://github.com/void-linux/void-mklive/issues)
- [Project website](https://voidlinux.org)
- [README](https://github.com/void-linux/void-mklive/blob/master/README.md)
- [void-linux/void-mklive on GitHub](https://github.com/void-linux/void-mklive)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/void-linux-void-mklive
