Modify Storage Partition Layout

Canonical releases generic disk images with fixed partition layouts for all MediaTek Genio reference boards. But, some cases require adjustments to the partition layouts for your board, while re-using the root file system and boot partitions provided by Canonical.

This can be achieved by the following steps:

  1. Extract root FS partition(writable) and EFI system loader partition(ubuntu-boot) images from the ubuntu.img file released by Canonical, which is a full-disk image.

  2. Program the partition image onto your board storage. There are two possible approaches:

    1. Update a single partition on the eMMC storage of your board, if it is already formatted. This can be helpful during board bring-up and development stages.

    2. Combine the Ubuntu partition images and your bootloader partition iamges into a single full-disk image, and use genio-flash tool to format and program the entire board storage.

The steps are as following sections.

Extract RootFS and Ubuntu-Boot Partition Images

To do so, you need a Ubuntu host machine.

  1. Install required packages using the following command:

    sudo apt-get update; sudo apt install -y android-sdk-libsparse-utils sleuthkit
    
  2. Download Ubuntu image package and extract it. Locate the file ubuntu.img.

  3. The file format of ubuntu.img is an Android sparse image, so we need to convert it into raw image:

    simg2img ubuntu.img disk.img
    
  4. Then we can check each partition in the raw full-disk image file disk.img:

    mmls disk.img
    

    The result should be similar to this:

    GUID Partition Table (EFI)
    Offset Sector: 0
    Units are in 512-byte sectors
    
        Slot Start End Length Description
    000: Meta 0000000000 0000000000 0000000001 Safety Table
    001: ------- 0000000000 0000001023 0000001024 Unallocated
    002: Meta 0000000001 0000000001 0000000001 GPT Header
    003: Meta 0000000002 0000000033 0000000032 Partition Table
    004: 000 0000001024 0000009215 0000008192 bootloaders
    005: 001 0000009216 0001033215 0001024000 ubuntu-boot
    006: 002 0001033216 0006525427 0005492212 writable
    007: ------- 0006525428 0006559743 0000034316 Unallocated
    

    Please note the index (000 to 007 above) of each partition:

    • writable is the root filesystem partition containing the Ubuntu system.

    • ubuntu-boot is the EFI system loader partition which contains system loader applications such as GRUB and also the kernel images. This is mounted as /boot under Ubuntu.

    • bootloaders partition are board-specific bootloaders, and usually you don’t want or need to extract this partition from ubuntu.img, since it is only applicable to a MediaTek Genio EVK board.

  5. Extract writable and ubuntu-boot partition. In the example above, these are partition 5 and 6 accordingly. Please adjust the index if they are different in your cases:

    mmcat disk.img 5 > ubuntu-boot.img
    mmcat disk.img 6 > writable.img
    

The resulting file, ubuntu-boot.img and writable.img are raw images that you need. Depending on your use cases, you have 2 options to apply these the images:

  1. Convert these images into Android sparse image format and flash a single partition on your eMMC storage, if it is already being formatted.

  2. Combine ubuntu-boot.img, writable.img and your own bootloader image partitions into your own full-disk image, and flash an unformatted eMMC storage on your board.

Update Single Partitions in a Formatted Storage

If your board is already formatted and you simply want to update the Ubuntu rootFS partition, you could convert the partition images into Android sparse image format and then update single partitions with genio-flash, provided that it is already formatted. This approach would be more useful during board-bringup and development.

To do so, follow these steps:

  1. Convert the image format from raw imgae to android sparse image format:

    # Usage: img2simg <raw_image_file> <sparse_image_file> [<block_size>]
    $ img2simg ubuntu-boot.img system-boot.img 1024
    $ img2simg writable.img ubuntu-rootfs.img 1024
    

    Note

    Depending on your OS and tool version, the parameter to img2simg could be different. Please refer to the help text of the img2simg installed in your host PC.

  2. Copy the resulting sparse image files system-boot.img and ubuntu-rootfs.img into your boot-asset directory.

  3. Locate the file ubuntu.json in your image directory. This file should be part of the Ubuntu boot asset. Make sure the properties writable and ubuntu-boot exist in the partitions element in the json file:

    {
        "ubuntu-env": {
            "edition": "ubuntu classic/core images",
            "codename": "jammy",
            "version": "22.04",
            "mtk-aiot": "i500/i1200-demo/g700/g1200-evk"
        },
        "ethernet": {
            "oui": "00:0C:E7",
            "num-of-eth": 1
        },
        "aiot-tools": {
            "min-version": "1.1.0"
        },
        "partitions": {
            "mmc0": "ubuntu.img",
            "mmc0boot0": "bl2.img",
            "mmc0boot1": "u-boot-env.bin",
            "bootloaders": "fip.bin",
            "ubuntu-boot": null,
            "writable": null
        },
        "groups": {
            "all": {
            "erase": ["mmc0", "mmc0boot0", "mmc0boot1"],
            "flash": ["mmc0", "mmc0boot0", "mmc0boot1", "bootloaders"]
            },
            "bootloaders": {
            "flash": ["bootloaders"]
            }
        }
    }
    

    If those properties does not exist, please add these lines to the json file manually. Note that JSON properties must be comma-separated and there must be no trailing comma.

  4. To erase and update a partition labeled as <partition-name> using a partition image file <partition-img>, use the following command:

    $ genio-flash <partition-name>:<partition-img>
    

    For example, to update the rootfs and EFI system loader, use the following commands:

    $ genio-flash writable:ubuntu-rootfs.img ubuntu-boot:system-boot.img
    
  5. The following log output should appear if genio-flash successfully found the partition with label ubuntu-boot on the storage:

    Sending bootstrap to address: 0x201000
    Jumping to bootstrap at address 0x201000 in AArch64 mode
    flashing ubuntu-boot=system-boot.img
    < waiting for any device >
    Invalid sparse file format at header magic
    Sending sparse 'ubuntu-boot' 1/1 (76396 KB)        OKAY [  1.810s]
    Writing 'ubuntu-boot'                              OKAY [  2.744s]
    Finished. Total time: 6.019s
    Rebooting                                          OKAY [  0.002s]
    

