Tune up Arch Linux Installation on Raspberry Pi

It so happened that I’ve got one of those marvelous ARM GNU/Linux based Raspberry Pi boxes and decided to move my existing Mediawiki installation on it. This was basically due to very low power consumption needed by the pi (<5W).

Here’s a list of hardware that is in place:

  1. Raspberry Pi Model B (512MB SDRAM)
  2. SanDisk 8GB Ultra Class 10 UHS-I SD 30MB/s
  3. SanDisk 16GB Cruzer USB Memory Stick (SDCZ33-016G-B35)
  4. Aluminium heatsink, size 15mm x 15mm x 8mm (H x W x D)
  5. 5V 1500mA Micro USB Power Supply
  6. CAT5 Ethernet cable

USB stick will be used to keep database backup etc.

Today’s plan is to install Arch Linux onto SD card and tune up the default OS configuration. After that, we’ll go about installing LAMP and Mediawiki.

General disclaimer applies, no liability will be accepted for any loss or damage, use at your own risk and do frequent backups!

Initial Post-Installation Housekeeping (via Monitor and Keyboard)

The first thing to do is to change default root password:

# passwd

Then add our own regular user:

# useradd -m -s /bin/bash sandy
# passwd sandy

We also need to configure SSH server to be able to work remotely. Open:

# vim /etc/ssh/sshd_config

and change the following settings appropriately (check OpenSSH Server: Installation and Configuration for more detailed options):

Port 12             # change the default SSH port, no low hanging fruit
Protocol 2          # force the protocol 2
SyslogFacility AUTH 
LogLevel INFO       
LoginGraceTime 60   
PermitRootLogin no  # disable root login
AllowUsers sandy    # allow only our user to login
DenyUsers root      
DenyGroups root     
StrictModes yes     
PasswordAuthentication yes
PermitEmptyPasswords no
UsePAM yes

Restart SSH daemon:

# systemctl restart sshd

SSH should now be listening on port 12.

Initial Post-Installation Housekeeping (via SSH)

As we may see, SD card size is not fully utilised, therefore we need to extend it to maximum. Below is presented the initial disk partition table after imaging Arch (archlinux-hf-2013-07-22.img) onto 8GB SD card:

# fdisk -l
Disk /dev/mmcblk0: 7948 MB, 7948206080 bytes, 15523840 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 label type: dos
 Disk identifier: 0x00057540
Device Boot Start End Blocks Id System
 /dev/mmcblk0p1 2048 186367 92160 c W95 FAT32 (LBA)
 /dev/mmcblk0p2 186368 3667967 1740800 5 Extended
 /dev/mmcblk0p5 188416 3667967 1739776 83 Linux

Let’s extend /dev/mmcblk0p5 partition to fill the whole available SD card space (careful here!):

 # fdisk /dev/mmcblk0
 p
 d
 2
 n
 e
 (return) # accept default partition no
 (return) # accept default start
 (return) # accept default end
 n
 l
 (return) # accept default start
 (return) # accept default end
 p
 w

Reboot the system to let the kernel pick up our changes:

# reboot

Once system is back online, we can check partition tables:

# fdisk -l
Disk /dev/mmcblk0: 7948 MB, 7948206080 bytes, 15523840 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 label type: dos
 Disk identifier: 0x00057540
Device Boot Start End Blocks Id System
 /dev/mmcblk0p1 2048 186367 92160 c W95 FAT32 (LBA)
 /dev/mmcblk0p2 186368 15523839 7668736 5 Extended
 /dev/mmcblk0p5 188416 15523839 7667712 83 Linux

As we can see above, partitions were successfully extended – good. Let’s now check disk usage:

# df -h | egrep 'File|root'
Filesystem Size Used Avail Use% Mounted on
/dev/root  1.7G 444M 1.2G   28% /

Resize the filesystem:

# resize2fs /dev/mmcblk0p5

And disk usage again:

# df -h | egrep 'File|root'
Filesystem Size Used Avail Use% Mounted on
/dev/root  7.3G 445M 6.5G    7% /

All looks good. Next step is to create a swap file:

# fallocate -l 100M /swapfile
# chmod 0600 /swapfile
# mkswap /swapfile
# swapon /swapfile
# echo "/swapfile none swap defaults 0 0" >> /etc/fstab

