Posts Tagged ‘headless’

Raspberry Pi with Arch Linux

November 26th, 2012 1 comment

Installation on SD-card

Installed Arch Linux on my raspberry pi. I didn’t want any gui schmui and this image seemed like a pretty clean option to me.

Downloaded the image, checked the sha1sum and dd’ed the file onto an sd card. (Determined the /dev/yoursddevice name by doing an fdisk -l)

sudo dd bs=4M if=/path/to/your/image/arch-linux.img of=/dev/yoursddevice

Waiting a few minutes, drinking some beer. Done.

Expanding the root partition

My card was 4GB and the downloaded img is only 2GB. This would result in some unused space and I wanted to use it. Add another partition or resize the current. Now is a good time as the device is not in use.

sudo fdisk -uc /dev/mmcblk0
Command (m for help): p
Disk /dev/mmcblk0: 3904 MB, 3904897024 bytes
64 heads, 32 sectors/track, 3724 cylinders, total 7626752 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0004f23a
        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1   *        2048      186367       92160    c  W95 FAT32 (LBA)
/dev/mmcblk0p2          186368     3667967     1740800   83  Linux
Command (m for help): d
Partition number (1-4): 2
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
Partition number (1-4): 2
# !!! Make sure next value is the same as the start of the deleted partition !!!
First sector (186368-7626751, default 186368): 186368 <-- That value! Same in this case, but can be different.
Last sector, +sectors or +size{K,M,G} (186368-7626751, default 7626751): 
Using default value 7626751
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

Wanted to run resize2fs but it prompted me to run e2fsck first.

sudo e2fsck -f /dev/mmcblk0p2

Resize the partition. (-p shows progress bar)

sudo resize2fs -p /dev/mmcblk0p2

Awesome, full SD-card will be available now. Unmount and put it in the rpi.
(I used a microSDHC (4GB, class 4) card from kingston with adapter which didn’t work. So I bought a set of regular 4GB class 4 SDHC cards from kingston)


In my first installations I just used the HDMI interface and an ethernet cable. Later I decided that it would be nice to have wifi as well. So I picked up an Edimax EW-7811Un Wireless USB Adapter.

You can set up your wireless interface in advance by mounting the new partition after writing the downloaded image with dd. Paths mentioned after this are of course relative to /mnt/sdcard

sudo mkdir /mnt/sdcard
sudo mount /dev/mmcblk0p2 /mnt/sdcard

To use it with the rpi I edited the /etc/conf.d/netcfg file and added ‘wireless-wlan0‘ to the networks array. I also added a DHCP_TIMEOUT=30 to allow for a bit more time for the wireless interface to get an IP-address.

# Enable these netcfg profiles at boot time.
#   - prefix an entry with a '@' to background its startup
#   - set to 'last' to restore the profiles running at the last shutdown
#   - set to 'menu' to present a menu (requires the dialog package)
# Network profiles are found in /etc/network.d
NETWORKS=(ethernet-eth0 wireless-wlan0)
# Specify the name of your wired interface for net-auto-wired
# Specify the name of your wireless interface for net-auto-wireless
# Array of profiles that may be started by net-auto-wireless.
# When not specified, all wireless profiles are considered.
#AUTO_PROFILES=("profile1" "profile2")

I then copied an example config:

cp /etc/network.d/examples/wireless-wpa /etc/network.d/wireless-wlan0

Originally it looks like this:

DESCRIPTION='A simple WPA encrypted wireless connection'
## Uncomment if the supplied ESSID is hexadecimal
# Uncomment this if your ssid is hidden

I only changed the ESSID and KEY values to match my wireless network settings. This is probably the most basic setup. For more advanced setups check out the netcfg and wireless sections in the arch wiki.

Reducing write cycles

I am not running any production-critical apps on my raspberry nor do I use any programs that require atime/relatime to be running. So I enabled the noatime option for the root partition and mounted /var/log as tmpfs as I don’t have any interest in these logs. (/tmp was already mounted as tmpfs)

My new /etc/fstab now looks like this:

# /etc/fstab: static file system information
# <file system>        <dir>         <type>    <options>          <dump> <pass>
/dev/mmcblk0p1  /boot           vfat    defaults        0       0
/dev/mmcblk0p2  /               ext4    defaults,noatime        0       0
tmpfs           /var/log        tmpfs   defaults,noatime,mode=0755,size=5%      0       0

Further installation

Inserting the sd-card into the Raspberry Pi. It booted okay. (If it is not check this list to see if your SD-card is compatible) Hostname was alarmpi at that moment so I just ssh-ed into it. You can scan with nmap if you don’t now which address your machine got. (Or check your router). Do this only when you have permission to scan the network. The command you could use looks something like this:

nmap -p 22 --open -sV | less
# My raspberry was listed as:
# 22/tcp open  ssh     OpenSSH 6.1 (protocol 2.0)
# MAC Address: B8:27:EB:XX:XX:XX (Unknown)
ssh root@alarmpi
   #password = root, so you probably want to change that asap. :)
   #and then create a new user so you don't have to login with root
useradd -m yourUserName
passwd yourUserName