Combine Partition Images into Full-Disk Image

One approach to combine separate partition images into full-disk images is to use the wic tool that is part of the Yocto project.

The follow steps shows you how to use the wic tool from IoT Yocto to pack your own Ubuntu full-disk image. You need a Ubuntu host machine to build IoT Yocto projects and also wic tool.

  1. Download IoT Yocto recipes as shown in IoT Yocto Get Started. Note that you don’t need to run the bitbake rity-demo-image command just yet.

  2. To build the wic tool, use the following commands:

    $ source src/poky/oe-init-build-env; DISTRO=rity-demo MACHINE=<your-board> bitbake wic-tools"
    

    Replace <your-board> with the MACHINE name that you’ve used to port the board bootloader. If the tool builds successfully, you should be able to use the wic commands:

    $ wic --version
    wic 0.2.0
    

    Since this wic tool is part of the bitbake tool that requires Yocto build environment, please make sure that source src/poky/oe-init-build-env is executed every time you login to a new shell session.

  3. Prepare a WIC Kickstart (.wks) file that defines layout of your full disk image. The following example assumes that you want to have 3 partitions in the full-disk image:

    Partition number

    Partition image file

    1

    fip.bin

    2

    ubuntu-boot.img

    3

    writable.img

    Starting by creating a directory tree as the following:

    WICTEST/
    ├── disk.wks
    └── imgs
        ├── fip.bin
        ├── ubuntu-boot.img
        └── writable.img
    

    Note

    wic tool only accepts raw image format. It does not take Android sparse image as input.

    The content of the kikstart file disk.wks should be the following:

    bootloader --ptable gpt --timeout=0
    part --source rawcopy --sourceparams="file=fip.bin" --part-name bootloaders --align 512 --fixed-size 4M
    part --source rawcopy --sourceparams="file=ubuntu-boot.img" --part-name kernel --size 20M
    part / --source rawcopy --sourceparams="file=writable.img" --part-name rootfs --part-type B921B045-1DF0-41C3-AF44-4C6F280D3FAE --active
    
  4. Execute the wic tool to generate full-disk image:

    $ source src/poky/oe-init-build-env
    $ wic create <WICTEST>/disk.wks -o <WICTEST>/out -r <WICTEST>/imgs -b <WICTEST>/imgs -k <WICTEST>/imgs -n <YOCTO_PROJ>/build/tmp/work/armv8a-poky-linux/wic-tools/1.0-r0/recipe-sysroot-native"
    

    where <WICTEST> is the path to the WICTEST directory you’ve created in step 3, and <YOCTO_PROJ> is the path to the directory you’ve used to build wic-tools in step 2.

    If the raw full-disk image is created successfully, the following logs should appear:

    In the example above, the resulting raw full-disk image file name is disk-202304191121-sda.direct. The exact file name may change depending on the exact build date/time and configuration.

  5. Convert raw image to sparse image. Although the raw image is ready to be written to the disk using tools like dd, we must convert the raw image into Android sparse images in order to flash the stoarge with genio-flash tool.

    $ truncate -s%4096 <WICTEST>/out/disk-202304191121-sda.direct
    $ export TOOLROOT=<YOCTO_PROJ>/build/tmp/work/armv8a-poky-linux/wic-tools/1.0-r0/recipe-sysroot-native
    $ export PATH=$PATH:$TOOLROOT/usr/bin:$TOOLROOT/usr/sbin
    $ img2simg -b 4096 -D 00000000 -o <WICTEST>/out/disk.img <WICTEST>/out/disk-202304191121-sda.direct"
    
  6. Replace the resulting full-disk image file disk.img into the Ubuntu image directory, and use the following commands:

    $ genio-flash mmc0:disk.img
    

    This would flash the entire mmc0 user partition with the full-disk image you’ve supplied.