ugly surprises with raspbian buster and external file systems

A while back I wrote about adding an SSD to a Raspberry Pi 4 and modifying /etc/fstab so that it would automatically mount when it booted. This is different than having it automount through /media/pi, since that type of automount only occurs after the OS is fully up and then scans for attached devices, such as those on USB. For nearly all use cases you can’t tell one from the other. But for those very few use cases where you need the kernel to mount the attached storage device before the rest of the system comes up, you need to define it in /etc/fstab.

That wasn’t a problem with Raspbian Buster up until just recently. Before that time, I had an entry for my SSD in fstab that started out like this:

/dev/sda1 ...

It worked just fine, until one day after a recent update that included the kernel, it didn’t. No warning that this was going to happen, none at all. After the update and subsequent reboot, the Raspberry Pi refused to boot, and instead dropped me into a prompt waiting for me to log in as root to fix the problem. Oh, wait, root is disabled by default in Raspian, so that just put me in an endless boot loop.

It took two attempts rebuilding a minimal boot micro SDXC before I finally figured out what was happening. Fortunately, that second micro SDXC card was a new one with a minimal Raspbian system, so it didn’t take too much effort to see that adding the entry to /dev/sda1 was causing it to fail to boot. Fortunately for me I have other Linux systems (my ten-year-old Samsung R580 running Ubuntu 18.04.04 came to the rescue) that allowed me to mount both micro SDXC cards, edit fstab and remove the entries. Once removed, both micro SDXC cards booted just fine in the Raspberry Pi 4.

Once I got back in I enabled root with ‘sudo passwd root’ and gave it a password. Now, if I have a problem where a Raspbian boot failure wants to dump me into the root account in single user mode, I can actually log in at that point.

The other problem was getting the USB SSD to mount. Here’s what I did to fix that. But first, a tiny bit of background.

The kernel in Raspbian buster uses what’s now known as a PARTUUID to identify a storage device instead of the old school device name in /dev. To find out what that PARTUUID is, you have to run this command at the command line in a terminal window:

pi@rpi4-4-01:~ $ sudo blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="69D5-9B27" TYPE="vfat" PARTUUID="d9b3f436-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="24eaa08b-10f2-49e0-8283-359f7eb1a0b6" TYPE="ext4" PARTUUID="d9b3f436-02"
/dev/sda1: LABEL="SSD" UUID="ad89d540-a007-4d0a-887b-0b0dbefe3e8e" TYPE="ext4" PARTUUID="937a0120-01"
/dev/mmcblk0: PTUUID="d9b3f436" PTTYPE="dos"

Since I already know the label on my SSD is “SSD” it’s quickly identifiable in blkid’s output. Copy the PARTUUID at the end of the entry, and use that in the fstab entry for the drive, like so:

PARTUUID=937a0120-01 /ssd ext4 defaults,auto,users,rw,nofail,x-systemd.device-timeout=30 0 0

Note that the quotes are not added to the entry. Also note all the flags I use, especially the shortened timeout (systemd.device-timeout=30) to shorten the wait during boot in case the SSD isn’t plugged in. The default is 90 seconds.

The primary reason I want the SSD mounted is because that’s where I put swap. In /etc/dphys-swapfile I add the following line:

# where we want the swapfile to be, this is the default

I want my swap on the SSD because testing has shown the SSD is an order of magnitude faster than the boot micro SDXC. I use the Raspberry Pi 4’s as development and native build machines, rather than set up an emulation and cross-compile tool chain on my Mac. Believe it or not, it’s a lot simpler the way I have it set up. This is a decent compromise that doesn’t require me to put the entire OS on the SSD and then configure the Raspberry Pi to boot off the SSD. There are some significant problems with that, such as the Rasberry Pi 4 wasn’t set up to do that for quite some time after its release, and the fact that once configured that way, you can’t go back. So I put swap on the SSD, then cd onto a work area on the SSD and develop and build away.

This all gets back to the bigger question: why did this change, and when did it change? I use the same type of setup, and the same SSD, on the Jetson Nano, and it’s running a tweaked version of Ubuntu 18.04.04, complete with the Ubuntu graphical desktop. The fstab entry for that is the regular device entry, /dev/sda1.

Oh well. I just keep reminding myself that this is just a hobby, and I’m retired.

the correct way to enable spi ports on the beaglebone black

One of the most important benefits of retirement is the time you have to do what you want to do. While working, I had to divide my time between work (which included commuting), then my obligatory civic responsibilities, followed by my obligatory home chores. Whatever was left I could devote to some personal project. With retirement, that’s been pretty much flipped 180 degrees. I have more time for civic and home chores, and considerable time to devote to projects, or considerable compared to when I had to work for a living.

