This article serves as a guide on how to create a custom microSD card image for the BeagleBone Black. The steps described in this guide are pretty much platform agnostic. One could also adjust them to other systems, besides the BeagleBone Black.
The BeagleBone Black is an open hardware ARM single-board computer, very popular for its attractive price and rich set of features.
The system ships with an Ångström Linux distribution installed in its internal 2GB flash, while a microSD card slot allows running other operating systems as well (or replacing the contents of the internal flash).
Various pre-made microSD card images are available, and eewiki.net has very detailed steps on creating a microSD with your own contents.
However, what we could not find (and decided to write about it) was a guide on how to generate our own image of a microSD for the BeagleBone Black. This can come in handy in several situations, such as when you want to:
- prepare all the work without having the actual microSD card at hand.
- use the card image in a virtual machine.
- maintain different versions of your installation.
- automate the process via scripts, without being forced to write the result to a microSD card every time.
- speed up the creation of multiple microSD cards from the same image.
The following links were used as input while writing this guide.
In order to perform the tasks described in this guide, you will need the following.
- A standard GNU/linux distribution. We use Debian.
- Root access via
sudo. If you prefer
su, adjust the steps accordingly.
sfdisk tool. In Debian-based distributions, install the package “util-linux”.
kpartx tool. In Debian-based distributions, install the package “kpartx”.
mkfs.ext4 tools. In Debian-based distributions, install the packages “dosfstools” and “e2fsprogs”.
Optionally, you might also want to use the following.
ddrescue tool. In Debian-based distributions, install the package “gddrescue”.
qemu-img tool. In Debian-based distributions, install the package “qemu-utils”.
If you use a Debian-based distribution and you want to install all of the above tools at once, you can issue the following command.
$ sudo apt-get install util-linux kpartx dosfstools e2fsprogs gddrescue qemu-utils
Create an empty image
The first step is to create an empty image file of an appropriate size. For our example, we will be creating a 500MiB image file (with a MiB being defined by IEC as 1024×1024 bytes, also known as a Mebibyte).
This task can be accomplished in many ways. The most standard way is to use the
dd command, which is available and installed in all GNU/Linux distributions, as part of the GNU coreutils software package.
$ dd if=/dev/zero of=bbb.img bs=1M count=500
In the above command, we create a file named
bbb.img, filled with zeroes, using 500 blocks of 1MiB each.
Another way is to make use of a little utility from QEMU.
$ qemu-img create bbb.img 500M
Partition the image
The next step is to create partitions inside the empty image file, as if it were a physical storage media. We use
sfdisk for this task and we provide all the necessary parameters via standard input.
$ sudo sfdisk --in-order --Linux --unit M bbb.img << EOF
In the above example, we create two partitions inside our image file. The first one will be the boot partition, starting at an offset of 1MiB, with a size of 48MiB and partition id “W95 FAT16 (LBA)”. The second one will consume all remaining space (451MiB in our example) and will have the default partition id (“Linux”).
Format and mount the partitions
As with any newly-partitioned media, we also have to create filesystems inside our partitions.
However, before we do that, we will use the excellent
kpartx command from multipath-tools, to make the handling of the partitions inside our image easier.
$ sudo kpartx -av bbb.img
Keep note of the output of the above command, in our example it was:
add map loop0p1 (253:0): 0 98304 linear /dev/loop0 2048
add map loop0p2 (253:1): 0 923648 linear /dev/loop0 100352
We are mainly interested in the loop device name (in our case loop0).
The above command makes use of the device mapper mechanism of the linux kernel to create virtual block devices for the two partitions inside our image. Assuming that kpartx reported
loop0 as the loop device name, our two partitions will now be available as
We can now format our partitions and mount them in temporary folders. We use FAT16 for the boot partition and assign the label “boot” to it, and EXT4 for the root partition and assign the label “rootfs” to it.
$ sudo mkfs.vfat -F 16 /dev/mapper/loop0p1 -n boot
sudo mkfs.ext4 /dev/mapper/loop0p2 -L rootfs
mkdir -p tmpmnt/boot
mkdir -p tmpmnt/rootfs
sudo mount /dev/mapper/loop0p1 tmpmnt/boot/
sudo mount /dev/mapper/loop0p2 tmpmnt/rootfs/
Make sure that you replace the loop device names with whatever was reported when you executed the
We are now ready to add files to our image.
Adding files to image
With both our partitions mounted as virtual block devices, we can copy any files we like into them, using any standard file copying method, be it command-line or graphical.
For a typical BeagleBone Black installation, we will be copying the bootloader (u-boot), the linux kernel image (zImage) and the compiled device tree structures (.dtb files) to the boot partition, while the actual root filesystem and any linux kernel modules will be copied to the root partition.
You can refer to the BeagleBone Black page on eewiki.net for more information on how to obtain these files and where exactly to copy them inside your image file.
You can also check out the Debian Live project if you are looking for a way to generate your own root file system from scratch.
Assuming that you have the bootloader, kernel and filesystem, make sure that you first copy the MLO file, followed by the u-boot.img file of the bootloader into an empty, freshly formatted FAT16 boot partition. The remaining files can be copied in any order.
Finish image creation
When we are done with adding files to the image, we must make sure that all files have finished being copied to the image, unmount the virtual block devices and release them.
sudo umount tmpmnt/boot/
sudo umount tmpmnt/rootfs/
sudo kpartx -dv bbb.img
That’s all. The image is now ready and you can use it as it is, or copy it to a microSD card.
Copy image to microSD card (optional)
To copy the image file to a microSD card, you can use the standard
$ sudo dd if=bbb.img of=[block_device]
Alternatively, we suggest using
ddrescue, which has a more verbose output.
$ sudo ddrescue -f bbb.img [block_device]
In the above commands, replace
[block_device] with the block device name of your microSD card (such as