For those with an A/B device, it can be frustrating to wait for GSI maintainers to build A/B variants. Don't worry, it's not too complicated to port A-only system images to A/B.
The difference that matters is that on A-only images, everything in / such as init.rc is in the ramdisk, which is in the boot partition. On A/B devices, the ramdisk is used for recovery instead, so all those files go on the system partition. This partition is actually mounted at / instead of /system. It functions as both the ramdisk and the system partition. This can actually lead to faster boots.
A/B devices also have a different Chrome OS derived updater that supports seamless OTAs to the other slot, but we won't worry about that.
First of all, you will need Linux. This is because Windows just can't handle the extra data we need to preserve, such as POSIX permissions and SELinux contexts.
You are expected to have experience with command-line tools. This is NOT for newbies. You may need to compile a tool.
Steps:
If you encounter any errors, the resulting image will most likely not work.
If you have a device with a small system partition that cannot fit the original A-only image you are trying to convert, it will be necessary to create a new, smaller image for the purpose. To create that new image, follow these steps after the ones above:
If there's enough demand, I might make a tool to automate this. Let me know what you think.
The difference that matters is that on A-only images, everything in / such as init.rc is in the ramdisk, which is in the boot partition. On A/B devices, the ramdisk is used for recovery instead, so all those files go on the system partition. This partition is actually mounted at / instead of /system. It functions as both the ramdisk and the system partition. This can actually lead to faster boots.
A/B devices also have a different Chrome OS derived updater that supports seamless OTAs to the other slot, but we won't worry about that.
First of all, you will need Linux. This is because Windows just can't handle the extra data we need to preserve, such as POSIX permissions and SELinux contexts.
You are expected to have experience with command-line tools. This is NOT for newbies. You may need to compile a tool.
Steps:
- Download an A/B GSI with the same Android version. We will use this image for the root files. (I was able to use an 8.1 base for a 9.0 system with some patches, but YMMV)
- Use the simg2img tool to convert the sparse A/B image to a raw one: simg2img system_arm64_ab.img base_ab_raw.img
- Use the same tool to convert the A-only image to raw: simg2img system_arm64_a.img system_a_raw.img
- Enter a root shell. This is to avoid any problems with permissions. sudo -s
- Create the directories to mount the images on: mkdir /mnt/ab; mkdir /mnt/a
- Mount the A/B image with flags rw,noatime: mount -o rw,noatime base_ab_raw.img /mnt/ab
- Mount the A-only with flags rw,noatime: mount -o rw,noatime system_a_raw.img /mnt/a
- Create a system folder in the A-only image: mkdir /mnt/a/system
- Set the SELinux context for the system folder: setfattr -n security.selinux -v u
bject_r:system_file:s0 /mnt/a/system
- Set permissions for the system folder just in case: chmod 755 /mnt/a/system
- Delete the system folder in the A/B image: rm -fr /mnt/ab/system
- Copy all the root files from A/B to the A-only image. These exact arguments are important to preserve everything. cp -Raf /mnt/ab/* /mnt/a/
- Unmount the A/B image: umount /mnt/ab
- Unmount the newly transformed A/B image: umount /mnt/a
- Convert the new A/B image to sparse format with img2simg: img2simg system_a_raw.img system_arm64_ab_new.img
- Flash and enjoy!
If you encounter any errors, the resulting image will most likely not work.
If you have a device with a small system partition that cannot fit the original A-only image you are trying to convert, it will be necessary to create a new, smaller image for the purpose. To create that new image, follow these steps after the ones above:
- Create the new raw sparse image: fallocate -l 2G system_ab_raw_small.img
- Create an ext4 filesystem on the new image: mkfs.ext4 system_ab_raw_small.img
- Mount the new image: mount -o rw,noatime system_ab_raw_small.img /mnt/ab
- Mount the old converted A/B image: mount -o ro system_a_raw.img /mnt/a
- Copy all the files: cp -Raf /mnt/a/* /mnt/ab/
- Unmount the new image: umount /mnt/ab
- Unmount the old image: umount /mnt/a
- Convert the new image to sparse: img2simg system_ab_raw_small.img system_arm64_ab_new_small.img
- Flash and enjoy!
If there's enough demand, I might make a tool to automate this. Let me know what you think.
Last edited: