For most use cases, the official OS images for the BeagleBone Black (BBB) will work just fine. However, sometimes you want to create your own custom image. And, if you find yourself doing that more than sometimes - like myself - you will want a repeatable process for generating the custom images. For that I recommend using Robert C. Nelson's OMAP Image Builder, available on GitHub. Using the config files already in the project as a reference, you can easily generate your own custom BBB OS image. In this post I'll provide you with an overview of the OMAP Image Builder project so you know what's what, and walk you through making your own custom OS image for the BBB.

Requirements and recommendations


It is highly recommended you use actual ARM7 hardware for building images. If you don't have access to something beefier than a BBB, and you don't want to buy a another (more expensive) board, check out Scaleway. They provide bare-metal ARM computers via a service similar to Linode or DigitalOcean. If you want a non-cloud option, the Wandboard Quad with an attached SATA drive is probably your best value.


I've used Ubuntu or Debian as the host OS when creating all of my images. You can probably get a Redhat-based distro to work, but I can't vouch for it. I doubt you can use OSX, but I'd love to be proven wrong.


This post is targeted towards those who are generally familiar with Linux, and are comfortable with Bash scripting. You'll probably be asked to install a number of missing packages and dependencies, so you should be familiar with how to install software through a CLI package manager. Also if you aren't familiar with chroot, Google it, as it is an essential concept in the image-creation process.

OMAP Image Builder overview

Building an image with the OMAP Image Builder is essentially a two-step process.

  1. Generate an OS filesystem in a chroot jail with custom attributes defined in a config file:

    ./ -c your_config_file

  2. Turn that filesystem into an image that can be copied to a microSD card:

    ./ [a] [bunch] [of] [options]

You can see some examples in the project README.


If you haven't done so yet, open the OMAP Image Builder GitHub project in a new tab. We'll be referring back to it. Here is the project structure:

├── configs
├── docs
├── machinekit
├── publish
├── scripts
│   ├──
│   ├──
│   └──
├── target
│   ├── boot
│   ├── chroot
│   ├── init_scripts
│   ├── keyring
│   └── other
└── tools
    ├── hwpack

I've omitted all the files except the few we're interested in.

So what's important?

  1. - This is main script for building root filesystem. Input is a config.
  2. configs/ - This folder contains the config files that can be used with
  3. target/ - This folder contains scripts, referenced in the config files, that can be optionally accessed while building the filesystem or by
  4. target/chroot/ - This folder contains scripts that can be executed from within the generated filesystem without knowledge of the host.
  5. target/boot - Various boot configs.
  6. - Script that generates the image file from what makes.

Configs and chroot scripts

These configs are the input for They may also refer to other scripts which will be executed at some point during the build process. In the configs folder you will find a template config file, but without guiding documentation, making it difficult to tell what each variable's purpose is, or what format its value should take. Rather than using that template to make a new config, it is often easier to take a preexisting config file, copy it, and edit it.

Let's take a closer look at There are a lot of variables, though there are only a few that you will probably want to change.

  1. deb_include - These are the packages that are installed by debootstrap, an application that installs a complete Debian base system in a subdirectory.
  2. deb_exclude - These are the packages that would be installed...but you don't want.
  3. deb_additional_pkg - Packages listed here are not installed natively by debootstrap, and will likely fail if done in QEMU on non-ARM7 hardware. Remember that warning about building on ARM7? This partly why. It's best to try to install packages via deb_include.
  4. rfs_username, rfs_fullname, and rfs_password - I think 'rfs' stands for "root filesystem". This is where you define the default username and password.
  5. chroot_script - The script in target/chroot/ that you want to execute from inside the chroot while building an image. This where you can install python packages, clone git repos, setup configs, etc. all from inside the chroot. Open up the chroot script, that is This a bit confusing, but this is what you use to install system packages. I recommend looking at the other scripts in this folder to see what they do.
  6. chroot_after_hook - This isn't currently used by any of the configs in the configs/ folder, but it's essentially like chroot_script; however, the script resides in the project root, and is executed outside of the chroot. This is useful if you have something on the host computer that you need to add to the chroot. Look at the and see where chrootafterhook is called. is not particularly well documented, but luckily there are a couple good examples of how to use it in I personally haven't strayed from these, but if you read the script, you will see that there are a lot more options available. I haven't verified this with the author, but I assume this is the script that is used to generate the official BeagleBone Black images.

