Partitioning of eMMC for A/B deployment support

I need some partitioning on the eMMC that supports A/B deployment for the rootfs+kernel+dtb:

partition | purpose | size | mount point

  • boot | u-boot + environment | 16MiB | /uboot
  • rootfs+kernel+dtb A | root file system A with kernel A and DTB A in /boot directory | 6GB | /rootfs if B inactive
  • rootfs+kernel+dtb B | root file system B with kernel B and DTB B in /boot directory | 6GB | /rootfs if A inactive
  • data | persistent data of rootfs+kernel A and B | 2,88GB | /data

I read the suggested answer for this related question. I think I need to change/implement the following.

  • modify MBR creation and partitioning by adding the partitions ~ update.sh
  • modify boot partition creation for u-boot by adding the kernel a/b and dtb a/b to the rootfs partitions a/b(instead of kernel image) ~ update.sh
  • modify rootfs partition creation by adding kernel and dtb (instead of rootfs only) ~ update.sh
  • create image for kernel+rootfs A and image for kernel+rootfs B (instead of single rootfs without kernel)
  • implement flash option for kernel+rootfs A image and for kernel+rootfs B image in the (run update_rootfs_kernel_A and run update_rootfs_kernel_B instead of run update_kernel and run update_rootfs) ~ flash_blk.scr
  • additional: modify mountpoint creation of rootfs to support 2 rootfs (instead of signle rootfs) [tegra-uboot-flasher/genext3fs.sh]
  • add expansion of the rootfs A and B to their full size of the partition they live in ~ fs-init.bb
  • add mounts in /etc/fstab (custom “dynamic” A and B switching ~ u-boot)

But as I do want to use Yocto (cannot use meta-toradex) it is not obvious for me how to do it actually.
Is this general procedure correct or did I miss something?
Could you get me some advice to adopt the instructions to a non-Yocto build?

Some more OTA software update specific details could pop up in this question in the future. They could be very specific to our product and would probably not be very helpful for others.

@roman.tx update.sh of Apalis_TK1_LinuxImageV2.6.1Beta2_20161122 states BOOT_START=$(expr 1024 \* 4 \* 2) and a size of 4MiB for IMAGE_ROOTFS_ALIGNMENT. I it correct that BOOT_START= needs to be changed to $(expr 1024 \* 2 \* 2)? Or is this size 8 MiB? (The same needs to be considered for BOOT_SPACE which seems to be 40MiB instead of 20MiB.)

Regarding to “modify MBR creation and partitioning by adding the partitions ~ update.” I tried as follows.

I modified update.sh:

@@ -205,7 +205,7 @@
 		CBOOT_IMAGE=apalis-tk1.img
 		CBOOT_IMAGE_TARGET=tegra124
 		# assumed minimal eMMC size [in sectors of 512]
-		EMMC_SIZE=$(expr 1024 \* 7450 \* 2)
+		EMMC_SIZE=$(expr 1024 \* 14900 \* 2)
@@ -343,17 +343,19 @@
 # user area aka general purpose eMMC region:
 #
 #    0                      -> IMAGE_ROOTFS_ALIGNMENT         - reserved (not partitioned)
-#    IMAGE_ROOTFS_ALIGNMENT -> BOOT_SPACE                     - kernel and other data
-#    BOOT_SPACE             -> SDIMG_SIZE                     - rootfs
+#    IMAGE_ROOTFS_ALIGNMENT -> BOOT_SPACE                     - u-boot + u-boot environment
+#    BOOT_SPACE             -> ROOTFS_A_SIZE                  - rootfs + kernel + dtb A
+#    ROOTFS_A_SIZE          -> ROOTFS_B_SIZE                  - rootfs + kernel + dtb B
+#    ROOTFS_B_SIZE          -> DATA_SIZE                      - persistent data
 #
