Skip to content

Add a RW data partition

Overview

In this tutorial, you'll create and configure your own Yocto layer and add a read-write (RW) partition to your system.

What you'll learn:

  • How to add partitions and set their sizes
  • How to populate them and leverage the split feature of Welma
  • How partitions and filesystems are related
  • How to use the wic tool to explore your image

What you'll need:

  • A workstation with a Linux operating system

  • A Raspberry Pi 4B device

  • The device is reachable from you workstation through an IP network by SSH, using the name device-under-test.

Step 1: initial setup

Create your working directories on your workstation:

ROOT=...               # your root working directory
mkdir $ROOT/build      # your Yocto build directory
mkdir $ROOT/sources    # your Yocto layers

Download Welma into $ROOT/sources:

cd $ROOT/sources

MACHINE=raspberrypi4-64-welma
WELMA_REF=scarthgap-next
WELMA_GIT_NAMESPACE=witekio/rnd/theembeddedkit/welma

git clone git@gitlab.com:$WELMA_GIT_NAMESPACE/welma-manifest.git
welma-manifest/setup-download welma-manifest/$WELMA_REF/manifest-$MACHINE.txt

Set up your Yocto build directory in $ROOT/build.

Terminal-1: Yocto build environment
cd $ROOT
source sources/meta-welma/setup/setup-build-env \
       sources/meta-welma-raspberrypi/conf/templates/$MACHINE

If you did not fuse the PBKH on your device, do not try to do it now, but be sure to add WELMA_SECURE_BOOT="0" in your conf/local.conf.

Build the development image:

Terminal-1: Yocto build environment
bitbake welma-image-minimal-dev

One interesting build artifact is the wic image. Let's have a look into it:

Terminal-1: Yocto build environment
gunzip --force --keep \
    tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic.gz

wic ls tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic
Num     Start        End          Size      Fstype
 1       4194304     35651583     31457280  fat16
 2      35651584     88080383     52428800  fat16
 3      88080384    140509183     52428800  fat16
 4     140509184    559939583    419430400
 5     559939584    979369983    419430400
 6     979369984    995098623     15728640
 7     995098624   1010827263     15728640
 8    1010827264   1430257663    419430400  ext4

The wic image is something that can be flashed directly to a SD card, eMMC, USB flash drive, SSD... It contains:

  • the partition table (ie: start offset and size of each partition)
  • the contents of the partitions (which can be filesystems or raw data)

Here is the manually annotated version:

Num     Start        End          Size      Fstype
 1       4194304     35651583     31457280  fat16     # bootloader (vfat)
 2      35651584     88080383     52428800  fat16     # boot A (vfat with kernel, initramfs)
 3      88080384    140509183     52428800  fat16     # boot B (vfat with kernel, initramfs)
 4     140509184    559939583    419430400            # sysro A (ext4 + verity header)
 5     559939584    979369983    419430400            # sysro B (ext4 + verity header)
 6     979369984    995098623     15728640            # appro A (ext4 + verity header)
 7     995098624   1010827263     15728640            # appro B (ext4 + verity header)
 8    1010827264   1430257663    419430400  ext4      # sysrw (ext4)

But this does not show everything of the storage memory layout. A more accurate view is this one:

The key things are:

  • The contents of a partition (whether raw data or filesystem) does not fill all the memory region allocated for the partition. In particular, at runtime, if you enter the command df, it will not show the size of the partition, but the size of the filesystem, which is smaller.

  • Memory regions should not overlap.

  • Data may be located anywhere out of partitions. In our case, we have bootflags and datastore located out of regular partitions.

Step 2: create a Yocto layer

We're now going to prepare a Yocto layer where we'll add our modifications.

Create a dedicated directory $ROOT/sources/meta-partitioning, in which you create the following:

meta-partitioning/conf/layer.conf
# Add layer to BBPATH
BBPATH .= ":${LAYERDIR}"

# Add recipes to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
            ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "partitioning-layer"