In the script you can see this function:

generic_img () {  
        cd \${base_rootfs}/
        sudo ./ \${options}
        mv *.img ../
        cd ..

and a little further down you can see it being used to make the image:

options="--img-2gb BBB-eMMC-flasher-\${base_rootfs} --dtb beaglebone --boot_label BEAGLEBONE --enable-systemd --bbb-flasher --bbb-old-bootloader-in-emmc --hostname beaglebone"  

Let's look at some of the options used.

  1. img-2gb - This is basically defining how big the image will be. Important for BeagleBone Black owners as the latest generation (rev C) has a 4GB eMMC, while past generations had a 2GB eMMC.
  2. dtb - I think this is where you say which hardware profile to use from tools/hwpack.
  3. bbb-flasher - make it an eMMC flasher (flash the eMMC with the image), as opposed to booting off the SD card.

All together now

Ok let's make a custom image! This is what we're going to do:

  1. Clone the repo
  2. Make a custom config file
  3. Make a custom chroot script
  4. Generate our root filesystem
  5. Make an eMMC flasher image out of the root filesystem
  6. Compress the image so you can easily send it to all your friends

Step 1: Clone that repo

Git clone the OMAP Image Builder project. If you're unfamiliar with git, Atlassian has this great guide.

git clone && cd omap-image-builder

Step 2: Create a custom config

Copy a config you like to a different name:

cp configs/ configs/custom-image.conf  

In configs/custom-image.conf add or remove some packages from deb_include. I love htop, nmap, and moon-buggy, so I'm adding those. Change any of the other variables that you feel comfortable changing. Feel free to look at other configs for inspiration.

deb_include="ca-certificates dosfstools dbus initramfs-tools linux-base \  
openssh-server patch rsync sudo systemd wget htop nmap moon-buggy"  

Step 3: Create a custom chroot script

Copy a chroot script you like to a different name:

cp target/chroot/ target/chroot/  

Open the config file you just made, and make sure to change chroot_script to point at your new script:


Ok, back to Let's install some more python packages. In your new config, find the function install_pip_pkg. Here it is in the original script. I like ipython and ipdb, so i'm going add those here:

pip install Adafruit_BBIO ipython ipdb  

At the bottom of the script, uncomment #install_pip_pkgs.

Step 4: Generate the root filesystem

./ -c custom-image

Get a coffee... this will take a while.

Step 5: Generate an .img file

Finished? No errors? Cool, let's make an image. The last step made a deploy/ directory. The root filesystem is in there.

cd deploy  

In there you will see a folder with the name of the filesystem you created. If you used the as your reference, it's probably something like debian-7.8-console-armhf. cd into that directory.

In this directory you should see Use that to make a eMMC flasher image.

sudo ./setup_sdcard --img-2gb BBB-eMMC-flasher-debian-7.8-console-armhf --dtb beaglebone --boot_label BEAGLEBONE --enable-systemd --bbb-flasher --bbb-old-bootloader-in-emmc --hostname beaglebone"  

This should generate an image file named BBB-eMMC-flasher-debian-7.8-console-armhf-2gb.img.

Step 6: Compress that image file

If you used the --img-2gb option, your .img file should be just shy of 2 GB. We should be able to compress that down to under 500 MB. To do so, do this:

xz -z -8 -v BBB-eMMC-flasher-debian-7.8-console-armhf-2gb.img  

This takes a few minutes, but afterwards you'll have a much smaller file to distribute.


It is way easier to just install an OS using the provided images, and configure them after deploying. There is no shame in that. If you don't need a custom image, don't use one!

But, for those scenarios that don't allow for using the stock images, I'm thankful that Robert Nelson has provided the OMAP Image Builder and made it simple to add new configs. Also see this post about modifying an image with the loop device. Good luck hacking!