-#            4MiB               16MiB           SDIMG_ROOTFS
-# <-----------------------> <----------> <---------------------->
-#  ------------------------ ------------ ------------------------
-# | IMAGE_ROOTFS_ALIGNMENT | BOOT_SPACE | ROOTFS_SIZE            |
-#  ------------------------ ------------ ------------------------
-# ^                        ^            ^                        ^
-# |                        |            |                        |
-# 0                      4MiB      4MiB + 16MiB              EMMC_SIZE
+#            4MiB               16MiB         6000MiB         6000MiB        2880MiB
+# <-----------------------> <----------> <-------------> <--------------> <---------->
+#  ------------------------ ------------ ---------------------------------------------
+# | IMAGE_ROOTFS_ALIGNMENT | BOOT_SPACE | ROOTFS_A_SIZE | ROOTFS_B_SIZE | DATA _SIZE |
+#  ------------------------ ------------ ---------------------------------------------
+# ^                        ^            ^               ^               ^            ^
+# |                        |            |               |               |            |
+# 0                      4MiB      4MiB + 16MiB   20MiB + 6GiB  6,02GiB + 6GiB     14,9GiB
@@ -374,9 +376,14 @@
 else
 	if [ "${MODTYPE}" = "apalis-t30" ] || [ "${MODTYPE}" = "apalis-tk1" ] || [ "${MODTYPE}" = "colibri-t30" ] ; then
 		# Boot partition [in sectors of 512]
-		BOOT_START=$(expr 4096 \* 2)
-		# Rootfs partition [in sectors of 512]
-		ROOTFS_START=$(expr 20480 \* 2)
+		BOOT_START=$(expr 1024 \* 4 \* 2)
+		# Rootfs A partition [in sectors of 512]
+		ROOTFS_A_START=$(expr 1024 \* 20 \* 2)
+    # Rootfs B partition [in sectors of 512]
+		ROOTFS_B_START=$(expr 1024 \* 6020 \* 2)
+		# Data partition [in sectors of 512]
+		DATA_START=$(expr 1024 \* 12020 \* 2)
@@ -385,11 +392,14 @@
 		# Initialize a sparse file
 		dd if=/dev/zero of=${BINARIES}/mbr.bin bs=512 count=0 seek=${EMMC_SIZE}
 		${PARTED} -s ${BINARIES}/mbr.bin mklabel msdos
-		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary fat32 ${BOOT_START} $(expr ${ROOTFS_START} - 1 )
-		# the partition spans to the end of the disk, even though the fs size will be smaller
-		# on the target the fs is then grown to the full size
-		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary ext2 ${ROOTFS_START} $(expr ${EMMC_SIZE} \- ${ROOTFS_START} \- 1)
-		${PARTED} -s ${BINARIES}/mbr.bin unit s print 
+		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary fat32 ${BOOT_START} $(expr ${ROOTFS_A_START} - 1 )
+		# the partition of rootfs+kernel+dtb A and B are greater than the fs size
+		# on the target the file systems are then grown to the full size of the partitions
+		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary ext3 ${ROOTFS_A_START} $(expr ${ROOTFS_B_START} \- 1)
+		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary ext3 ${ROOTFS_B_START} $(expr ${DATA_START} \- 1)
+		${PARTED} -a none -s ${BINARIES}/mbr.bin unit s mkpart primary ext3 ${DATA_START} $(expr ${EMMC_SIZE} \- 1)
+		#${PARTED} -s ${BINARIES}/mbr.bin set 1 boot on
+		${PARTED} -s ${BINARIES}/mbr.bin unit GiB print

I created the TFTP update media using:

./update.sh -c -m 2 -o /srv/tftp/

Powered the board on and interrupted the autoboot.

Updated the flash scripts and flashed the MBR into the eMMC:

Apalis TK1 # run setupdate
....
Apalis TK1 # run update_1

I checked the partition table:

Apalis TK1 # mmc dev 0 0
Apalis TK1 # mmc part                                                                                                                                  

Partition Map for MMC device 0  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     8192            32768           000a7e26-01     0c
  2     40960           12288000        000a7e26-02     83
  3     12328960        12288000        000a7e26-03     83
  4     24616960        5898240         000a7e26-04     83

I did a full update:

Apalis TK1 # run setupdate

and rebooted…:

Apalis TK1 # boot

…into Angström (no password):

apalis-tk1 login: root
root@apalis-tk1:~#

Does that make sense or do you see some issues (something missing or not correct)?