Framework
facebook/openbmc avatar
facebook/openbmc

OpenBMC: building a Linux image for a board management controller

OpenBMC is an open software framework to build a complete Linux image for a Board Management Controller (BMC).

690 stars307 forksCApache-2.0

At a glance

What is it?
OpenBMC is an open software framework that produces a complete Linux image for a board management controller, layered on the Yocto Project. It is used by hardware teams at Facebook and its partners to bring up new switch, chassis and compute platforms, and the build is a Yocto bitbake run against a vendor meta-layer.
Who is it for?
OpenBMC fits a hardware team bringing up a new switch, chassis or server board that needs a board management controller firmware, and that is prepared to work inside the Yocto build system rather than around it. It does not fit a team that wants a ready-made BMC image, or one that needs a different Linux distribution on the management controller.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A BMC is a second computer, and this builds its software stack

OpenBMC is an open software framework to build a complete Linux image for a Board Management Controller. A BMC is the small, separate computer in a server or switch that monitors voltage, temperature and fan state, controls the power, and keeps the host running when the main CPU has crashed. That second computer needs its own bootloader, kernel, drivers and userspace, and every vendor used to write that stack from scratch. The point of OpenBMC is to make it a shared, layered artefact instead. The README ties it to specific hardware from Facebook, including Wedge, a 40G OS-agnostic TOR switch, Yosemite, an open source modular chassis for high-powered microservers, Lightning, a flexible NVMe JBOF, Wedge100, a 32x100G TOR switch, Backpack, a 128x100G modular open switch, Tioga Pass, a dual-socket compute platform, YosemiteV2, Bryce Canyon and Grand Canyon disk storage platforms. The audience is therefore hardware engineers bringing up new platforms, not application developers.

Three layers, and knowing which one your code belongs in

The repository is organised as three sets of layers, and this is the single most important thing to understand before writing anything. The OpenBMC Common Layer holds the common packages and recipes that can be used in different types of BMC, so an application that works across BMCs lives here. The BMC System-on-Chip Layer holds SoC specific drivers and tools, and it includes the bootloader, u-boot, and the Linux kernel, both of which are expected to carry the hardware drivers for that SoC. The Board Specific Layer holds board specific drivers, configurations and tools, and it is the layer that defines how the image is configured and which packages get installed for a particular board, along with any board specific initialisation. The README also explains how these map onto Yocto naming, where a meta-layer names a layer or a category of layers and recipe-abc names a recipe, and where the project itself is a meta layer called meta-openbmc. The common recipes live in the common directory, while SoC and board code are grouped by vendor, with meta-aspeed holding Aspeed SoC source and meta-facebook holding Facebook board code, and the tree also carries meta-delta, meta-evb, meta-nuvoton and meta-zephyr.

Cloning, syncing Yocto and initialising a build directory

The build sequence in the README is four steps, and the second one is the one people miss. First you set up the build environment following the Yocto Project Quick Start Guide. Then you clone the project and pull in the other open source repositories, which is what the sync script is for:

bash
 $ git clone -b helium https://github.com/facebook/openbmc.git
 $ cd openbmc
 $ ./sync_yocto.sh

The branch name matters, since helium is the default branch of this repository. Next you initialise a build directory for the platform you want, in the openbmc directory:

bash
 $ source openbmc-init-build-env wedge

The README notes that references to a platform in the instructions are examples and have to be replaced with the platform you are targeting, and that you can choose between wedge, wedge100, yosemite or any of the other platforms listed in the meta-facebook directory. After this step you land in openbmc/build, and the yocto/ directory and yocto_repos.sh in the tree are what the sync script works against, with a .buckconfig and .buckversion for the Buck build tool used by parts of the stack.

bitbake produces the image and four artefacts land in deploy

The build itself is a single bitbake invocation, run from inside the build directory:

bash
 $ bitbake <platform>-image

The process fetches the necessary packages and builds the complete image, and the results end up under openbmc/build/tmp/deploy/images/<platform>. Four artefacts matter. u-boot.bin is the u-boot image for the board, uImage is the Linux kernel, the <platform>-image-<platform>.cpio.lzma.u-boot file is the root filesystem, and flash-<platform> is the complete flash image combining the bootloader, the kernel and the rootfs. One detail in the README deserves emphasis for anyone taking this to a lab: the root password will be 0penBmc, and you may change this in the local configuration. The default is documented, which is helpful, but it also means an image flashed without that change ships with a known password.

devtool for kernel and bootloader work, without a full layer fork

