Or, why did I buy this again? Oh, right- it looked cool.
The Espressobin I purchased via the Globalscale kickstarter arrived Saturday and I finally took the time to work with it. It’s a rather neat machine that solves an issue I had with small system boards- I wanted a small format low-power router capable system and SBC’s either had a single ethernet port or were too costly to consider. The three independent ethernet ports and 1G of ram will ensure I won’t have any concern for resources. Additional hardware details for the espressobin is well covered in Globalscale’s website.
First, a bit of stumbling.
The bringup instructions for their board covers using Ubuntu 14.04 in good detail, but I wanted to use 16.04 as it’s more recent. Here, I’ll cover the issues I had and how I solved them. Credits go to Globalscale for their Ubuntu 14.04 instructions, on which these are based.
- First, there’s apparently no binary kernel on their website, so I used their instructions for installing the toolchain and kernel source to build a working kernel for the board. Too keep things simple, I just used the defconfig as instructed.
- Next, I needed some storage for the board. The version shipped to me doesn’t have an EMMC chip mounted, so I got an SD card and inserted it into my computer. Ubuntu automatically mounts the sdcard, so I had to umount it to continue as I’ll be changing the filesystem on it.
- Fdisk was used to change the partition type to 83 (linux). The use of fdisk in linux should be well understood and I’ll excuse myself from covering the topic in detail as I’m not generally a good instructor. Note that I only edited the partition type tag rather than zeroing out the MBR and repartitioning the card as Globalscale directs us to. This is done under the assumption that the SDcard manufacturer aligned the first block of the partition on one of the SDcard’s flash erase boundaries, and re-creating the partition may start the partition in the middle of an erase block and cause filesystem allocation blocks to span multiple erase blocks, reducing performance significantly. This theory is untested, so your results may vary. I have the belief the manufacturer would know how the partition should be aligned and would ship the card appropriately configured.
- Next I used mkfs.ext4 on the sdcard’s partition (mmcblk0p1 in my case as I have an onboard SDcard reader) since the u-boot config on the board can directly read ext4 filesystems. I ejected the SDcard, waited a few seconds for Ubuntu to realize it’s ejected, and re-inserted it to get it to remount.
- Time to drop Ubuntu into place. Since there’s no installer for this board, I got the 16.04 aarch64 tarball from ubuntu at http://cdimage.ubuntu.com/ubuntu-base/releases/16.04.2/release/ubuntu-base-16.04.2-base-arm64.tar.gz and unpacked it onto the sdcard. Be VERY careful as it contains a full root filesystem. If it’s errantly unpacked in the root directory on another unix-like system it WILL destroy it unrecoverably. Danger-danger, flailing arms, all that. Seriously.
- Now that we have a somewhat working root filesystem on the card, we need to copy the kernel that we built using globalscale’s instructions. Copying the kernel in is also covered in their website, so I won’t repeat them here.
- The Ubuntu 14.04 instructions for setting up ttyMV0 will apply to this install, and will offer us a login prompt. Add the content below to /etc/init/ttyMV0.conf.
start on stopped rc or RUNLEVEL=
stop on runlevel [!12345]
exec /sbin/getty -L 115200 ttyMV0 vt100 -a root
- All that was left was to resolve some dependencies for smoothly running apt and debconf. The stock tarball for 16.04 is very minimally installed and configured, so some additional packages and configuration was necessary to get a quietly running system. These steps are below.
At this point the startup went swimmingly indicating that ubuntu 16.04 runs happily with the kernel source and toolchain globalscale provided. However, there was an issue with ttyMV0.conf timing out. Research discovered some things that were mising, most specifically udev. Also, Ubuntu 16.04’s stock getty doesn’t appear to auto-log in so we’ll have to set a root password and permit logins.
[add prose to seem clever] [possibly leave this here for a chuckle] [okay, chuckle it is.]
In the end, the steps I took to build a brand new image are below. Hopefully I didn’t forget to document any of them.
- Insert sdcard and discover its device ID. Mine’s fixed at /dev/mmcblk0 since it’s not a USB-type reader.
- Umount the partition that gets automatically mounted
- Use fdisk to tag partition 1 on the card as type 83 (linux) and mkfs.ext4 to reformat the partition
- remount the sdcard and cd to its mountpoint
- host$ curl /ubuntu-base/releases/16.04.2/release/ubuntu-base-16.04.2-base-arm64.tar.gz |tar zxvf – DANGER! Make sure you’re in the sdcard’s directory before doing this. It streams the tarball from the web rather than downloading it, so it’ll unpack immediately to wherever you type the command.
- host$ apt install qemu-user-static on the host system so we can run arm64 binaries
- host$ cp /usr/bin/qemu-static-aarch64 usr/bin/ on the sdcard so the system will find it during the chroot setup.
- host$ cp /etc/resolv.conf etc/resolv.conf so that DNS will work within the card’s environment
- host $ chroot . (include the dot at the end, it indicates to chroot into the current location). The prompt won’t change much, so use uname -m to ensure you see aarch64 instead of your host’s native architecture.
- chroot$ apt update
- chroot$ apt install net-tools udev ifupdown vim iputils-ping less whiptail apt-utils ; It’s important to note that many warnings and errors may come up during this step. It has a lot to do with being in a chroot without /proc mounted, and a little to do with just being in a chroot jail.
- chroot$ passwd root
- chroot$ echo ttyMV0 >> /etc/securetty
- chroot$ exit
- Install the kernel and dtb as instructed on Globalscale’s page
- Set up u-boot as instructed on Globalscale’s page
- sync, umount, insert into espressobin, and hopefully smile as you see Ubuntu boot up and request a login on the USB serial console.
- Log in as root, using the password you entered earlier, and then fix language warnings by typing: locale-gen en_US.UTF-8
- disable unusable VTY’s with: for i in 1 2 3 4 5 6; do systemctl mask getty@tty$i.service; done
- Edit or create /etc/network/interfaces (you may need to install your favorite editor first) and add:
iface eth0 inet manual
iface lo inet loopback
iface lan1 inet dhcp
pre-up /sbin/ifconfig lan1 up
My biggest stumbling block was the networking failing to start up. I discovered that lan0, lan1, and wan won’t work unless eth0 is up. The network tools will bring the interfaces up in parallel so lan1 comes up before eth0 is ready, and will stay down. The key here is the pre-up statement on lan1, bringing it up manually before running dhcp.
- set /etc/hostname to something meaningful (in my case, I used espressobin)
So what am I going to do with this machine? It’ll likely serve as a router in the future. Embedded routers are great for most people, but I use a dhcp configuration that I haven’t figured out how to do with the options offered by factory, ipfire, or *wrt distributions. Also, I do have a mild preference for managing most things via ssh rather than a WWW interface. It’s a matter of personal preferences as it’s how I initially learned to do many things in linux, including setting up NAT under ipfwadm and then ipchains.
Before I use the system as a router I’ll explore its other capabilities, such as the apparently fully functional mini-pci express slot as well as the sata interface. I’d like to some day be brave enough to try mounting an EMMC chip on the pads Globalscale left in place. Maybe.
My only real issue with the board is the little power LED. I could probably hang it above an average solar panel and power a house with the light it puts out. Okay, probably not. However it is blindingly bright. Hopefully Globalscale will revise the BOM by changing to a larger dropout resistor so it doesnt go to solar mode while powered up.
Thanks for reading. 🙂