# Crochet builds bootable FreeBSD images for ARM boards and x86 alike

> Crochet is a shell driven image builder for FreeBSD that turns a per-board configuration file into a bootable disk image, with board definitions for Raspberry Pi, BeagleBone, PandaBoard, Pine64, Wandboard and others. It keeps build products between runs so an iteration is minutes rather than hours, and its known gaps include swap sizing and virtual machine image output.

**freebsd/crochet** — Build FreeBSD images for RaspberryPi, BeagleBone, PandaBoard, and others.

- Repository: https://github.com/freebsd/crochet
- Stars: 633 · Forks: 186
- Language: Shell
- License: BSD-2-Clause
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/freebsd-crochet

## An image builder for boards, not a general purpose builder

Crochet is a tool for building bootable FreeBSD images, and the repository's origin explains its shape. It was formerly known as freebsd-beaglebone, or beaglebsd, because the original work was done for BeagleBone, but it now supports more boards and the README says it should easily extend to many more.

The board list is long and covers the ARM and embedded world: Alix, BananaPi, BananaPi BPI-M3, BeagleBone, Chromebook Snow, Cubieboard, OrangePi, NanoPi-NEO and NEO2, PandaBoard, Pine64, RaspberryPi and RaspberryPi 2, Wandboard, Versatile PB, and generic x86 systems. There are also entries for Soekris, Versatile PB, ZedBoard, Zybo and VMWare, plus a generic x86 case, which is what makes the tool usable for virtual machine images as well as physical boards.

The structure of the repository is what makes this extensible rather than a fixed set of scripts. There is a board/ directory holding a subdirectory per board, each with a README describing how to run FreeBSD on that particular system, and some boards have several READMEs in subdirectories with additional technical information. There is an option/ directory holding the reusable pieces, a lib/ directory for the script's own functions, a config.sh.sample at the root which the README describes as carrying extensive documentation in the form of comments, and ci/ for continuous integration.

The licence is BSD-2-Clause, and the primary language is Shell, which tells you the whole thing is a set of scripts rather than a compiled tool.

## The build is five steps, and the first one is reading

The README's walkthrough is short enough to follow exactly, and the ordering matters.

Step one is to read board/*board-name*/README. The board-specific directories each have a README with details about running FreeBSD on that particular system, and some have several in subdirectories with additional technical information. This is not a formality, because a board may need special boot pieces, a particular device tree, or a console setup that only the board documentation describes.

Step two is to create a config file, starting by copying config.sh.sample. The first line of that file specifies the board configuration you want to use, and the name must exactly match a directory under board/. The sample file documents the customisations you can set, and the config can specify a wide variety of them.

Step three is to run the script as root, with the command `$ sudo /bin/sh crochet.sh -c <config file>`.

The script first checks that you have the needed sources, and if you do not, it tells you exactly how to obtain the missing pieces, with instructions to follow and re-run until everything is present. Once it has them all, it compiles everything and builds the disk image, and the README warns that this part can take many hours.

Step four is copying the image to a suitable device, an SD card, a disk drive or similar, and the script suggests a dd command to do it. Step five is booting the image on the board, and the README sends you back to the board README for the details.

The script runs on FreeBSD-CURRENT, though some people have reported success running it on FreeBSD 9-STABLE.

## Incremental by default, from scratch only when it matters

The most useful operational property of Crochet is that it keeps what it built.

The README states that Crochet keeps the built system, kernel and other files between runs, and that in many cases you can adjust the configuration and re-run it to build a new image in just a few minutes. The contrast is with the first build, which compiles everything from source and can run for many hours. For anyone doing iterative work on a kernel configuration or a device tree, that ratio is the difference between a usable loop and an unusable one.

The invalidation rule is stated just as clearly. If you update the FreeBSD sources or make a significant configuration change, you should probably delete the contents of the work directory to force everything to be rebuilt from scratch. So the cache is not stale-tolerant by design, it is opt out of when you have changed the ground truth.

The command line interface is small. The -b option loads a standard configuration for a board, -c loads configuration from a file, -e takes an email address to receive build status, and -u updates the source tree. That last one matters for the incremental workflow, because pulling new sources is the trigger for the rebuild from scratch case.

There is also a shortcut for people who only want the most basic build for a board, the command `$ sudo /bin/sh crochet.sh -b <boardname>`.

The README is explicit about the trade: if you want to tweak the build in any way, you need a config file. The -b path is for a stock image, nothing more.

## Packages in the image: pkg, ports, and the PackageInit option

The image Crochet produces is a normal FreeBSD system, so the package story is the standard one, with a couple of hooks specific to the build.

Once the image is running, packages come from the normal pkg repositories:

```
pkg install nginx
```

For the ports tree, the README gives the two commands, to be run as root:

```
 portsnap fetch
 portsnap extract
```

and points at the FreeBSD port collection browser at freshports.org for finding what is available.

The build-time hook is the PackageInit option, which is how you bake packages into the image rather than installing them after the fact. The README shows the shape:

```
# Package Installation Information
option PackageInit $pkg-repo
option Package sudo

# If you don't put a custom resolv.conf in your overlay use this
# Otherwise pkg will not be able to resolve hostnames

option Resolv
```

You change $pkg-repo to the full URL of your own package repository, and you can specify more than one package at a time, for example option Package sudo tmux.

The Resolv option is the detail worth understanding. For pkg to talk to a remote repository it has to resolve hostnames, and if you have not placed a custom resolv.conf in the board overlay, pkg cannot do that, which is why option Resolv exists. It is a small thing, and it is exactly the kind of small thing that makes an image build fail in a way that is easy to misread as a network problem.

The FAQ also covers the two questions every new user asks. Root cannot log in over ssh with the default FreeBSD configuration, and the fix is to use the User option in the Crochet config to create a non-root user who can, or to log in on a serial console and create such a user yourself. And on the video question, not every platform supports HDMI or VGA yet, while most platforms support RS-232.

## The board directory is where you add a new target

The Potential Projects section of the README is the clearest statement of the project's intent and its limits.

The first item is more boards. Crochet should be able to support any board for which the FreeBSD source tree can build a working kernel, and the README is honest about where the difficulty lies: the hardest part is working out the various boot pieces required. It points at board/NewBoardExample for explanations about adding support for a new board.

That is a useful admission. Building a kernel for a board is the easy half, because the FreeBSD source tree can often be pointed at a new platform. The hard half is the boot chain, the device tree, the u-boot or firmware handshake and the early console, and that is per board and per revision work that no amount of generality can automate.

The other items are the current gaps. Out-of-tree kernel configuration is not supported, because the scripts assume kernel configuration files are in the FreeBSD source tree, and the README notes it does not think config(8) requires that, and that it would be nice to include a tweaked kernel configuration as part of a board definition.

Swap is only partly handled. The script can create swap files in the FreeBSD partition, which the README says is easy and seems to work well enough, but there is no way to specify a swap size and have the disk layout adjusted automatically.

Read-only root and other more complex partitioning approaches are not supported at all.

And virtual machine output is incomplete. The VMWareGuest configuration can build a VMWare virtual machine, which is more than just the disk image, but the README admits there are bugs that might involve the VM configuration files or FreeBSD kernel bugs, and it should also be possible to build Bhyve, Parallels, VirtualBox or OVF images directly. That last sentence is a to-do list, not a feature.

## Maintenance: a 14.2 tag and work continuing in 2026

The release history of this repository is thin in a way that is worth understanding before you depend on it.

There is a single recent release, 14.2, published on 2025-01-19. That is a FreeBSD release branch number rather than a Crochet version number, which tells you something about how this project is versioned: the artefact tracks the FreeBSD release it is built for.

The last push was on 2026-06-27, so the repository is not abandoned. The default branch is master, and the presence of a ci/ directory suggests builds are exercised automatically. What is missing from this listing is a stream of Crochet specific releases, so if you are tracking Crochet itself rather than tracking FreeBSD, the commit history is the signal to watch rather than the tag list.

For an adopter, the practical consequence is that the version of FreeBSD you ship is your responsibility. The script runs on FreeBSD-CURRENT, and the tool's job is to assemble sources into an image, so pinning a release branch is a decision you make in the config and the sources you point it at.

The licence is BSD-2-Clause, which is the most permissive of the common BSD variants: no copyleft obligation, no per-seat requirement, and a short notice obligation if you redistribute. The LICENSE.TXT file is in the repository root. Since the tool is a set of shell scripts and configuration that you are expected to read before running as root, that permissiveness is consistent with the project's character.

## Conclusion

Adopt Crochet if you need a FreeBSD system image for a supported ARM or embedded board and you are prepared to build the world from source on FreeBSD-CURRENT. Do not adopt it for a virtual machine deployment, since the VMWareGuest configuration is described as having bugs and Bhyve, Parallels, VirtualBox and OVF output is listed as future work, and do not rely on it for swap sizing or a read-only root. Before you start, read the README for your specific board under board/, copy config.sh.sample, and confirm you can run the build as root on a machine with the sources and a few hours of CPU time.

## FAQ

### How do I build a FreeBSD image with Crochet?

Read the README for your board under board/, copy config.sh.sample and set the board name, then run `sudo /bin/sh crochet.sh -c <config file>` as root. The script checks for the required sources, compiles everything, and produces an image you copy to the device with dd.

### What are the Crochet command line options?

The README lists four: -b <board> loads a standard configuration for a board, -c <file> loads configuration from a file, -e <email> gives an address to receive build status, and -u updates the source tree. The -b shortcut is only for a stock build; any customisation needs a config file.

### Can I install packages into a Crochet built image?

Yes. Use `pkg install nginx` on the running image for the normal repositories, and for the ports tree run portsnap fetch and portsnap extract as root. To bake packages into the image itself, use option PackageInit with your repository URL and option Package for each package, and add option Resolv if your overlay has no custom resolv.conf.

### How do I log in to a Crochet FreeBSD image over ssh?

The default FreeBSD configuration does not allow root to log in over ssh. You can use the User option in your Crochet configuration file to create a non-root user who can log in over ssh, or log in on the serial console and create such a user yourself.

## Sources

- [freebsd/crochet on GitHub](https://github.com/freebsd/crochet)
- [Issues](https://github.com/freebsd/crochet/issues)
- [License: BSD-2-Clause](https://github.com/freebsd/crochet/blob/master/LICENSE)
- [README](https://github.com/freebsd/crochet/blob/master/README.md)
- [Releases](https://github.com/freebsd/crochet/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/freebsd-crochet