BBFILE_PATTERN_partitioning-layer = "^${LAYERDIR}/"
BBFILE_PRIORITY_partitioning-layer = "1000"

LAYERVERSION_partitioning-layer = "1"
LAYERSERIES_COMPAT_partitioning-layer = "scarthgap"

Add meta-partitioning in bblayers and build:

Terminal-1: Yocto build environment
cat << EOF >> conf/bblayers.conf
BBLAYERS =+ "$ROOT/sources/meta-partitioning"
EOF

At this point, you should make sure that meta-partitioning takes precedence over meta-welma-raspberrypi and meta-welma, and that your BBPATH reflects this:

bitbake-getvar -r welma-image-minimal-dev BBPATH
...
BBPATH=...:.../meta-partitioning:.../meta-welma-raspberrypi:.../meta-welma:...

This variable BBPATH will determine the search path of files that we'll use in the next section.

Then you can build:

bitbake welma-image-minimal-dev

The build should succeed, but the built image does not contain any modification yet!

Step 3: add a RW partition

We're now going to create a new partition between appro B and sysrw, with a RW ext4 filesystem inside it. The size of the partition will be 1 GiB and the ext4 filesystem will fill the entire partition, so that we'll be able to store up to 1 GiB of data (actually a little less as the ext4 filesystem overhead will take some space). This filesystem will be mounted at /var/business.

Create these files:

meta-partitioning/recipes-welma/images/welma-image-minimal-dev.bbappend
meta-partitioning/split/welma.part
meta-partitioning/split/welma.split
meta-partitioning/wic/welma.wks.in

meta-partitioning/recipes-welma/images/welma-image-minimal-dev.bbappend
ROOTFS_POSTPROCESS_COMMAND += "mkdir_business;"

mkdir_business() {
    install --directory --mode=755 ${IMAGE_ROOTFS}/var/business
    echo hello > ${IMAGE_ROOTFS}/var/business/hello.txt
}

In this bbappend, we create a new directory /var/business that will serve as a mounting point and a separation between filesystems: the contents of /var/business will in the end lie on a different filesystem and partition than /var.

The .part file should look like this:

meta-partitioning/split/welma.part
part boot     size=50M,update=ab,dev=/dev/mmcblk0p2:/dev/mmcblk0p3
part sysro    size=400M,update=ab,dev=/dev/mmcblk0p4:/dev/mmcblk0p5
part appro    size=15M,version=0.0,update=ab,dev=/dev/mmcblk0p6:/dev/mmcblk0p7
part business size=1G,dev=/dev/mmcblk0p8
part sysrw    size=400M,dev=/dev/mmcblk0p9

This .part file adds the business line to the default Welma .part. We specify on which physical partition business shall be stored (dev=/dev/mmcblk0p8) and the size of the partition (size=1G). This size is used by the Yocto recipes to populate the variable PARTITION_SIZE_business that we'll use below.

The .split file is as follows:

meta-partitioning/split/welma.split
split boot     /boot         vfat    overhead=1.1,minsize=4096,boot,mount=ro
split sysro    /             ext4    overhead=1.1,${SPLIT_VERITY_OPT}
split appro    /app          ext4    overhead=1.1,extrasize=4096,${SPLIT_VERITY_OPT},systemd
split business /var/business ext4    overhead=1.0,minsize=1048576,mount=rw
split sysrw    /var          ext4    overhead=1.3,extrasize=390000,mount=defaults:noexec

migrate    /home    /var/home    bind

This .split file adds the business line to the default Welma .split. In this line, we specify where the business partition shall be mounted (/var/business), which filesystem should be used (ext4), an exact size for the filesystem (overhead= and minsize=), and that it should be mounted in read-write mode (mount=rw).

Let's explain why we're using here overhead=1.0 and minsize=. The extrasize and overhead parameters map to the IMAGE_ROOTFS_EXTRA_SPACE and IMAGE_OVERHEAD_FACTOR variables of Yocto. They are meant to extend the size of the filesystem beyond what is needed to store the files that lie in /var/business at build time. Therefore it is difficult to get their value right so that the filesystem spans exactly the whole partition. Instead, we're using minsize which maps to the Yocto variable IMAGE_ROOTFS_SIZE and specifies an exact size.