I then ran a system update to prevent unfound packages later on:

pacman -Syu

I then installed vim. As my favorite editor.

pacman -S vim
ln -s $(which vim) /usr/local/bin/vi
ln -s $(which vim) /usr/local/bin/view

Changed the hostname to something else. (jukepi in my case, I want to use this one as a jukebox)

vi /etc/hostname
    #alarmpi -> yourHostName

I then disabled root login with SSH. (After testing my new account worked)

vi /etc/ssh/sshd_config

Uncommented PermitRootLogin and changed to ‘no’

PermitRootLogin no

Save and restart sshd

systemctl restart sshd

Changed my timezone with tzselect

    # Get the options

I modified /etc/timezone and added the outcome to the generic profile in /etc/profile

# Set our default path
export PATH
# Set timezone
export TZ
# Load profiles from /etc/profile.d

Reloaded the profile

source /etc/profile

Modified the /etc/ntpd.conf by adding a few ntp server to sync with.


And restarted the ntpd daemon

systemctl restart openntpd

And checked if date was correct by running date.

#Mon Nov 26 22:46:14 CET 2012

Installed alsa-utils and mpg123 for sound

pacman -S alsa-utils mpg123

Make sound module to auto-load. (It isn’t by default)

vi /etc/modules-load.d/snd_bcm2835.conf
# Load Sound

To play sound through jackplug: (Found this info here)

amixer cset numid=3 1

Or to play sound through HDMI:

amixer cset numid=3 2

Add your user to the audio group to have it play sounds.

usermod -G audio -a yourUserName

And test it if you like:

aplay police_s.wav

If you get this error:

ALSA lib confmisc.c:768:(parse_card) cannot find card '0'
ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name
ALSA lib conf.c:4246:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:4725:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM default
aplay: main:696: audio open error: No such file or directory

Then you need to add your user to the audio group. 🙂

usermod -G audio -a yourUserName
# to apply the group directly, you can start a new login shell
# su -l yourUserName

VLC (As a service)

Because I couldn’t play every audio stream I decided to install vlc. (Which conveniently comes with a web interface)

pacman -S vlc

I got some 404 messages while installing for several packages so I looked them up on google and downloaded/installed them by hand. (Presumably because my install was not up-to-date atm. Run pacman -Syu to upgrade to latest version)

wget ftp://blablabla/missing-packagename-version.pkg.tar.armv6h.pkg.tar.gz
pacman -U missing-packagename-version.pkg.tar.armv6h.pkg.tar.gz
pacman -S vlc

After running cvlc I got some pulseaudio messages. Stating that it was missing. 🙂

pacman -S pulseaudio pulseaudio-alsa
# libao to make mpg123 work with pulse
pacman -S libao
# change /etc/libao.conf 'alsa' => 'pulse' to make it work with pulse

After that I rebooted to make sure everything was loaded/working ok. (And it did, used paplay police_s.wav to test)

I edited the vlc http .hosts file to allow access from my network:

vi /usr/share/vlc/lua/http/.hosts
# And added

To run vlc headless with http interface:

cvlc --intf http --http-host <yourIpHere> --http-port 8080 <fileName|streamUrl>

Running VLC + PulseAudio is lot heavier than just mpg123 (~40% for VLC + ~10% for Pulse vs ~10% mpg123) but I like the flexibility it gives me.

I want to create some kind of jukebox so the next thing to do is to create a systemd service to run vlc.
We will first create the script which we will place in /etc/rc.d

sudo vi /etc/rc.d/vlc
case "$1" in
                echo "Starting VLC"
		su -l -c "/usr/bin/cvlc --intf http --http-port 8080 <fileName|streamUrl> &" <yourUsername>
                echo "Stopping VLC"
		killall vlc
                $0 stop
                sleep 1
                $0 start
                echo "usage: $0 {start|stop|restart}"
exit 0

Now we will create a systemd service file.

vi /usr/lib/systemd/system/vlc.service
Description=VLC Daemon
ExecStart=/etc/rc.d/vlc start
ExecReload=/etc/rc.d/vlc restart
ExecStop=/etc/rc.d/vlc stop

The last step is enabling the service.

systemctl enable vlc.service

Google Go

The next one to install is Google Go. I wanted to be able to spend the rest of the cpu power as effectively as possible.
At the moment there is no (official) package available for Google Go so we will have to build it from source.
I used Dave Cheney’s excellent tutorial to install it but then for Arch Linux. (No need to install libc6-dev btw) I made symbolic links in /usr/bin to the compiled binaries go, godoc and gofmt.


After completing your setup it might be a good idea to create a backup which you can tuck away for a rainy day. My previous SD-card was unrecoverable after some ungrateful and ungraceful shutdowns. To be able to get the system up and running asap we will create a gzipped image. Shutdown your rpi gracefully and let’s create an image of the sd-card.

dd if=/dev/mmcblk0 conv=sync,noerror bs=1M | gzip -c  > /mnt/yourbackuplocation/rpi.img.gz

Restoring the file:

gunzip -c /mnt/yourbackuplocation/rpi.img.gz | dd of=/dev/mmcblk0 conv=sync,noerror bs=1M