Why use FreeBSD
A big question in anyone's mind, at this point, might be "Why should I use FreeBSD on my Raspberry Pi board?"
Well, to answer that question, I'll need to go into a bit of technical depth
To begin with, there are many different operating systems available for the Raspberry Pi, the most popular of which
appears to be a version of Debian Linux known as
'Raspbian'. It currently tracks the latest production version of Debian,
which (unfortunately) includes systemd, and a version of 'bluez' (bluetooth tools) that has problems with legacy
USB bluetooth devices, as well as (potential) encumberances of the GPL.
But for most Raspbian users, you probably won't even notice those things.
For people who are interested in making devices based on the Raspbery Pi, by either embedding a Raspberry Pi
(as I have done HERE), or by using the same ARM device that the
Raspbery Pi uses [in a compatible manner], some of the concerns I have with Raspbian may be enough to choose an
alternative operating system. And a very good choice for THAT would be FreeBSD.
FreeBSD is designed for 'build from source', and so the 'ports' collection helps to make this easy. More
information on this aspect can be found in the FreeBSD handbook
and other resources. What is worth pointing out is that FreeBSD makes a LOT of development work easier,
and if you develop software specifically for the Raspberry Pi, you may grow to appreciate how much easier
that can be.
Additionally, GPIO manipulation in FreeBSD uses an ioctl interface rather than proc variables. The Linux
implementation appears to be tailored for use by scripts and interpretive languages (like Python). The
FreeBSD implentation does include a command line utility ('gpioctl'), but it's the ioctl interface that would
make a C language application more practical.
In Linux, you can directly access memory (via '/dev/mem') and map it into your address space (via 'mmap')
and then directly manipulate the GPIO registers yourself (see THIS EXAMPLE).
But (unfortunately) it generally requires a 'root' user to access '/dev/mem' (changing permissions on /dev/mem
to allow non-root access is NOT a very good idea at ALL). Apparently, you can also use this method in FreeBSD
(I have not tried it yet, but the /dev/mem device exists). However, in FreeBSD, you can change the permissions
on the GPIO pin device /dev/gpioc0 automatically, with a configuration file, so that the 'gpio' group has
read/write access to it. This way you can allow specific users to directly access the GPIO pins without having
to 'be root', using a very fast (ioctl) interface.
Additionally FreeBSD supports I2C using the 'iic' device (via ioctl) as well as the 'i2c' utility for
command line access. However, it does not (yet) appear to have an SPI driver. I guess I'll have to
Raspberry Pi, FreeBSD, and the 'gpioshutdown' module
One of the glitches that I've found, with respect to using FreeBSD on the Raspberry Pi, is the manner in which
FreeBSD handles GPIO pins on shutdown. In Linux, the GPIO pins are reset such that it is possible to detect the
shutdown condition with appropriate hardware (like the
The ATXRaspi), which would let you do a
'safe poweroff' on the Raspberry Pi, and avoid possible file system corruption. This is ESPECIALLY important for
a headless system, because you won't be able to see the console output.
To correct for this, I created a loadable kernel module 'gpioshutdown', which is tentatively to be added to the
'ports collection' as 'misc/raspberrypi-gpioshutdown' (more on this, later).
By loading this kernel module, the IO pins are reset to their 'default' (input) state right at the point where it
is safe to power off the device. If, for example, you set a pin to an output with a '1' value, and then drove
an LED (through a 220 ohm resistor) with that pin, the pin would light up when the system startup completes. If
you then checked another pin for a shutdown (let's say it has a pushbutton on it), you could issue the command
'poweroff' (as root) upon detection of the pushbutton, and do a proper shutdown sequence. Once the system has
completed shutting down, the LED would turn off, indicating that it's safe to turn off the power.
Alternately you could have a hardware device (like the ATXRaspi) do some of this work for you. The shutdown
would be indicated by the output GPIO pin becoming a 'high impedence' input pin (similar to the LED trick that
I just mentioned), at which point it would be safe to power off the Raspberry Pi.
Worthy of mention, this already works under Linux. The kernel module makes it work under FreeBSD, too.
Installing FreeBSD on a Raspberry Pi
Obtaining an SD card image
You must first obtain a bootable SD card image from the FreeBSD.org web site. Currently, you can download
the latest FreeBSD 11.1 Raspberry Pi images HERE.
For the RPi Model 1B, you'll probably want FreeBSD-11.1-RELEASE-arm-armv6-RPI-B.img.xz.|
For the RPi Model 2, you'll probably want FreeBSD-11.1-RELEASE-arm-armv6-RPI2.img.xz.
For the RPi Model 3, there is no production release available (yet). However, there is an incomplete 'bleeding edge'
release available HERE.
(look for a link that begins with "FreeBSD-12.0-CURRENT-arm64-aarch64-RPI3" or similar, as these links change
frequently and you'll nearly always want the latest one).
NOTE: It's important to point out that as newer releases become available, they will be linked to from the main FreeBSD web site,
at https://www.freebsd.org/. So if this web page is several years old, please keep
in mind that these links are for the newest images at the time I wrote it.
Once you obtain the compressed disk image (compressed using 'xz'), you need to extract this into a binary image.
Use the 'xz' utility (in Linux or FreeBSD) as follows:
xz --decompress ImageFileName.img.xz
where 'ImageFileName.img.xz' is the name of the image you downloaded. This will get you the raw image file,
named similarly to 'ImageFileName.img'.
Transfer the image to an SD card
Next, you'll need to insert an SD card that is at least 4G (preferably 8G or larger)
into an appropriate slot [and then plug in the USB cable, if you are using an external USB device] on your Linux
or FreeBSD computer, but do NOT allow it to be 'auto mounted' (you might have to forcibly unmount it if your GUI
is aggressive and persistent at "helping" you in this way).
Then, once the SD card shows up in the '/dev/' tree, you'll need to overwrite the primary partition on the SD card
with the contents of the '.img' file you extracted earlier. On a FreeBSD system, it will probably have a device
name similar to '/dev/da0'. If the SD card has a file system on it, there may be other entries like '/dev/da0s1'.
The entry you want to overwrite is the 'root' device, '/dev/da0'. On Linux the device naming is similar. If you're
not sure which device to use, try unplugging the SD card, and plugging it back in again, and see which device names
disappear and then re-appear when you do this.
Assuming that you're running FreeBSD and the SD card is '/dev/da0', use the following command to write the image:
dd if=ImageFileName.img of=/dev/da0 bs=1M conv=noerror,sync
The 'conv=noerror,sync' parameter fills out the remainder of the image with padded zeros, necessary when you
specify a non-default block size. And the block size of 1M actually speeds the process up quite a bit (there
is a similar command example near the end of the man page).
Initial boot on a Raspberry Pi
Next, you'll want to boot up this image on an actual Raspberry Pi. You should connect a monitor and keyboard to
the Raspberry Pi in order to monitor the process (and maybe control it). On initial boot, the FreeBSD startup
script will automatically extend the image to fill the SD card completely, so you'll have the most possible disk
space available. This is actually necessary prior to you making any modifications.
The first thing you'll need to do is log in via the console. I suggest logging in as 'freebsd' with the password 'freebsd'
(this is documented in the FreeBSD/ARM Raspberry Pi wiki,
and if for some reason the user/password changes, use the user/password specified there, instead). Then, you should
change the password to something of your choice. You should never leave the default password as-is, for security
Next, you should immediately 'su' to root and change the root password. Don't leave it as 'root'. Again, this is for
security reasons. I also recommend that you add a new login for the user name you prefer to log in as, using the
'adduser' command. Just fill in the prompts and accept the defaults (they'll be fine, for now). You can always
modify them later, as needed.
FreeBSD 'pkg' utility and kernel/world source
FreeBSD has a package system that uses the 'pkg' utility. You'll want to install that. Type 'pkg' and follow
the instructions you're given to get it up and running.
At this time it's a good idea to consider which packages you are going to want to install. If you prefer 'bash'
as your login shell, you can install it via the command 'pkg install bash'. Other things, like Perl, Python,
and a GUI, can be installed as packages. More information on this can be found in the
If you will be building any kernel modules from source, including the 'raspberrypi-gpioshutdown' port (see below),
you'll need to install the kernel source yourself. This is a VERY large tree (around 1.5G), and as such, you may
want to host it on a different computer, via an NFS share, and mount it to /usr/src (rather than hosting the
kernel/world source there). Keep in mind that the kernel source MUST match the actual kernel for this to work
properly, so you might have to update the kernel on the Raspberry Pi's image as well. I'll cover this later.
You'll need to choose a directory for the kernel+world source. FreeBSD will expect it to be in the
'/usr/src' directory on the Raspberry Pi. You can mount an external NFS share at this point, or else load
the source tree directly onto the SD card at this point. Either way works. And if the source files are on
an external computer, you can obtain the source directly on that computer first, and then mount it via NFS
on the Raspberry Pi at your convenience (this is the method I prefer).
The FreeBSD kernel+world source is available via subversion. This is covered in the
FreeBSD Handbook Chapter 23,
including instructions on building the 'world' and 'kernel' trees. You'll need 'world' to build the kernel, so
you basically have to get the entire tree.
On the Raspberry Pi, you can install the subversion client with the following command:
pkg install subversion
With subversion installed, change the working directory to the location where you'll be keeping the source files
(it should be a clean directory), and enter a command similar to the following:
svn checkout https://svn.freebsd.org/base/releng/11.1
In this case, it will get the source for '11.1-RELEASE', which should match the SD card images I referenced earlier.
Keep in mind that over time, you'll probably want to use a version newer than '11.1'. I used that version here only
as an example. Also, additional information (and any corrections) will be available in the FreeBSD handbook.
NOTE: If you have a somewhat slow (pathetic DSL let's say) connection, or a connection that gets interrupted
for some reason (storms, cable guy screwup, whatever) and the svn command fails, you can repeat the same command and
subversion should figure out that it was interrupted and pick up where it left off.
Customizing the FreeBSD installation
It's very likely that you'll want to change how the operating system starts up, the things that are running by
default, and so forth. The manual page for the 'rc' system ('man rc') explains all of this, but I'll cover
some of the basics here, for convenience.
FreeBSD has a file '/etc/rc.conf' that assigns various pre-defined environment variables for the 'rc' system,
that determines how the system boots up. It can configure network connections, load device drivers, start
daemon programs, and do 'one time during startup' kinds of processing. Script files contained in '/etc/rc.d'
and '/usr/local/etc/rc.d' define what the 'services' are, very similar to the 'System V' style startup used
by pre-systemd versions of Linux.
Details on the contents of 'rc.conf' can be found in its 'man' page ('man rc.conf').
Most of the configuration can be done using the '/etc/rc.conf' file, with occasional startup scripts in
'/usr/local/etc/rc.d' for customized operations (let's say, flipping a GPIO output bit to indicate that the
Raspberry Pi has started up). There is also legacy support for 'rc.local', in case you want to go THAT route.
If you want to load a specific kernel module, for example, you could add the following line to '/etc/rc.conf':
This would load the 'gpioshutdown' kernel module on startup (for more information on using this, see the
section below on the 'misc/raspberrypi-gpioshutdown' port). If you want to load more than one module, just
separate the module names with white space.
(If you want to know what script handles this, see '/etc/rc.d/kld')
Setting up the Raspberry Pi for serial console boot
By default, the Raspberry Pi image for FreeBSD will boot using the video console and use the attached
keyboard (via USB). However, on a 'headless' system, you will often want an alternate means of doing
a controlled bootup, such as for maintenance or recovery.
To configure the Raspberry Pi to use serial port 0 ( /dev/ttyu0 and /dev/cuau0 ) :
- edit (or create) the '/boot/loader.rc.local' file, and add the following:
This will configure the serial console on pin 8 (TX) and pin 10 (RX) for 115k baud, 8 bits, no parity. To use a different speed, alter the line for 'comconsole_speed'.
- To get the 'beastie' boot menu, add the following at the end of the '/boot/loader.rc.local' file:
Building and installing the 'gpioshutdown' kernel module from source
Before you can build and install the 'gpioshutdown' kernel module from source, you'll need to install the ports collection
onto the Raspberry Pi, as well as having the kernel source available. As with the kernel source, the ports collection is
relatively large (about 800Mb), but in this case, it should be installed locally on the Raspberry Pi's SD card.
For more information on obtaining the ports collection, see
The FreeBSD Handbook Chapter 4.5.
In summary, you'll be using the 'portsnap' utility to obtain the ports collection. It's a time-consuming process,
especially on a slower CPU like the one on the Raspberry Pi. I recommend letting it run overnight.
A summary of the commands you'll need to run:
I suggest reading the FreeBSD Handbook chapter first, so that you have a good idea of what's involved.
Currently the port for the 'gpioshutdown' module is not (yet) available in the FreeBSD ports collection. Eventually
it will be, and should also be installable as a package. However, I am making it available here, and the instructions
reflect installing the kernel module by building it from source, using a customized 'port' contained in a user directory.
If you plan on creating your own ports, or need to extract this one into a user directory, you should create a directory
called 'ports' in the home directory of an appropriate user on the Raspberry Pi. In this example, it's the 'rpi' user.
First, log in as "that user" (in this case, 'rpi') and create a directory '~/ports'. Next, change the working
directory to '~/ports' and create a directory 'misc'. Then, change the working directory to '~/ports/misc' and download
the 'shar' file with the following command:
Next, extract the port by running the 'shar' archive as a shell script:
Once you've extracted the port files, you can delete the 'shar' file.
Now, change the working directory to the port directory, 'raspberrypi-gpioshutdown'. Then, use 'su' to switch
to the root user. You will need to build and install the port as root, by running the command:
Even though you're not in the '/usr/ports' directory, you can still compile it as a port. The kernel module
will be correctly installed into '/boot/modules' and will be version checked on load. Keep in mind that if
you update the kernel, you'll also need to update the kernel module (basically re-build and re-install it
with the correct kernel source).
The port installs an 'rc.d' script file 'gpioshutdown' in '/usr/local/etc/rc.d'. This script automatically assigns
the LED pin 'pwr' (on an RPi model 2) or 'ok' (on an RPi model 1) as a shutdown indicator, using the correct LED
polarity for each of those devices (later RPi models may not have this capability, which is why it's optional).
To use the built-in 'gpioshutdown' script, add the following line to rc.conf:
To start the script, you can reboot the Raspberry Pi or use the following command:
service gpioshutdown start
You should now see the LED turn on (Raspberry Pi model 1B and model 2) indicating that the script is running.
To test it, enter the 'poweroff' command (as root). You should see the LED turn off after about 30 seconds,
indicating that it's safe to turn off the Raspberry Pi.
If you have a serial console enabled, or a monitor connected, you should see the following text appear:
The operating system has halted.
Please press any key to reboot.
The LED that was previously on (before) should turn off just before this text prints on the console. You can
verify this by watching the shutdown sequence and observing the text and the LED state.
Back to S.F.T. Inc. home page