Setting Up Arch Arm on Raspberry Pi 4


Published on 2020-05-15 by Kenneth Flak

Back to Tech Research


Table of Contents

Recently we got a request to perform on a street-festival in Pärnu, which gave us the impetus to get a bit more mobile with our technology. We already own a battery-powered boombox, so now we needed something a bit smaller than a laptop to deliver sensor-triggered sound to the box. An obvious candidate for this is the Raspberry Pi 4, which, if rumors are correct, has become quite a powerful little beast.

This is a record of the steps I took to set the rpi up with my Linux distro of choice Arch, make it possible to receive data from our minibees and trigger stuff in SuperCollider using it. Let's get to it! Much of the information is taken from Mads Kjeldgaard's blog and translated to Arch equivalents. Additionally there is a lot of good information in Niklas Adam's blog.

Installing Arch

Arch ARM is actually a separate distro targeted at the ARM architecture. I followed this guide for the basic setup.

First of all: figure out what my SD card is called:

$ lsblk
NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                     8:0    1  28.9G  0 disk  
└─sda1                  8:1    1  28.9G  0 part  

The card is called sda, which means it will be available at /dev/sda.

Next, partition the card:

sudo fdisk /dev/sda

For the rest, follow the instructions.

Now on to the interesting stuff: connect to the Rpi through your network. As I intend to use the Rpi in headless mode, I want to set it up for remote control. So, plug an ethernet cable into the appropriate pi-hole and connect it to the local network. Then run nmap -sP 192.168.1.0/24 to get a full list of the active ip addresses on your network. In my case this returned 192.168.1.125 for alarmpi.lan.

This is where your inner Hollywood hacker gets to shine. Run the following command:

ssh alarm@192.168.1.125

and when prompted for the password type the default alarm.

Rooting it

In order to get anything done while in the depths of you Rpi, you need to become a root user. At first I tried sudo, but this didn't fly, so I had to do su instead, and, when prompted, punch in the default root password root. From here I was able to do

pacman-key --init
pacman-key --populate archlinuxarm

which are essential to turn your Rpi into a computer.

Update your system and the pacman database:

pacman -Syy
pacman -Syu

We need to make a ssh session behave like a normal terminal session. The first thing I noticed was that every backspace was read like a space in the Rpi, which is not very conducive to hard labor. So me being a termite user I had to go:

pacman -S termite-terminfo

Log out and log out again. Now your ssh should behave properly.

su-ing every time you want to perform system administration tasks soon becomes both tedious and unsustainable, so you want to enable sudo. pacman -S sudo to the rescue. Then visudo, uncomment the line that says # %wheel ALL=(ALL) ALL, save and exit the editor. Next, let's get our toolbox in order.

sudo pacman -S neovim tmux git git-lfs zsh man fzf trash-cli base-devel python python-pynvim w3m

Get yourself an aur helper:

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

From now on you will be able to search and install from the arch repos and aur by typing yay <package>

Create User

Keeping the default alarm user around might be nifty for the initial setup, but I prefer to be myself and use the same username for my main computer and the Rpi:

sudo useradd -m <user> -p <password>
sudo usermod -a -G wheel,audio <user>

Log out of the session, and log back in again as your new user. You should be able to use sudo. If you can't get in, then go back in as alarm and run

sudo passwd <user>

to make sure you have the correct login credentials. It is also a VERY good idea to change passwords for both alarm and root.

Set Hostname

sudo hostnamectl set-hostname <new_hostname>

Next, sudoedit /etc/hosts and fill in this:

127.0.0.1 localhost
::1 localhost
127.0.1.1 <new_hostname>.localdomain <new_hostname>

This sets up an alternative address for the computer for the ssh session. IP addresses can change, but this name won't.

Generate Locale

sudoedit /etc/locale.gen

Uncomment the locale you want to use and run:

sudo locale-gen

Set Local Time

If /etc/localtime does not exist you need to create the symlink:

ln -s /usr/share/zoneinfo/Europe/Tallinn /etc/localtime

Replace with appropriate timezone.

Zsh

I prefer zsh to bash. To change the default shell, run chsh -s /bin/zsh (if, that is, you have installed it). To get syntax highlighting in the shell (highly recommended), run this:

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
echo "source \
${(q-)PWD}/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" \
>> ${ZDOTDIR:-$HOME}/.zshrc 

To get your prompt a bit more beautiful than default zsh, you can do worse then pure. Run these commands to get hold of it:

mkdir $HOME/.zsh
cd .zsh
git clone https://github.com/sindresorhus/pure

To enable the prompt add these lines to .zshrc:

fpath+=$HOME/.zsh/pure
autoload -U promptinit; promptinit
prompt pure

Exit the ssh session, log back in again, and you should be good to go.

Dotfiles

I keep my dotfiles in a gitlab repo, so that they are but a git clone https://gitlab.com/kflak/dots.git away. My strategy is simply to keep all the dotfiles I want to track in a central repo and symlink them to the necessary locations.

However, a lot of my laptop-specific stuff is specific to the laptop, and i don't need it on my Rpi. So instead of messing too much with an existing .zshrc, I opted to scavenge the dots repo, copying ~/dots/init.vim to ~/.config/nvim/init.vim, dots/zshrc to ~/.zshrc and edit them to fit Rpi's more modest requirements.

Next up: getting my nvim-plugs to work! I use vim-plug as my plugin manager. Installing it should be a simple matter of running:

sh -c 'curl -fLo \
$HOME/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

Be aware that there are security risks involved in piping curl to a script, so only do this if you are ok with the risk. Otherwise do it the proper way: download the script and inspect it before running it.

