Installing Arch Linux on the BeagleBone Black

Fri 19 August 2016


An Image

The BeagleBone Black in its Natural Habitat

I've been having a lot of run playing with a BeagleBone Black these days, which is a spiffy little single-board computer. In specifications it is similar to Raspberry Pi, but it has a lot of general purpose IO pins on it; you can think of it as a marriage between the Pi and an Arduino (in fact, it has two Programmable Realtime Units -- on-board micro-controllers -- so that you can do input and output with micro-controller-accurate timings, but I haven't really played with that yet).

The Debian Linux distribution is the recommended OS, and it's slick. The problem is that it comes with a whole lot of things enabled -- the OS itself takes up about 95% of the EMMC!

These days my Linux distribution of choice is Arch Linux, a minimalist distribution that's fun to use in the way that Slackware used to be fun in the early 90's. But the process of installing Arch on the BBB -- or any computer for that matter -- is a bit complicated. Even so, the Arch distribution only take up perhaps 25% of the memory, leaving plenty of room for doing stuff.

There is information on the web about installing Arch on the BBB, but there are a few conflicts and errors, so I wanted to put together a tutorial, from start to finish. I also wanted to bring a few different sources of information together in one place. I have a really bad memory, so if I want to do something twice I have to keep pretty detailed notes.

I used a laptop running Arch to do this, so it's arch all the way down.

Preparing the MicroSD Card

For this process you'll need a 4 GB microSD flash card and an adapter for your computer. The cards themselves sometimes come with a USB adapter, which is what I use.

The instructions here are largely correct (with an exception in the flashing process), but they leave a little to the imagination.

The first step, of course, is downloading the current version.

As a prerequisite, it's important to know which device the card represents itself as to your computer -- an error here could destroy your host computer's disk!

The easiest way to do this is to insert the card with a USB adapter and take a look at the output of dmesg:

[103078.114271] usb 1-1: new high-speed USB device number 7 using xhci_hcd
[103078.311179] usb-storage 1-1:1.0: USB Mass Storage device detected
[103078.311236] scsi host5: usb-storage 1-1:1.0
[103078.311295] usbcore: registered new interface driver usb-storage
[103078.312321] usbcore: registered new interface driver uas
[103079.316420] scsi 5:0:0:0: Direct-Access     Generic- SD/MMC   ....
[103079.901835] sd 5:0:0:0: [sdb] 7698432 512-byte logical blocks: ....
[103079.902058] sd 5:0:0:0: [sdb] Write Protect is off
[103079.902060] sd 5:0:0:0: [sdb] Mode Sense: 03 00 00 00
[103079.902270] sd 5:0:0:0: [sdb] No Caching mode page found
[103079.902272] sd 5:0:0:0: [sdb] Assuming drive cache: write through
[103079.904101]  sdb: sdb1
[103079.905158] sd 5:0:0:0: [sdb] Attached SCSI removable disk
[103080.194846] EXT4-fs (sdb1): mounted filesystem with ordered data mode...

so in this case the correct device is /dev/sdb.

Creating the Partition

You will want to zero-out the first few blocks of the card and create a partition (ext4, primary, including the whole disk). This can be done with the commands:

sudo dd if=/dev/zero of=/dev/sdb bs=1M count=8
sudo fdisk /dev/sdb

Danger Will Robinson: It's common practice when posting code snippets like the above to substitute something like /dev/sdX in the code, so that if someone just cuts & pastes without thinking nothing disastrous takes place. If I were a kind man I would do this too. But I haven't. So really, if you're following these instructions be careful. Verify which device the card presents itself as before you do anything with dd, fdisk, and the like!

As an example of the session:

mark@lucid:/usr/really-local/beagle/new$ sudo dd if=/dev/zero of=/dev/sdb bs=1M count=8
8+0 records in
8+0 records out
8388608 bytes (8.4 MB, 8.0 MiB) copied, 0.00818393 s, 1.0 GB/s
mark@lucid:/usr/really-local/beagle/new$ sudo fdisk /dev/sdb

Welcome to fdisk (util-linux 2.28).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x3e44d174.

Command (m for help): o
Created a new DOS disklabel with disk identifier 0x760035cb.

Command (m for help): p
Disk /dev/sdb: 3.7 GiB, 3941597184 bytes, 7698432 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
Disklabel type: dos
Disk identifier: 0x760035cb

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-7698431, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-7698431, default 7698431):

