Build an image
Set up the build container and build Home Assistant OS for a board.
Home Assistant OS builds inside a Debian based container that has every tool Buildroot needs. You do not install Buildroot's dependencies on your own machine, and every contributor builds in the same environment.
New to embedded Linux and Buildroot? The free training material from Bootlin is a good place to start. The Buildroot manual is the reference you will keep coming back to.
- A Linux machine with Docker, and permission to run privileged containers. Rootless Docker does not work: the build mounts a file system image on a loop device inside the container.
- A regular user account with
sudo. The build scripts refuse to run as root, but some steps need elevated privileges. - Disk space and time. A first build downloads and compiles everything, and takes an hour or more, depending on your machine.
The repository pulls in Buildroot as a Git submodule. Clone with the submodule:
git clone https://github.com/home-assistant/operating-system.git
cd operating-system
git submodule update --initWhen you pull new changes, update the submodule as well. Buildroot is updated regularly, and a mismatch causes confusing build errors:
git pull
git submodule updateTo throw away all your local changes and get back to a clean state:
git reset --hard
git submodule update --init --forceEach build target has a configuration file in buildroot-external/configs/, named <target>_defconfig. Pass the target name to make, without the _defconfig part. scripts/enter.sh builds the build container and runs the command in it:
scripts/enter.sh make rpi4_64make help lists every target. Supported boards explains which target is which board.
The build output goes to output/. The finished images are in output/images/, named after the board and version, like haos_rpi4-64-18.4.dev0.img.xz. Next to the disk image is a RAUC update bundle, .raucb, that you can use to update an existing installation. See test your build.
Downloads and the compiler cache are kept in ~/hassos-cache, outside the repository. Set CACHE_DIR to put them somewhere else. Later builds are much faster because of it.
One output folder holds one target. To build several boards from the same checkout, give each its own output folder with O=:
scripts/enter.sh make O=output_rpi4_64 rpi4_64
scripts/enter.sh make O=output_ova ovaIf you reuse an output folder for a different target, the build warns you and waits ten seconds. Run make distclean first in that case.
Buildroot builds packages from source and remembers what it has built. A second build only regenerates what changed and the final image. To force a package to build again, delete its build folder:
rm -rf output/build/linux-custom/Not sure which package a file in the image comes from? output/build/packages-file-list.txt maps every file to its package.
Without arguments, scripts/enter.sh opens a shell in the build container. From there you can run the same builds, and other Buildroot targets:
scripts/enter.sh
make O=output_rpi4_64 rpi4_64Targets the repository's Makefile does not know are passed on to Buildroot. For example, to change the configuration of a target interactively and then graph the dependencies between packages:
make O=output_rpi4_64 menuconfig
make O=output_rpi4_64 graph-dependsRun make buildroot-help to see everything Buildroot offers.
Every build signs its update bundle. The first time you build, a self-signed certificate and key are created as cert.pem and key.pem in the root of the repository, and added to the keyring in the image. Every later build uses the same pair. That way an image you built yourself accepts update bundles from your later builds. The update system has the details.
Keep the pair if you want to keep updating devices that run your builds. Deleting it means a new certificate, and devices with the old one will refuse your new bundles.