6.8 KiB
+++ title = "Arch on a Raspberry Pi - the basics" date = 2020-09-26 tags = ["raspberry pi"] toc = true +++ Installing Arch on a Raspberry Pi is amazingly easy. the Arch ARM project gives instructions for the basic installation here.
Chroot into the SD card
When you finished installing the basic system to the SD card, you may wish to
install the following packages in your host system (we'll suppose your host
system is already an Arch linux) : arch-install-script
that provides the
arch-chroot
command, and qemu-user-static-bin
, that provides the means to
run ARM binaries from the host system. Then you can mount the SD card on e.g.
/mnt
and do :
# arch-chroot /mnt
arch-chroot
will mount all useful mounts like /mnt/proc
, /mnt/sys
,
/mnt/dev
, and event /mnt/boot
if it's in /mnt/etc/fstab
. When you're done,
it will clean everything and hopefully let you unmount the drive cleanly.
Setup SSH
Over there you can modify your target system, which provides a user named pi
.
You might use that or add a user. Make sure you set up ssh login credentials. If
in doubt check Archlinux wiki's OpenSSh page ; I believe it's
installed by default on archlinuxarm.
When you're done just hit Ctrl-d
to unbind the chroot.
Networking
The tricky bit is to be able to log into it on a headless config. You will have to make sure it's reachable on the network so you can ssh into it. There are a few options here : if the RPi provides an ethernet plug, connect over ethernet. If not (as for the RPi zero series), connect with USB over ethernet. If you need (or crave) to connect wirelessly, the wifi leaves you options to either make it connect to your local network, or turn the RPi into a wifi hotspot.
Note that wireless networking does imply a certain overhead ; you might consider turning it off when in production use, specially when running JACK (I read it somewhere in a JACK tutorial page but I can't remember where).
Wired over USB
Skip this part if your RPi has an ethernet socket. Else chroot in the SD card.
Add the following to /boot/cmdline.txt
:
modules_load=dwc2,g_ether
Now into /boot/config.txt
, add the following line :
dtoverlay=dwc2
This will let the system load an ethernet over USB module at boot-time. To have it setup at boot-time run :
# systemctl enable systemd-networkd
And create or edit /etc/systemd/network/01-usb.network
so that it reads :
[Match]
Name=usb*
[Network]
LinkLocalAddressing=ipv4
IPv4LLRoute=yes
get out of the chroot, unmount the SD card and boot.
Wireless - connect to a local network
You will need the wpa_supplicant
package, and a systemd service to launch it.
Chroot into the SD card, and run as root :
# pacman -S wpa_supplicant
wpa_supplicant
can be started by systemd-networkd
: edit/create
/etc/systemd/network/05-wlan.network
with the following contents :
[Match]
Name=wlan*
# Run as a client with wpa_supplicant
[Network]
DHCP=ipv4
MulticastDNS=yes
Now edit or create /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
, and add your
local network credentials. Refer to man wpa_supplicant.conf
for details. The
syntax is :
network={
ssid="THE_NAME_OF_YOUR_ACCESS_POINT"
psk="THE_ACCESS_POINT_PASSWORD"
}
systemd-networkd
will start wpa_supplicant@wlan0.service
, who will in turn
use the latter config file to run. You can quit the chroot, unmount the SD card
and boot it ; the system should connect to the local network at boot-time. You
can add Access Points at run-time with the wpa_passphrase
utility, like in :
wpa_passphrase AP_NAME AP_PASSWORD | sudo tee --append
/etc/wpa_supplicant/wpa_supplicant-wlan0.conf
Wireless - fallback to hotspot
It can be very handy to fall back to setting up an Access Point if we can't
connect to any known network. This way you're still able to ssh
back into the
RPi and for instance register a new Access Point to connect to. This trick was
derived from this post.
wpa_supplicant
provides this feature with a rather ... cryptic manner ; see by
yourself :
# AP configuration as a fallback :
network={
ssid="RPi"
mode=2
priority=-999
key_mgmt=WPA-PSK
psk="a rather long raspberry pi password"
frequency=2412
}
You just insert this snippet in /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
so that it gets loaded only if the other networks are not found. It doesn't have
to sit in the bottom, so you can still append more attractive APs with
wpa_passphrase
. Even if you don't use the priority
option, wpa_supplicant
will be smart enough to load it only if no known host is found. The RPi Zero W
doesn't do 802.11g, it's only capable of 802.11b, but you don't need to tell it,
it will handle that. I actually tested all these options, because I couldn't
find documentation on these features.
But it won't give you or your client an IP address - for this a DHCP server is
needed. The RPi can act like one with the dnsmasq
package, who will in turn
require the interface to be setup with a static address. As stated in this
StackExchange discussion, you can have several addresses on
the same interface at the same moment. So in
/etc/systemd/network/05-wlan0.network
, append this line to the [Network]
section :
Address=192.168.2.1/24
We just want dnsmasq
to run if the RPi is in Access Point mode. Systemd can
help here, you may add a conditional on dnsmasq.service
's execution with the
following snippet :
file: /etc/systemd/system/dnsmasq.service.d/only-if-we-are-an-AP.conf
# Insert a test that fails if the device is not an Access Point.
[Unit]
After=wpa_supplicant@wlan0.service
[Service]
ExecStartPre=/bin/sh -c 'eval $(wpa_cli -i wlan0 status) && test "$mode" == "AP"'
[Install]
WantedBy=wpa_supplicant@wlan0.service
If you want to know what it does, try sudo wpa_cli -i wlan0 status
; you'll
see it outputs various informations about the network device, including its
mode, with possible values AP
and managed
. The above test succeeds only if
the interface is configured as an Access Point. And Systemd services fail if any
of the ExecStartPre instructions fail. The drawback of this setup is that the
service will simply appear as failed in journalctl, with no explanation.
Copy the snippet to the given location, reboot. If you can't ping the RPi on the local network, look for it in the available APs. Connect to it, ssh it. You're done !