Created a new partition 1 of type 'Linux' and of size 3.7 GiB.

Command (m for help): w
The partition table has been altered.

Create the File System

sudo mkfs.ext4 -O ^metadata_csum,^64bit /dev/sdb1

Mount the File System and Create the Image

mkdir mnt
sudo mount /dev/sdb1 mnt
sudo bsdtar -xpf ArchLinuxARM-am33x-latest.tar.gz -C mnt
sync

Create the Boot Loader

This is a strange one -- we'll be writing data directly to a file system with dd:

sudo dd if=mnt/boot/MLO of=/dev/sdb count=1 seek=1 conv=notrunc bs=128k
sudo dd if=mnt/boot/u-boot.img of=/dev/sdb count=2 seek=1 conv=notrunc bs=384k
sync
sudo umount mnt

At this point we should be able to insert the card and boot it from the slot. Depending upon what OS is already on the BBB, you may -- or may not -- need to push the user boot button: with Debian it seems necessary, with Arch Linux it seems necessary to not push the button. Sometimes. Frankly, I haven't been able to figure out when the user boot button needs to be pressed. Try it first by pushing it, and if that doesn't work try it without the push.

Connecting for the First Time

One must boot the newly minted card and connect to the device. This is a bit easier if one has a regular BeagleBone laying about -- the BeagleBone has a USB serial console upon boot, which has been removed from the BBB. If you only have the Black, you'll need to attach the device to your network, examine the router to see what IP is assigned, and SSH directly (using the credentials alarm/alarm). If you have the BeagleBone, you can use the USB console:

sudo screen /dev/ttyUSB0 115200

You're now running Arch from the microSD. You'll want to configure it a bit and flash it to the internal memory.

Configuring the Card

Upon booting you will want to configure USB networking. This way you'll be able to connect directly over a USB cable, so you won't have to keep running over to your router whenever something needs attention.

The first thing to do is to enable the module that is needed for USB Ethernet:

echo g_ether > /etc/modules-load.d/g_ether.conf

Next you'll want to enable and start the USB network. First, create the file /etc/netctl/usb0 with the following content

Connection=ethernet
Description='Connection via USB'
Interface=usb0
IP=static
Address=('192.168.7.2/30')

And the interface needs to be enabled and started:

netctl enable usb0
netctl start usb0

At this point USB networking should be working, so you can boot down the BBB and attach it to your computer directly. Note, however, that we haven't brought DHCP up on the board, so your USB network interface will need to be assigned an IP address by hand (for which you should use 192.168.7.1). On my laptop I run Network Manager and this is very easy to do from it's widget.

If you have done the above and are now connected through the USB, the BBB, by default, will not be able to connect to the Internet. To do that you'll need to add a default gateway on the board and enable packet forwarding on your computer.

Default Route

route add default gw 192.168.7.1

Packet Forwarding

On the host machine you'll need to add port forwarding. On my laptop (running Arch) this can be done with the following commands (as root):

sysctl net.ipv4.ip_forward=1
iptables --table nat --append POSTROUTING --out-interface wlp4s0 -j MASQUERADE
iptables --append FORWARD --in-interface enp0s20u2u2 -j ACCEPT

On other machines the interfaces may have different names, but the procedure is the same. You can use the ip link command to see what your interfaces are named.

Update Your Software

Now you'll want to upgrade and at least install wget:

pacman -Syyuu
pacman -S wget

Flashing the BBB

The flashing of the device is similar to the initial card creation.

Download the Image and Install to Flash

For this process the device to use for partitioning is /dev/mmcblk1, and the partition is /dev/mmcblk1p1 (note that the naming convention is a little different than for /dev/sda, as there is an extra character):

wget http://os.archlinuxarm.org/os/ArchLinuxARM-am33x-latest.tar.gz
dd if=/dev/zero of=/dev/mmcblk1 bs=1M count=8
fdisk /dev/mmcblk1
mkfs.ext4 -O ^metadata_csum,^64bit /dev/mmcblk1p1
mkdir mnt
mount  /dev/mmcblk1p1 mnt
bsdtar -xpf ArchLinuxARM-am33x-latest.tar.gz -C mnt
sync

Write the Boot loader to Flash

Similarly:

