down. translated.

@spec.get_opts.each do |name, opt| options[name] = opt.value counts[name] = opt.count end @spec.get_args.each do |name, arg| args << arg.value named[name] = arg.value end args.flatten! args += trailing @report = Report.new(args, named, trailing, options, counts) if @report.opt(:help) self.print_usage() end unless @spec.get_args.values.all? {|arg| arg.fulfilled? } raise InterfaceError, "Required argument '#{name.upcase}' was not given." end if @spec.trailing_error && !@report.trailing.empty? raise InterfaceError, "Error: got trailing argument(s): #{trailing.join

Software

I recently dug out an old Raspberry Pi and was surprised to find it still working. I couldn't remember exactly what model it is so I ran lshw on it and discovered that I have a Raspberry Pi 1 Model B Rev 2, a single-core ARMv6 device. I christened it "Mucor" and decided to install Void Linux on it, since Void is lightweight and has ARMv6 Raspberry Pi builds available.

I wrote this guide based on the experience. It takes a simple approach, using pre-built live images, and is easy to follow from either Windows or Linux. It assumes some general familiarity with Linux and the command line, but I try not to assume too much. I'm also working on a Void Linux Cheatsheet that may be helpful to look at.

§Requirements

This guide requires an SD card with at least 2GB of storage. It's written for an ARMv6 Raspberry Pi 1, but I imagine the same basic approach would work for many similar platforms.

§Preparing the Media

Void offers two different approaches to installation — live images and ROOTFS tarballs. This guide will cover the live image approach. I'll be using the ARMv6 build, and for simplicity glibc — musl is more lightweight but we have enough space for either.

Insert the SD card you want to use. The next steps depend on what platform you're on.

Determine the device name of your SD card. In this guide mine is at /dev/sdh. Be sure to change this in the following commands.

# Download the image
curl https://repo-default.voidlinux.org/live/current/void-rpi-armv6l-20240314.img.xz -o void-rpi-armv6l-20240314.img.xz

# Decompress the image
unxz void-rpi-armv6l-20240314.img.xz

# Flash the image to your SD card
dd if=void-rpi-armv6l-20240314.img of=/dev/sdh bs=1M status=progress

Jump to Free space below to continue.

First, download the live image.

Under Windows you can use multiple tools to flash the image to your SD card, such as Rufus, imageUSB and Raspberry Pi Imager. Raspberry Pi Imager can use xz-compressed images directly, so we'll use that. Download and install Raspberry Pi Imager, then open it:

Ignore the "Choose Device" button. Click "Choose OS", then scroll to the bottom of the list and select "Use Custom":

From here, select the image file you downloaded earlier, named void-rpi-armv6l-20240314.img.xz. After this you'll be returned to the main inteface. Click "Choose Storage". You'll be presented with a list of removable drives you can flash:

Pick the SD card you want to use. You'll be returned to the main interface again. From here, hit "Next". You'll be prompted to apply OS settings:

Hit "No" here. You'll then be warned that all data on the SD card will be erased. Hit "Yes" to continue. The writing process will begin, then the card will be verified. If all goes well you'll see the following notice:

Click continue. Raspberry Pi Imager automatically ejects the SD card, but we aren't done with it. Remove and re-insert the SD card.

When using the live image method, you'll have unallocated free space left on your SD card if it's larger than 2GB. If your card is only 2GB, skip to Working With the System. We could expand the existing root partition but I prefer to just create a new partition to fill the space. It's simpler and less fiddly, and we can use bind mounts to preserve space on the root partition.

Run cfdisk /dev/sdh:

Highlight "Free space" and hit Enter to create a new partition:

You'll be asked for the size of the new partition, and then whether it should be primary or extended. The defaults should be fine, so just hit Enter for both questions. Afterwords you'll be returned to the main interface. Use the right arrow key to highlight "Write" at the bottom of the interface:

Hit Enter to write the partition table. You'll be asked to confirm this. Type "yes" then hit Enter to commit your changes to disk. If all goes well you'll see this:

Highlight "Quit" and press Enter or just press "q" on your keyboard to exit cfdisk. Run sync then remove the SD card and insert it back into the Raspberry Pi.

Now the partition is ready. Later we'll create a filesystem on it and configure it to mount at boot.

Continue to First Boot.

Under Windows we'll use Disk Management to create a new partition. Hit Windows key + R and type Diskmgmt.msc to launch it:

In my case my SD card is Disk 2, with 5.32GB of unallocated space. Find your card and right click the "Unallocated" space at the end of it:

Click "New Simple Volume". Click Next three times until you get to the "Format Partition" screen. Select "Do not format this volume":

Click Next and then Finish. After a moment you should see something like this:

Eject the disk and remove the SD card, then insert it back into the Raspberry Pi.

Now the partition is ready. Later we'll create a filesystem on it and configure it to mount at boot.

Now insert the SD card into your Raspberry Pi and boot it. If it succeeds, congratulations. You've installed Void Linux. The live system is your installation. Continue below to configure it.

§Configuration

To work with the new Void Linux system, you can either connect a monitor and keyboard to the Raspberry Pi, or connect to it via SSH. Void runs an SSH server by default which accepts passwords. In either case you can login as root using the password voidlinux.

Perform a system update with xbps-install -Su. Be sure to run this occasionally to keep the system up to date.

Note that Void comes with vi as its text editor. If you would prefer to use something else, install it now. For example, to install nano: xbps-install nano