With all that extra “spare” time I turned my attention to some of the single-board computers I’d been collecting over the past five years. Some of them only got a cursory examination before they were put on the shelf “for some time later.” In the case of the BeagleBoard Rev C, I purchased it August 2014 and wrote about the purchase here ( That was the last I wrote about the BBB at all until today. Before I put it away I briefly powered it up and logged into the Debian default account using the Cloud 9 IDE bundled with the BBB just to make sure it worked.

What’s Good

Let’s get this part out of the way first. The best part of Beagle Bone IMHO is the web-based Cloud 9 IDE built-in service that allows the developer/maker (I hate the ‘maker’ adjective) to begin to work immediately with the BBB. This post’s┬álead media image shows the latest version of this tool. It follows a classic IDE layout; a long gutter on the left showing work area and files, a top source editor, and a bottom section containing tabbed areas for logging and running one or more shells.

It’s the ability to run a shell in a web page that always impresses me. I’ve seen the same thing with Cockpit running on CentOS7/8. The fact I can do it with the BBB means I don’t need to plug in, at a minimum, a separate monitor and keyboard. The BBB comes with only one USB port, and mine is currently occupied with a tiny WiFi dongle.

The current source code editor is nice as well. Much more than say, gedit, but not as sophisticated as Visual Studio Code. All in all it’s still a great text editor with very good syntax highlighting and reasonable, if minimal, language support in JavaScript and C/C++.

And Now For (Some of) the Complaints

The genesis of this section has been my ongoing attempt to interface a TI 74HC595N 8-bit serial-to-parallel shift register to the BBB’s serial peripheral interface (SPI) port. I was going by the instructions printed in the book “Exploring BeagleBone” by Derek Molloy, chapter 8. The book was published late 2014 with a 2015 copyright notice. I picked it up early 2015, right before I headed to Japan to support a major software installation and training effort. It went on the shelf next to the BBB and just like the BBB it was forgotten in the mad that started in April and didn’t finish until December of that year.

So here I was in retirement, powering up the BBB, and getting to know it and the book again. If you know anything about the book’s chapter 8, it’s all about serial communications, first with I2C and then SPI. I went after the SPI section because I’d already built up some material with 12C and the Raspberry Pi.

So I got the parts and built up a simple circuit to use as my test bed. And that’s when nothing appeared to work. I quickly ┬ádiscovered that the directions in chapter 8, and supporting information in chapter 6, were all wrong. The OS that shipped on my BBB was Debian. I eventually updated that initial Debian to the latest, but it did nothing to help get anything working. In the end, reading various fora and looking in the code, I discovered how to get it all working.

  1. First disable the HDMI port on the BBB. This is done by editing the file ‘/boot/uEnv.txt’ and uncommenting the line ‘disable_uboot_overlay_video=1’
  2. Reboot the BBB after uncommenting the disable HDMI line.
  3. Use the command config-pin to then configure all the pins for SPI0 and SPI1

As an example for setting up the pins with config-pin, please see the following Bash script. Please note that you’ll need to run the script with sudo.

#!/usr/bin/env bash
# Execute on a BeagleBone Black with no overlays loaded.
# These commands require the default pin configuration in order to work.

# For SPI1, /dev/spidev1.#
config-pin p9_17 spi_cs
config-pin p9_18 spi
config-pin p9_21 spi
config-pin p9_22 spi_sclk

# For SPI0, /dev/spidev2.#
config-pin p9_28 spi_cs
config-pin p9_29 spi
config-pin p9_30 spi
config-pin p9_31 spi_sclk

If you deliberately or accidentally fail to disable the HDMI port, then you’ll see the following errors when trying to enable all pins for SPI0

P9_28 pinmux file not found!
bash: /sys/devices/platform/ocp/ocp*P9_28_pinmux/state: No such file or directory
Cannot write pinmux file: /sys/devices/platform/ocp/ocp*P9_28_pinmux/state
P9_29 pinmux file not found!
bash: /sys/devices/platform/ocp/ocp*P9_29_pinmux/state: No such file or directory
Cannot write pinmux file: /sys/devices/platform/ocp/ocp*P9_29_pinmux/state
P9_31 pinmux file not found!
bash: /sys/devices/platform/ocp/ocp*P9_31_pinmux/state: No such file or directory
Cannot write pinmux file: /sys/devices/platform/ocp/ocp*P9_31_pinmux/state

In Summary

  • If you’re working with either SPI port on the BeagleBone Black, then ignore just about everything in books and across the internet when it comes to configuring the SPI ports.
  • If you enable SPI ports via the firmware overlays with an entry in uEnv.txt, then only SPI1 will work. Any attempt to enable SPI0 will fail with both the config-pin command as well as the SPI0 firmware overlay.
  • If you want to enable both SPI ports then disable HDMI in the uEnv.txt (as documented above), then reboot the BBB. Then use config-pin to configure and enable all the necessary pins.
  • Chapter six in “Exploring BeagleBone” with regards to enabling SPI is totally wrong now. There is no Cape Manager anymore, and no “slots” feature to set up the firmware overlays. The only way to enable them appears to be via uEnv.txt, which must be hand edited before rebooting the BBB.