By default the build fetches and builds the Linux kernel and u-boot directly from their GitHub repositories, which is the right choice for reproduction but the wrong one for development. The README gives the mechanism for working on them: in the build directory, run devtool modify linux-aspeed to create a local Linux package under <buildir>/workspace/sources/linux-aspeed, or devtool modify u-boot for the bootloader. When you are done, devtool reset linux-aspeed returns you to the default recipes. This is the part of the workflow that makes OpenBMC practical for kernel and driver work, because it lets you iterate on a single package without maintaining a private copy of the entire layer. The tree also holds a Documentation directory, a conf directory for configuration, tools, classes, tests2 and a github directory, plus a CONTRIBUTING file and a code of conduct.

Where the logs are, and how to change a fan speed that stays changed

The FAQ in the README is the most operationally useful part of the document, because it answers the questions a hardware team actually has on a bring-up bench. For debugging, the answer is always logs, and the file locations are specific. REST API problems are logged under /tmp, with /tmp/rest.log given as the example. Problems in the fan speed control daemon appear in the fscd logs under /var/log, with /var/log/fscd.log as the example, and mTerm data from the x86 CPU side is in /var/log/mTerm<something>.log, usually /var/log/mTerm_wedge.log on most platforms. Some persistent logs also go to the /mnt/data partition, and for everything else the answer is /var/log/messages. The second FAQ explains how to configure sensor thresholds. Fan RPM is changed with set_fan_speed.sh and read back with get_fan_speed.sh from the OpenBMC shell, with some platforms, especially storage and compute ones, using fan-util instead, and those scripts live under /usr/local/bin on the BMC. The catch is that the fscd process resets the fan speed, so a changed value will not persist unless the watchdog is turned off and fscd is killed. Temperature thresholds cannot be changed that way at all, they require modifying the code and building a new BMC image.

Contributing is structured by the same three layers

The contribution rules mirror the layer structure, which is a sensible way to route incoming patches to the right place. If you have an application that can be used by different BMCs, you contribute it to the OpenBMC common layer. If you are a BMC SoC vendor, you contribute SoC specific drivers to the BMC SoC layer. If you are a board vendor, you contribute to the board specific layer. The project is Apache-2.0 licensed with the LICENSE file at the root, which is the usual arrangement for a firmware stack that vendors embed into their own images. The recent releases are named with the flashy- prefix followed by a commit hash, with tags such as flashy-0ec2208 on 2026-09-16, flashy-caa4ca2 on 2026-09-04 and flashy-41815de on 2026-09-01, and the last push was on 2026-10-20. The naming convention is itself informative, since these are nightly or continuous-integration style tags rather than numbered releases with a changelog attached to each one.

Editorial conclusion

OpenBMC fits a hardware team bringing up a new switch, chassis or server board that needs a board management controller firmware, and that is prepared to work inside the Yocto build system rather than around it. It does not fit a team that wants a ready-made BMC image, or one that needs a different Linux distribution on the management controller. Before starting a build, read the layer structure in the README so your drivers land in the right meta-layer, plan for the sync step that pulls the Yocto repositories, and remember that the documented default root password has to be changed in the local configuration before any image reaches a lab.

Frequently asked questions

How do I build an OpenBMC image?

Set up the Yocto environment, clone the repository with git clone -b helium and run ./sync_yocto.sh, then initialise a build directory with source openbmc-init-build-env wedge, replacing wedge with your platform. From the build directory, run bitbake <platform>-image, and the artefacts appear under openbmc/build/tmp/deploy/images/<platform>.

What files does an OpenBMC build produce?

Four: u-boot.bin for the bootloader, uImage for the Linux kernel, <platform>-image-<platform>.cpio.lzma.u-boot for the root filesystem, and flash-<platform>, which is the complete flash image combining the bootloader, the kernel and the rootfs.

Where are the OpenBMC logs when a fan or sensor problem appears?

The README points REST API issues to /tmp, with /tmp/rest.log as the example, fan speed control daemon issues to the fscd logs under /var/log, mTerm data from the x86 side to /var/log/mTerm<something>.log, and everything else to /var/log/messages. Some persistent logs are written to the /mnt/data partition.

Can I change a fan speed threshold on a running BMC?

Partly. Fan RPM can be changed with set_fan_speed.sh and read back with get_fan_speed.sh from the OpenBMC shell, with some platforms using fan-util instead, but the fscd process will overwrite the value unless the watchdog is disabled and fscd is killed. Temperature thresholds require a code change and a new image build.

Official sources

  1. facebook/openbmc on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/facebook-openbmc.svg)](https://hysenlabs.com/projects/facebook-openbmc)

Was this useful?