dd if=mnt/boot/MLO of=/dev/mmcblk1 count=1 seek=1 conv=notrunc bs=128k
dd if=mnt/boot/u-boot.img of=/dev/mmcblk1 count=2 seek=1 conv=notrunc bs=384k

Configuring the Flash

The easiest way to configure the flash, now that it has been written, it to install the arch-install-scripts package and use the arch-chroot command:

pacman -S arch-install-scripts
arch-chroot mnt

We are now running in a chroted environment, and can configure the card. First, as always, we should upgrade:

pacman -Syyuu

We can do most of what we could do if we had booted directly to the card, such as create users, install software, configure the system, etc. Importantly, we probably want to enable USB networking as above. Changing the host name, installing avahi, and enabling it are also probably good things to do.

Once you've configured everything you want to configure. exit from the chroot shell, unmount the flash, and sudo poweroff. The next time you boot from flash you should have a new system installed.

Miscellaneous Configuration Stuff

rc.local

Perhaps I'm just old-school, but I like to have /etc/rc.local for site-specific stuff.

  1. Create /etc/rc.local

    The file should be valid from a shebang and chmod perspective.

  2. Create the Service file.

    Create a service file, /etc/systemd/system/rc-local.service

    This file should contain:

    [Unit]
    Description=/etc/rc.local compatibility
    
    [Service]
    Type=oneshot
    ExecStart=/etc/rc.local
    # disable timeout logic
    TimeoutSec=0
    #StandardOutput=tty
    RemainAfterExit=yes
    SysVStartPriority=99
    
    [Install]
    WantedBy=multi-user.target
    
  3. Enable with systemctl enable rc-local.service

VNC

For remote access it's useful to install and configure VNC on the device. This will allow you to work on a desktop remotely.

To do this a few packages must be installed:

  • fluxbox (or some other window manager)
  • x11vnc
  • xorg-server-xvfb
  • xterm
  • ttf-dejavu

For example:

pacman -S fluxbox x11vnc xorg-server-xvfb xterm ttf-dejavu

Next you will want to create a script to launch the vnc server:

#!/bin/bash

dbus-launch x11vnc -create -usepw -forever \
  -env FD_PROG=/usr/bin/startfluxbox \
  -env X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 \
  -env X11VNC_CREATE_GEOM=1700x1000x24

The first time the script is run it should be done manually (by the user under which the server should be run) so that the password can be entered. After this is done it can be added to rc.local to start automatically, for example:

sudo -u mark /home/mark/startvnc.sh &

will start the script as user mark.

Of course, other window managers can be used. If such is the case the FD_PROG entry in the above script should be changed.

I actually installed the enlightenment window manager once to see it if would work -- and it did -- but servicing the eye candy took about half of the CPU.

An Image

Fluxbox Running over VNC Connection

Random Numbers

The BBB has a hardware entropy source, so it's good to use it

  1. Install rng-tools

  2. Configure rngd.

    This is done by editing the /etc/conf.d/rngd file and placing the following in it:

    RNGD_OPTS="-o /dev/random -r /dev/hwrng"
    
  3. Enable the service:

    systemctl enable rngd
    systemctl start rngd
    
  4. Disable haveged (optional)

Note that there is a bug in the rngd service file that prevents it from starting at boot, so you'll probably have to manually start the daemon whenever you reboot (systemctl start rngd).

AVAHI

AVAHI/Bonjour/Zeroconf is useful, in that you can connect to your BBB via it's name (so you won't have to check your router for it's assigned IP address). Some computers -- like a MacBook -- will understand this natively, whereas others (like an Arch Host) will need a little configuration.

On the BBB:

pacman -S avahi
systemctl enable avahi-daemon.service
systemctl start avahi-daemon.service

The name it announces will be the name in /etc/hostname with .local appended, i.e.:

ssh kahuna@alarm.local ; # alarm is the default name for BBB Arch

If you're running Arch on the machine you're connecting from you'll first need to install a few packages:

pacman -S avahi nss-mdns
systemctl enable avahi-daemon.service
systemctl start avahi-daemon.service

You will also need to edit /etc/nsswitch.conf to include the following line:

hosts: files mdns_minimal [NOTFOUND=return] dns myhostname

Stuff Still to be Done

  • Setting up DHCPD on the BBB USB so that the host computer receives an IP address automatically.
  • Getting BoneScript up and running: Thus far I have been unable to compile or install a version of node.js that works with BonesScript.