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.
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:
One interesting build artifact is the wic image. Let's have a look into it:
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:
# 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:
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:
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
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:
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:
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:
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:
Now let's take a look at what got built:
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):
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:
# df -h /var/business
Filesystem Size Used Available Use% Mounted on
/dev/mmcblk0p8 925.4M 280.0K 857.9M 0% /var/business
925.4M and not
1G.
One last thing to check in about the files of business.
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.