Using FreeBSD® on a Raspberry Pi™

Raspberry Pi(tm) logo with FreeBSD(R) 'beastie'


Why use FreeBSD
Raspberry Pi, FreeBSD, and the 'gpioshutdown' module
Installing FreeBSD on a Raspberry Pi
Obtaining an SD card image
FreeBSD 'pkg' utility and kernel/world source
Customizing the FreeBSD installation
Configuration via the 'rc.conf' file
Configuring 'powerd' for CPU frequency power management
Automatic device configuration via the 'devfs.conf' file
Setting up the Raspberry Pi for serial console boot
Building a custom kernel and updating the image
Building and installing the 'gpioshutdown' kernel module from source
Using the GPIO pins
External Links

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 as well as the wiringPi implementation for examples of this). 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). In FreeBSD this method basically does not work. However, there is an ioctl method available via the 'gpioc' device, as well as a utility 'gpioctl', that gives you direct control over the GPIO pins. Additionally, you can change the permissions on the GPIO pin device /dev/gpioc0 automatically, by editing a configuration file, so that a particular user or group (the 'operator' group as one example) has read/write access to the gpio pins.

Because of the way /dev/mem and mmap work on Linux, it is very likely that an ioctl interface is more efficient at accessing the device than would be a memory map (it is also safer). And, assigning permissions to /dev/gpioc0 can allow specific users to directly access the GPIO pins without having to 'be root'.