We also need to create the business partition in the wic description file to have is consistent with what we've done before:

meta-partitioning/wic/welma.wks.in
part --source bootimg-partition --fstype=vfat --label boot --active --align 4096                            --fixed-size 30M

# boot
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.boot.vfat${IMG_SUFFIX_boot}"  --fixed-size ${PARTITION_SIZE_boot}
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.boot.vfat${IMG_SUFFIX_boot}"  --fixed-size ${PARTITION_SIZE_boot}

# rootfs
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.sysro.ext4${IMG_SUFFIX_sysro}" --fixed-size ${PARTITION_SIZE_sysro}
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.sysro.ext4${IMG_SUFFIX_sysro}" --fixed-size ${PARTITION_SIZE_sysro}

part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.appro.ext4${IMG_SUFFIX_appro}" --fixed-size ${PARTITION_SIZE_appro}
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.appro.ext4${IMG_SUFFIX_appro}" --fixed-size ${PARTITION_SIZE_appro}

# /var/business
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.business.ext4${IMG_SUFFIX_business}" --fixed-size ${PARTITION_SIZE_business}

# /var
part --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.sysrw.ext4${IMG_SUFFIX_sysrw}" --fixed-size ${PARTITION_SIZE_sysrw}

bootloader --ptable gpt

In this wic description file, we added one partition for /var/business. We're using PARTITION_SIZE_business, which is automatically computed after the size that we configured (size=1G).

Let's build now:

Terminal-1: Yocto build environment
bitbake welma-image-minimal-dev

Now let's take a look at what got built:

Terminal-1: Yocto build environment
gunzip --force --keep \
    tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic.gz

wic ls tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic
Num     Start        End          Size      Fstype
 1       4194304     35651583     31457280  fat16
 2      35651584     88080383     52428800  fat16
 3      88080384    140509183     52428800  fat16
 4     140509184    559939583    419430400
 5     559939584    979369983    419430400
 6     979369984    995098623     15728640
 7     995098624   1010827263     15728640
 8    1010827264   2084569087   1073741824  ext4
 9    2084569088   2503999487    419430400  ext4

wic ls tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic:8
      2   40755 (2)      0      0    4096  4-Feb-2026 14:53 .
      2   40755 (2)      0      0    4096  4-Feb-2026 14:53 ..
     11   40700 (2)      0      0   16384  4-Feb-2026 14:53 lost+found
     13  100644 (1)      0      0       6  9-Mar-2018 13:34 hello.txt

You can see that the file hello.txt has been moved to the right partition. This is done by the split feature of Welma.

Then, install the image on your device:

  • Insert the SD card in your workstation.

  • Copy the Welma image to the SD card (be careful about the destination /dev/mmcblk0, your milage may vary):

Terminal-1: Yocto build environment
gunzip --stdout \
    tmp/deploy/images/$MACHINE/welma-image-minimal-dev-$MACHINE.wic.gz |
    sudo dd of="/dev/mmcblk0" bs=10M
sync

Remove the SD card from your workstation, and insert it into your device. Do the cabling so as to get SSH access to your device. Then start your device, connect to it via SSH, and look at the available space:

On your device
# df -h /var/business
Filesystem                Size      Used Available Use% Mounted on
/dev/mmcblk0p8          925.4M    280.0K    857.9M   0% /var/business
That is consistent with our configuration, as the overhead taken by the ext4 filesystem explains why the total size is 925.4M and not 1G.

One last thing to check in about the files of business.

On your device
# cat /var/business/hello.txt
hello

The file hello.txt is there, all right!

Summary

You learned how to add and customize a new partition in your system, set its size and populate its contents. You also learned how partitions and filesystems are related. Finally you learned how the wic tool can help verifying and investigating.

You'll find more features and properties to configure by reading the page about Partitioning.