Ssh-agent

After a while of ssh-ing it gets a bit tedious to keep typing your password every time you want to log in to the rpi. Enter ssh-agent and friends! First of all you need to generate a pair of keys on your work computer (not the rpi) with the command ssh-keygen. You will be asked for a password. The keys will be created in ~/.ssh/. Next you need to copy the public key over to the rpi:

ssh-copy-id '<user>@<ip-address-of-pi'

Next, run:

eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa

Enter password and that should be it! Now you can ssh into the rpi without password! More detailed information can be found in this tutorial.

To make the ssh-agent run for the entire session, I put this into my ~/.zlogin file:

eval $(ssh-agent)
ssh-add

From now on I have to type the password once per user session, instead of every time I fire up a new terminal window.

Realtime Kernel

A realtime kernel is pretty much essential when working with realtime audio. Luckily a readymade kernel is available so you don't have to go through the troubles of compiling one for yourself. Thom Johansen over at Notam has done all the hard work, and you can download it from here. The next bit is a little bit fiddly, but if you keep your head straight, it should work without a hitch. I assume that the tar.gz file lands in your ~/Downloads folder. I followed the instructions from this tutorial. As the kernel is already compiled, I only had to do the last bit. On my main computer:

scp ~/Download/rt-kernel.tar.gz <user>@<ip-of-rpi>:/tmp

On the Rpi:

cd /tmp
tar xzf rt-kernel.tar.gz
cd boot
sudo cp -rd * /boot/
cd ../lib
sudo cp -dr * /lib/
cd ../overlays
sudo cp -d * /boot/overlays
cd ..
sudo cp -d bcm* /boot/

Next, edit the boot parameters:

sudoedit /boot/config.txt

and add kernel=kernel7l.img to the end of the boot parameters. sudo reboot, grab a coffee, and return to your computer when the rpi is back. Verify that you are running the rt-kernel by typing uname -r. If it says something like 4.19.71-rt24-v7l+ you are good to go!

Setting Performance Parameters

Install realTimeConfigQuickscan, an essential tool for diagnosing your audio setup.

yay -S realtimeconfigquickscan-git

Look around and see what is needed. The official way of setting cpupower to "performance" is to put it in the /etc/default/cpugovernor file, but this didn't seem to stick on reboot, so I created a systemd service instead.

/etc/systemd/system/cpupower.service
---
[Install]
WantedBy=multi-user.target

[Unit]
Description=Set cpugovernor to performance

[Service]
Type=simple
ExecStart=/usr/bin/cpupower frequency-set -g performance

Start the service and enable it on startup:

sudo systemctl enable --now cpupower.service

Install alsa-utils, jack and realtime-privileges:

sudo pacman -S alsa-utils jack2 realtime-privileges
# add user to realtime-group
sudo usermod -a -G realtime <user>

In order to use the onboard audio device you need to add

dtparam=audio=on

Reboot and run aplay -l to confirm that alsa sees the soundcard. The output should look something like this:

card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 7/7
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  ...

SuperCollider

At first I was very happy to learn that SuperCollider is just a sudo pacman -S supercollider sc3-plugins away. However, there was a hickup: the mesa dependency couldn't be downloaded. It turned out to be a simple matter of updating the pacman database: sudo pacman -Syy. Something I should have done immediately upon installation, of course...

The next major obstacle was to get SuperCollider to run in a headless environment using the distribution-provided version. Luckily this is not as difficult as it used to be, with a recent qt bugfix. Simply set the QT_QPA_PLATFORM environment variable to offscreen, either in your terminal session or, more permanently, in your .zshrc:

export QT_QPA_PLATFORM=offscreen
source ~/.zshrc

Test your supercollider setup with this little snippet:

~/test.scd
---
s.waitForBoot({{SinOsc.ar}.play});

and run it:

sclang ~/test.scd

If all is well, you should now hear a 440hz sinewave in your left speaker.

In a headless environment you will not be able to use the official SuperCollider IDE. I highly recommend David Granström's scnvim for Neovim. Check out the github repo for installation instructions!

MiniBee Movement Sensors

Now that we have SuperCollider up and running, the next step is to get MiniBees to talk to it. The commandline client for receiving data from MiniBee is called pydon-cli and is written in python 2. This is not included in the base installation, so:

sudo pacman -S python2

Next, we need to clone the repo and run the installation script. I do this in ~/build, but it's up to you where you want to put it.

mkdir ~/build
cd ~/build
git clone https://github.com/sensestage/ssdn_python.git
cd ssdn_python
# invoke script as root with python2, otherwise it won't work
sudo ./installation.sh python2

Connect the receiver to the usb port and run pydoncli.py in a directory where you have a pydon-config. If you get a lot of scrolling text complaining that pydoncli could not open serial port, the first thing to do is to check which port the receiver is connected to. Run ls /dev/tty* without the receiver plugged in, and once more with it plugged in. The extra port that shows up is the correct one. In my case it is /dev/ttyUSB0, so I try once more to run pydoncli.py -s /dev/ttyUSB0. If this still doesn't work you are probably experiencing a permissions problem. Verify this by running

sudo chmod 666 /dev/ttyUSB0 

and try once more. You should now have a working board.

You definitely don't want to do this every time you connect your minibee receiver, so add this udev rule to your system:

/etc/udev/rules.d/52-xbee.rules
---
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", GROUP="users", MODE="0666" 

And that should be it! If all is well you now have a working installation of Arch Linux ARM on your Raspbery Pi 4 as well as a SuperCollider environment.

If you have feedback or questions, feel free to get in touch!