Edit /etc/hostname with your hostname of choice (I'll be using Mucor; be sure to change that where you see it)

Now edit /etc/rc.conf. We need to set our keymap here. You can find available keymaps under /usr/share/kbd/keymaps. For many qwerty keyboard users, us will be sufficient:

KEYMAP="us"

We also need to set our timezone in /etc/rc.conf. You can find available timezones in /usr/share/zoneinfo. Find yours and adjust the following command:

ln -sf /usr/share/zoneinfo/EST /etc/localtime

You can configure your locale in /etc/locale.conf. The default settings are sufficient for me:

LANG=en_US.UTF-8
LC_COLLATE=C

Run locale -a to see available locales. However, these are a bit limited by default. If you need something else, edit /etc/default/libc-locales and uncomment any locales you need, then run xbps-reconfigure -f glibc-locales.

You should find and take note of the block device representing the SD card. It will probably be /dev/mmcblk0, but run lsblk to double check. This guide will use /dev/mmcblk0, be sure to change it if necessary.

Now we'll finish preparing the storage partition we created earlier. We'll start by creating an ext4 filesystem on it:

mkfs.ext4 -L "Mucor-Storage" /dev/mmcblk0p3

We'll mount this at /mnt/storage:

mkdir /mnt/storage
mount /dev/mmcblk0p3 /mnt/storage

Now we need to add the partition to our fstab so it will mount on boot. We'll need to know its UUID for that, so we'll use lsblk to find it:

lsblk -o PATH,UUID
# PATH           UUID
# /dev/loop0     f3cd6547-f95a-46b8-91fd-9c9d819cd979
# /dev/mmcblk0
# /dev/mmcblk0p1 8382-5862
# /dev/mmcblk0p2 6557fbc9-8415-45b0-9a8d-92463bf670b1
# /dev/mmcblk0p3 2acef3cd-f95a-46b8-91fd-9c9d8b9cd979

Here we see that the (filesystem) UUID of /dev/mmcblk0p3 is 2acef3cd-f95a-46b8-91fd-9c9d8b9cd979.

Now edit /etc/fstab and add the storage drive with a line like this (use your own UUID!):

UUID=f3cd6557-f95a-46b8-91fd-9c9d8b9cd979 /mnt/storage ext4 defaults 0 2

We'll also add a bind mount from /mnt/storage/home-data to /home. This way any data stored in your home directory will be located on the storage partition, preserving space on the root partition. You can do the same with any other directories that might be taking up too much space. Enter a line like this:

/mnt/storage/home-data /home none bind 0 0

Now your fstab should look something like this:

UUID=fbc92ace-8415-45b0-9a8d-92463bf670b1 / ext4 defaults 0 1
UUID=8862-3825 /boot vfat defaults 0 2

# Storage partition
UUID=f3cd6557-f95a-46b8-91fd-9c9d8b9cd979 /mnt/storage ext4 defaults 0 2

# Bind mounts
/mnt/storage/home-data /home none bind 0 0

Run mount -a to ensure everything is mounted. The storage partition is now ready!

Now we'll configure our users. We need to give root a better password and create an admin user that we'll login as in the future.

Since we're already logged in as root, run passwd and follow the prompts to change the root password.

You may also want to give root a better login shell. Run chsh -l to see available shells. Run chsh -s /bin/bash to use bash, for example.

Next we'll create our admin account. The following command will create a user named nn with zsh as its login shell. Adjust it accordingly (and run xbps-install zsh if you do want to use zsh):

useradd -m -G wheel -s /bin/zsh nn

Now run passwd nn and follow the prompts to set a password for the account.

Run visudo -f /etc/sudoers.d/010_admin and write the following line into the file:

%wheel ALL=(ALL:ALL) ALL

This will allow users in group wheel (such as nn) to run any command via sudo, after providing their password.

In this section we'll secure our SSH configuration and authorize ourselves to login to our admin account via SSH. If you don't plan on using SSH, just run sv down sshd to disable the server.

We'll be disabling password logins completely and instead rely on SSH keys for greater security. First we'll authorize ourselves to login to the admin account. Do the following:

# Switch to our admin user and create a .ssh directory in the admin's home directory
su nn
cd
mkdir .ssh

Now edit .ssh/authorized_keys and paste in the public key you'd like to login with. Now we need to correct permissions:

chmod 600 .ssh/authorized_keys

Now run exit to return to the root user.

Now we need to secure our SSH server a bit. Edit /etc/ssh/sshd_config.d/010_restrict.conf. Add the following lines:

# Let's use a less obvious port
Port 22022
# We don't need to login as root, our admin can use sudo      
PermitRootLogin no
# Password authentication is insecure; disable it
PasswordAuthentication no

Now we need to restart the sshd server for these changes to take effect. Run sv restart sshd. My ssh connection survived the restart, but now is as good a time as any to log out of root and re-connect as nn with our public key.

Type exit to return to your host machine. Now type ssh -p22022 nn@192.168.1.23. If this works then you're done configuring users and can login as your admin user from now on.

Security is somewhat beyond the scope of this guide, but we will set up a basic firewall with UFW. Install UFW:

xbps-install ufw

We'll allow connections from inside our LAN only. You'll need to know where your router assigns addresses; this guide will use 192.168.1.0/24. Do the following:

# Deny all incoming connections
ufw default deny
# Except from inside our LAN
ufw allow from 192.168.1.0/24
# Start our firewall and set it to start at boot
ufw enable
ln -s /etc/sv/ufw /var/service/

If you want to login to the system with SSH from outside the network, run:

ufw limit 22022

This will rate limit (external) SSH connection attempts for additonal security.

§Finishing Up

You should now have a minimal, functional Void install on your Raspberry Pi, ready for you to build on. I plan to write more guides around Void Linux in the future, including one on ROOTFS installs.

For now, see my Void Cheatsheet for useful commands and packages to install.

Good luck! 🚀

§History

  • Edited 2024-09-15 to correct typo and better reflect best practices in configuring sudo and sshd.

Directory