Time to upgrade the list of packages as well as upgrade the packages installed on the system:

# pacman -Syu

I like to colour regular user’s bash prompt (in green) to distinguishing it from the root prompt. A habit. So, we need to switch to our regular user now:

# su sandy

Open:

$ vim ~/.bashrc

Comment out the default prompt:

#PS1='[\u@\h \W]\$ '

Add the following green prompt:

PS1='\[\e[1;32m\][\u@\h:\w]\$\[\e[0m\] '

We have to logout and login back again to notice changes. OK, need to do the same for root user. Switch back to root:

$ su root

Open root’s .bashrc file if one exists or simply copy it from /etc/skel if the file is not present.

# vim /root/.bashrc

Assign a red prompt for root:

PS1='\[\e[1;31m\][\u@\h:\w]\$\[\e[0m\] '

Again, we need to logout and login to see changes.

Another thing to do is to set up a hostname:

# echo arch > /etc/hostname

Add a suitable timezone:

# ln -s /usr/share/zoneinfo/Europe/London /etc/localtime

Configure system-wide locale. Default setting on Arch-berry are below:

 # locale
 LANG=C
 LC_CTYPE="C"
 LC_NUMERIC="C"
 LC_TIME="C"
 LC_COLLATE="C"
 LC_MONETARY="C"
 LC_MESSAGES="C"
 LC_PAPER="C"
 LC_NAME="C"
 LC_ADDRESS="C"
 LC_TELEPHONE="C"
 LC_MEASUREMENT="C"
 LC_IDENTIFICATION="C"
 LC_ALL=

Let’s see what’s available by default:

# locale -a
 C
 POSIX

Nothing much, as expected. Open:

# vim /etc/locale.gen

Uncomment any preferred locale:

[...]
#en_DK ISO-8859-1
en_GB.UTF-8 UTF-8
#en_GB ISO-8859-1
[...]

Generate locale:

# locale-gen

Check available locales again:

# locale -a
C
POSIX
en_GB.utf8

Much better now. We need to set some locale preferences in /etc/locale.conf:

# echo LANG="en_GB.UTF-8" > /etc/locale.conf
# echo LC_TIME="en_GB.UTF-8" >> /etc/locale.conf
# echo LC_COLLATE="C" >> /etc/locale.conf

And then update the system:

# locale-gen

And finally, the best part – overclocking! We’ll use fairly modest setting for now to avoid going too extreme…

Open:

# vim /boot/config.txt

Set the following parameters:

#Modest
arm_freq=800
arm_freq_min=100
core_freq=250
core_freq_min=75
sdram_freq=400
over_voltage=0

A reboot is needed for new settings to take effect:

# reboot

OK, the last bit left to do is to test how stable our raspberry pi is (well, you never know). Create a stress test file:

 # touch /root/stress-test.sh
 # chmod 0700 /root/stress-test.sh

Open the file and add the following lines:

#!/bin/bash
#Original script was taken from http://elinux.org/RPiconfig
#Simple stress test for system. If it survives this, it's probably stable.
#Free software, GPL2+
 echo "Testing overclock stability..."
#Max out the CPU in the background (one core). Heats it up, loads the power-supply.
 nice yes >/dev/null &
#Read the entire SD card 10x. Tests RAM and I/O
 for i in `seq 1 10`;
 do echo reading: $i;
 uptime >> /root/load.log;
 /opt/vc/bin/vcgencmd measure_temp >> /root/load.log;
 dd if=/dev/mmcblk0 of=/dev/null bs=4M; done
#Writes 512 MB test file, 10x.
 for i in `seq 1 10`;
 do echo writing: $i;
 uptime >> /root/load.log;
 /opt/vc/bin/vcgencmd measure_temp >> /root/load.log;
 dd if=/dev/zero of=deleteme.dat bs=1M count=512; sync; done
#Clean up
 killall -9 yes #just to make sure it's really killed
 rm deleteme.dat
#Print summary. Anything nasty will appear in dmesg.
 echo -n "CPU freq: " ; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
 echo -n "CPU temp: " ; cat /sys/class/thermal/thermal_zone0/temp
 dmesg | tail
echo "Not crashed yet, probably stable."

Run the stress test if brave:

# /root/stress-test.sh

P.S. Raspberry Pi passed the test.

Next thing on our list – set up Logwatch, SSMTP and Iptables.