Additionally FreeBSD supports I2C using the 'iic' device (via ioctl) as well as the 'i2c' utility for command line access. And in the development version ('head', currently version 12) there is an 'spigen' driver that has support for overlays that define the spi interface. It is still under development, but is likely to end up looking a lot like the 'spidev' device, with its own ioctl interface (I'm currently assisting the kernel devs with this, with several proposed patches in 'phabricator').

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 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 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, either from the keyboard (with a monitor attached), or by using ssh. The image comes with two pre-defines user:password combinations, 'freebsd:freebsd' and 'root:root'. 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 pre-assigned user:password for the SD card image changes, use the user:password specified there, instead of anything you see here. NOTE:  you should change the 'freebsd' and 'root' user passwords to something of your choice. You should never leave any default passwords as-is, for security reasons. Additionally, FreeBSD does not allow users that are not members of the 'wheel' group (GID 0) to 'su' to 'root'. Keep this in mind when adding new users, or removing them.

Once logged in as 'freebsd', you can 'su' to 'root' and change the 'root' password. Don't leave it as 'root'. Although you can log in as 'root' directly from a video console, keep in mind that you cannot login to 'root' via ssh. This is disabled by default in all FreeBSD installation images, and for good reason. If you want, you could enable ssh login as 'root' by modifying the sshd configuration, but I do not recommend it (my security logs are filled with countless attempts to log in via ssh as 'root' and IPv6 addresses are nearly always publically visible, even behind an IPv4 NAT firewall. So you should just use 'su' from a user in the 'wheel' group, or install/configure 'sudo' - more on this later).

    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 FreeBSD Handbook.

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 the basic 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. More on building the kernel/world yourself and updating it, later.

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
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 'svn checkout' command and subversion should figure out that it was interrupted and pick up where it left off. You may need to use the 'svn cleanup' command to restore the in-progress checkout to a usable state, before continuing again with 'svn checkout'.

Customizing the FreeBSD installation

If you are familiar with the way Linux is configured, you should know that FreeBSD's configuration system is a bit different, and in many ways, much more flexible. FreeBSD uses a configuration system known as the 'rc utility', which is explained in the 'rc(8)' manual page. It's a long read, but the things that you really must know can be summarized fairly easily. I'll try to do that, here.

Additionally, the boot process uses a 'loader' program that interprets scripts written in Forth, located in the '/boot' directory with extensions of '.4th'. There is one specific file (that you might need to add), where you can put custom boot information into, the '/boot/loader.rc.local' file, which I'll cover later in this section.

It's very likely that you'll want to change how the operating system starts up, the kernel modules and settings that are loaded, services that are running by default, and so forth. The manual pages for things like 'rc.conf' and 'devfs.conf' cover this topic well, but I'll mention some of the basics here, for convenience, in order to help get you started.

    Configuration via the 'rc.conf' file

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')

Additionally, if you have a (properly set up) service script in '/usr/local/etc/rc.d', it will be automatically loaded by the 'rc' system during startup and shutdown, and you'll be able to access it with the 'service' utility [this is a lot like the System V configuration for Linux]. For a typical service script, you'll have a variable assignment in the 'rc.conf' file that enables it, similar to the following:

When the rc.conf file is loaded by the service script, it detects that the enable variable is set to 'YES' and enables the service. Additional custom parameters for the service script would also be added to rc.conf if the default values aren't correct.

    Configuring 'powerd' for CPU frequency power management

The 'powerd' built-in daemon can be configured to automatically cycle the CPU frequency based on the load. The Raspberry Pi tends to power up in whatever frequency was pre-assigned in the hardware definition, and as such may not be what you want. To activate the 'powerd' daemon, you can add lines similar to the following to your '/etc/rc.conf' file:

    # powerd - cpu frequency 'high adaptive'
    powerd_flags="-n hadp -a hadp -b hadp"
This tells 'powerd' to use the 'high adaptive' power management scheme, abbreviated 'hadp', for AC power, battery power, and 'unknown power state'. For additional settings, and their implications, you can visit the man page for powerd(8).

    Automatic device configuration via the 'devfs.conf' file

FreeBSD has another file '/etc/devfs.conf' that lets you modify device entries as they are created, so that you can set up customized permissions. This is extremely useful for the 'gpioc0' device, which (by default) does not allow non-root users to access the GPIO pins.

A simple change would be to add the following lines to '/etc/devfs.conf':

    own     gpioc0  root:operator
    perm    gpioc0  0660
This way, the 'operator' group has read/write access to GPIO pins. You can add as many users as you like to the 'operator' group, as you see fit. Or you can create a new group of your choice, and give read/write access to THAT group instead.

For serial port access, you might also want to add the following entries to '/etc/devfs.conf':

    own     ttyu0   root:dialer
    perm    ttyu0   0660
This way the 'dialer' group would be able to use the serial port 'ttyu0'. Keep in mind that if you have configured it as a console, the console I/O might interfere with it. Also worthy of mention, the corresponding 'cuau0' device is already assigned permissions that have group access via 'dialer'.

If you do not want to modify '/etc/devfs.conf' but would rather set up a rule set to access devices, you might be more interested in '/etc/devfs.rules'. Documentation on this is available via the manual pages (i.e. 'man devfs.rules').

    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 ) :

  1. edit (or create) the '/boot/loader.rc.local' file, and add the following:
            set boot_multicons="YES"
            set boot_serial="YES"
            set comconsole_speed="115200"
            set console="comconsole,vidconsole"
    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'.

  2. To get the 'beastie' boot menu, add the following at the end of the '/boot/loader.rc.local' file:
            include /boot/beastie.4th

    Building and installing a custom kernel from source

In some cases, you might need to get the latest kernel/world source, build it, and install it with all of the necessary changes and updates. FreeBSD has several branches that are documented in the FreeBSD Handbook Chapter 23.

NOTE:  At any time in the future, the build and install instructions may change. They are typically included with the source, in /usr/src/Makefile and /usr/src/UPDATING. You should consult with those before actually performing any build or install steps obtained from this web page.

One of the trickier processes involves using a MUCH faster (desktop) computer to build the kernel+world source, with an appropriate cross-compiler. Since the world build generates the correct cross-compiler for you, it is only a matter of setting up the environment correctly. As a general rule, you'll need a FreeBSD system with version 10 or later to build any Raspberry Pi compatible kernel/world from source. I recommend using the most current 'stable' release if possible. Additionally, you should either write the steps into a shell script, or make them available in a text file that you can invoke via 'source' aka '.'.

