How to create a portable retrogaming USB stick with Batocera Linux

Batocera is a free and open source Linux distribution designed to create retrogaming consoles out of a vast selection of devices. It supports a variety of platforms and architectures, from Intel-based computers to Raspberry Pi boards and handheld consoles, and works as a central control panel for all the best console emulators.

In this tutorial we learn how to flash Batocera Linux on a USB stick and create a portable retrogaming device.

In this tutorial you will learn:

  • How to download and flash Batocera on a USB stick
  • How to access roms and other resources from samba or NFS network shares
How to create a portable retrogaming USB stick with Batocera Linux
How to create a portable retrogaming USB stick with Batocera Linux
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Batocera Linux
Software dd or balenaEtcher
Other A USB stick
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Downloading Batocera image

To download the latest version of Batocera Linux (39 at the moment of writing), all we have to do is to navigate to the Download page of the distribution official website. Our goal, in this tutorial, is to install Batocera on a USB stick and use it as a boot device on x86_64 machines, therefore the first entry is the one which interests us:

Batocera download page
Batocera download page



Once the download is complete, we must write the image to a sufficiently large USB stick. Let’s see how we can do it.

Writing Batocera image

There are many ways we can write Batocera image on USB sticks: one of the most user-friendly is to use balenaEtcher, a free and open source tool designed to be easy to use and to work on any platform. We can download the appropriate version for our operating system, straight from the project official website; a portable Appimage is available for Linux. Once we install and launch the tool, we should see the following window:

balenaEtcher interface
balenaEtcher interface

The first thing we need to do, is to click on the “Flash from file” button, and select the compressed Batocera image we previously downloaded: it is not necessary to extract it beforehand, since Etcher is smart enough to do it for us.



Once we select the image, we need to select a target: the device on which we want to flash it. We click on the “Select target” button and choose the device we want to use as target from the list; finally, we click on the “Select” button to confirm our choice:

Choosing the target device with balenaEtcher
Choosing the target device with balenaEtcher

We are almost there. To flash the image to the target device, we just click on the “Flash!” button in Etcher main interface and provide our administration password if required. The flashing process will begin:

Flashing Batocera image with balenaEtcher
Flashing Batocera image with balenaEtcher

In a few minutes the flashing should be complete.

Batocera image successfully flashed with balenaEtcher
Batocera image successfully flashed with balenaEtcher

Writing Batocera image with dd (Linux and macOS only)

If we are using a Linux distribution or macOS, and we are comfortable working from the command line, we can flash Batocera image with dd, a tool usually installed by default on any Unix-based operating system. If we decide to use this method, we must pay close attention when specifying the target device, because there will be no confirmation prompt.

We can extract and write the image to the target device in a single command, by using the following syntax:

$ zcat </path/to/batocera/compressed/image> | sudo dd of=</target/device/path> bs=1M

Here I will assume Batocera image to be in the ~/Downloads directory, and the path of the target device to be /dev/sdb (example is run on Linux), therefore the command I would execute is:

$ zcat ~/Downloads/batocera-x86_64-x86_64-39-20240304.img.gz | sudo dd of=/dev/sdb bs=1M

Booting from the USB stick

Once the image is flashed, we must reboot (or create a Virtual Machine) and use the USB stick as boot device. The key used to access the boot menu varies depending on computer manufacturers (on some machines is the ESC key, while on Lenovo Thinkpads, typically, is F12).



From the boot menu, we select our USB device and press Enter. Batocera should start instead of our operating system. The first time we boot Batocera, it will automatically resize the partitions created on the USB device, in order to use all the available space. This could take a while, depending on system resources, and the size of the USB device:

Batocera first boot
Batocera first boot

Once the process is complete, we will see the system/console emulator selection screen:

Batocera emulators selection screen
Batocera emulators selection screen

How to access roms from a network share

