Setting Up Arch Arm on Raspberry Pi 4
Published on: 2020-05-15
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 QTQPAPLATFORM 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!