Setting up environment variables for cross-compile

To perform a cross-compile (arm32) for the Raspberry Pi Model 1 and 2 (with FreeBSD 11), you must be logged in as 'root', and the entire build is performed from the '/usr/src' directory (or wherever you put the source). By default, output will be to the /usr/obj directory, in directories that are specific to the target and its architecture. You will need to define the following environment variables before issuing any build or install commands:

From csh:

  1. setenv TARGET arm
  2. setenv TARGET_ARCH armv6

From bash/ksh/sh:
  1. export TARGET=arm
  2. export TARGET_ARCH=armv6

(Please note that, beginning with FreeBSD 12, the RPi 2 will use 'armv7' rather than 'armv6', and building for RPi 3 with -CURRENT probably uses 'arm64' and 'armv8' but I have not actually tried it)

The remaining steps will be similar to what you do to build a normal kernel+world. In short:

  1. cd /usr/src
  2. make -j 8 buildworld(this is required before buildling a kernel)
  3. make -j 8 buildkernel KERNCONF=RPI2(use 'RPI-B' for the Model 1 B)

The 'KERNCONF' argument tells make which kernel to build. You need to build the kernel that's specifically designed for your Raspberry Pi. FreeBSD 11 only supports the RPI 1B or RPI 2 at this time. However, the development branch -CURRENT has support for RPI 3. It's also likely to have build/run problems.

The '-j 8' tells make to use '8 jobs', i.e. 8 parallel processes, which greatly speeds up the build. If for some reason using '-j 8' uses too much CPU on your computer, or fails to build properly, you can remove this frmo the 'make' command and build single-threaded, or alter the '8' to something else that's more appropriate for your system. I suggest 2 times the number of CPU cores.

Additionally, since 'buildworld' is common for all kernels using arm.armv6, you can build second kernel that uses a different kernel configuration, after building the first one. You will still be able to install either kernel later on, since kernel output files are in a directory with the kernel configuration name in the path.