Batocera creates two partitions on the target USB device; the first one is formatted with the VFAT filesystem, and is labeled “BATOCERA”. It contains files required for the system to boot, such as batocera.conf. The second one, which spans over the rest of the device, is the “userdata” partition, formatted with the EXT4 filesystem with the “SHARE” label. It contains, among the others, the “saves”, “bios” and “roms” directories. The first one holds save files, the second is where we place bios images required by certain consoles, and the third contains games images in a series of subdirectories named after emulated systems:

The content of the "roms" directory
The content of the “roms” directory
COPYRIGHT WARNING
Even if roms for various systems con easily be found on the internet, you must only use roms for games you legally own, otherwise you would commit piracy.

The most straightforward way to make resources like roms available to Batocera, is to copy them in the appropriate directories, directly on the USB stick. If, however, we have a network share available in your LAN, we can mount directories over the network. This way we can avoid duplicates and having to maintain/keep in sync two sets of collections.

In order to mount shared directories, we need to edit the batocera.conf file, which, as we saw, is located in the “BATOCERA” partition. We are interested in the content of line 11:

sharedevice=INTERNAL

In order to mount network-shared directories, we need to change this to:

sharedevice=NETWORK

We then need to specify the directories we want to mount over the network. Almost every directory in Batocera userdata partition is identified by a keyword, which is basically its capitalized name. The SHARE keyword is an exception, since it represents the content of the partition as a whole. Available keywords are:

    • SHARE
    • ROMS
    • BIOS
    • SAVES
    • MUSIC
  • DECORATIONS
  • SCREENSHOTS
  • THEMES
  • CHEATS
  • SOUNDS
  • LIBRARY
  • SPLASH

Batocera supports mounting samba and NFS network shares. Let’s see how to mount samba-shared directories, first.

Mounting samba shares

Suppose we have a samba share named “data” accessible as an anonymous (guest) user on a NAS with the 192.168.0.39 IP. Inside this share we have a directory called “batocera” which contains the entire Batocera “SHARE” partition directory structure. To mount this directory as a whole, we can use the “SHARE” keyword. Here is the syntax we would use:

sharenetwork_smb1=SHARE@192.168.0.39:data/batocera:guest

If authentication is required to access the share, we can specify username and password via the dedicated options:

sharenetwork_smb1=SHARE@192.168.0.39:data/batocera:username=<username>,password=<password>

What if we want to mount only a specific directory? All we need to do is to use the appropriate directory keyword. Suppose, for example, we want to mount only shared roms. Assuming the same network share we saw in the previous example, we would write:

sharenetwork_smb1=ROMS@192.168.0.39:data/batocera/roms:username=<username>,password=<password>



We can specify multiple network mounts. In the example below, we mount the “roms”, “saves” and “bios” shared directories, separately:

sharenetwork_smb1=ROMS@192.168.0.39:data/batocera/roms:username=<username>,password=<password>
sharenetwork_smb2=SAVES@192.168.0.39:data/batocera/saves:username=<username>,password=<password> 
sharenetwork_smb3=BIOS@192.168.0.39:data/batocera/bios:username=<username>,password=<password>

Mounting NFS shares

What about NFS shares? The syntax is the same; the difference is that we need to use the “nfs” prefix instead of “smb”, and the full path of the shared directory, instead of the share name. Suppose, for example, the shared directory on the NAS is /srv/batocera. To mount its entire content, we would write:

sharenetwork_nfs1=SHARE@192.168.0.39:/srv/batocera

To mount directories separately, instead:

sharenetwork_nfs1=ROMS@192.168.0.39:/srv/batocera/roms
sharenetwork_nfs2=SAVES@192.168.0.39:/srv/batocera/saves
sharenetwork_nfs3=BIOS@192.168.0.39:/srv/batocera/bios

Conclusions

In this tutorial we learned how to create a portable retrogaming system on a USB stick using Batocera. We saw how to flash the image using balenaEtcher, and how to use dd as a command line alternative on Unix-based operating systems. Finally, we saw how Batocera partitions the USB stick, and how to access resources from samba or NFS network shares.