Once you have build the kernel and world from source, you need to install it on the SD card. This is probably one of the simplest ways to make that happen:

  1. De-energize the Raspberry Pi, and remove the (micro)SD card.

  2. Insert the (micro)SD card into an appropriate SD card reader on the computer on which you built the kernel+world.
    NOTE:  Now would be a good time to back the (micro)SD card image up using 'dd'. You may find that it's worth spending the extra time to do this. On FreeBSD the SD card will have several device names associate with it, something like this:
        /dev/da0        the SD card itself, along with the partition information
        /dev/da0s1      the 'msdosfs' partion containing broadcom's boot firmware, config.txt, and u-boot
        /dev/da0s2      the FreeBSD partition (don't mount this directly)
        /dev/da0s2a     the FreeBSD 'slice' containing the FreeBSD UFS image.  Mount this one to install kernel+world.
    To perform a backup of the entire SD card, you could do something similar to the following:
        dd if=/dev/da0 of=~/rpi-backup.img bs=1M conv=noerror,sync
    This will create the file ~/rpi-backup.img with a block size of 1M [which is faster], padded with 0-bytes in case of errors or 'short length' blocks.

  3. Mount the (micro)SD card on the computer on which you built the kernel+world, similar to:

        mount /dev/da0s2a /mnt

    where '/dev/da0s2a' is the device with the UFS partition containing the FreeBSD image on the SD card
    and '/mnt' is the directory on which to mount the image (remaining examples here assume '/mnt')

  4. from /usr/src, enter commands similar to the following:
    • make installkernel DESTDIR=/mnt DKERNCONF=RPI2    (or RPI-B, whichever one you built)

      NOTE:  do NOT forget or mis-spell the 'DESTDIR' argument; otherwise, you might end up with a cross-compiled kernel on your workstation. Make sure you do it right before pressing <ENTER>!

    • make installworld DESTDIR=/mnt

    • mergemaster -F -U -i -A arm -D /mnt
      NOTE:  if you are not familiar with mergemaster, it handles text configuration files. The arguments shown here will handle the basic upgrades automatically for you. when presented with a 'diff' screen showing the differences, you will be using whatever you have selected as your pager in the PAGER environment variable (typically 'more' or 'less'). When asked how to deal with it, pressing 'm' gets you into the merge screen. in short, 'l' accepts the left-hand [original], 'r' accepts the right-hand [new], and 'q' quits. You can always select 'deal with it by hand' if you want. The important changes will usually happen automatically anyway. More instructions on mergemaster are available via man pages and in the FreeBSD Handbook.

  5. Once you have installed the kernel and world onto the SD card, you can unmount it, re-insert into the Raspberry Pi, and boot normally.

    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 for the build. I prefer hosting this on another (FreeBSD) workstation, where I can more rapidly build a new kernel/world as needed, and then mounting it at /usr/src on the Raspberry Pi using an NFS share.

NOTE:  See the section on getting the kernel source, and on building a custom kernel, above. It is very important that your kernel source tree matches the installed kernel!

As with the kernel source, the ports collection is relatively large (about 800Mb), but the ports tree should probably 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 can use either 'subversion' or the 'portsnap' utility to obtain the ports collection. Either way, it's a time-consuming process, especially on a slower CPU like the one on the Raspberry Pi. If you use 'portsnap', I recommend letting it run overnight. Using 'subversion' should be a faster, at the expense of convenience.
A summary of the 'portsnap' commands you'll need to run:

    portsnap fetch
    portsnap extract
As always, I suggest reading the FreeBSD Handbook chapter first, so that you have a good idea of what's involved. Again, using subversion should be a lot faster, but less convenient. Information on using subversion to obtain the ports collection is also in the FreeBSD Handbook.

NOTE:  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:
    sh <raspberrypi-gpioshutdown.shar
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:

    make install
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.

Using the GPIO pins

FreeBSD has a convenient command line utility 'gpioctl' that can be used to set up GPIO pins, such as defining them as input or output pin, as well as querying a pin's value or assigning a value to an output pin. You should review the manual page for gpictl(8) for correct command line syntax and a full list of capabilities.

Additionally, there are IOCTL commands available for querying and manipulating GPIO pins, the same one that is used by the gpioctl utility. Since the device '/dev/gpioc0' can be configured to have 'operator' read/write capabilities, you do not have to be logged in as 'root' in order to use the GPIO pins from teh command line, or with the IOCTL (but you may have to customize the device permissions in devfs.conf)


    Using the 'gpioctl' application

Here is a summar of some 'gpioctl' commands that can get you started with controlling GPIO pins:

  • gpioctl -c 25 INConfigure GPIO pin 25 as an input
  • gpioctl -c 24 OUTConfigure GPIO pin 24 as an output
  • gpioctl 24 1Set GPIO pin 24 to a '1' (high) value
  • gpioctl 25Read the value of GPIO pin 25, output to stdout ['0' or '1']
  • gpioctl -lList all GPIO pins with their state and mode

    Using the 'gpio' ioctl calls from a C/C++ program

TEMPORARY: the following program demonstrates how to use the GPIO IOCTL functions in FreeBSD:

External Links:

Back to S.F.T. Inc. home page

Raspberry Pi™ is a trademark of the Raspberry Pi Foundation.
FreeBSD® is a registered trademark of the FreeBSD Foundation.
BSD Daemon Copyright 1988 by Marshall Kirk McKusick. All Rights Reserved.

©2018 by Bob Frazier and Stewart~Frazier Tools, Inc. - all rights reserved
last updated: 5/24/2018

Community projects are generally good, but socialism, in all of its forms, is always evil.