concatenate files with dd seek=$offset from xml and then sparse with img2simg
rawprogram0.xml
contains
- partition name: filename="system.img"
- partition size: num_partition_sectors="8388608"
- partition offset: start_sector="1312768"
rawprogram_unsparse.xml
contains system_1.img - system_53.img
- file name: filename="system_1.img"
- file size: num_partition_sectors="262160"
- file offset: start_sector="1312768"
Note: we don't want the offset so we will subtract from start_sector
1312768 - 1312768 = 0
- file name: filename="system_1.img"
- file size: num_partition_sectors="262160"
- file offset: start_sector="0"
1576968 - 1312768 = 264200
- file name: filename="system_2.img"
- file size: num_partition_sectors="16"
- file offset: start_sector="264200"
1581024 - 1312768 = 268256
- file name: filename="system_3.img"
- file size: num_partition_sectors="256048"
- file offset: start_sector="268256"
Now use the dd seek
parameter to paste junks into proper offsets
(sparse is filled with zeros)
bs=$SECTOR_SIZE_IN_BYTES
seek=$start_sector
count=$num_partition_sectors
dd if=system_1.img count=262160 seek=0 bs=512 of=system_ext4.img
dd if=system_2.img count=16 seek=264200 bs=512 of=system_ext4.img
dd if=system_3.img count=256048 seek=268256 bs=512 of=system_ext4.img
...
dd if=/dev/zero count=0 seek=8388608 bs=512 of=system_ext4.img
the result is mountable ext4 partition image
mkdir system
sudo mount -t ext4 -o loop system_ext4.img system
ls system
finally this file can be sparsed with img2simg
sudo apt install -y f2fs-tools android-tools-fsutils android-sdk-platform-tools-common
img2simg system_ext4.img system.img
GNU bash script with sed
#/bin/bash
shopt -s extglob
bs=512
label=system
input=rawprogram0.xml
output=rawprogram_unsparse.xml
source <(sed -nr "s,.\s(filename=.${label}.img.)\s.\s(num_partition_sectors=.[0-9]+.)\s.\s(start_sector=.[0-9]+.).,\1; \2; \3;,p" "$input" | head -n1)
out=$filename
off=${start_sector:-0}
end=${num_partition_sectors:-0}
printf '%s\n' "${label}"+([0-9]).img | cut -d. -f1 | sort -t -k2n | xargs -n1 -I_ echo _.img |
while read -r file
do
source <(sed -nr "s,.\s(filename=.${file}.)\s.\s(num_partition_sectors=.[0-9]+.)\s.\s(start_sector=.[0-9]+.).,\1; \2; \3;,p" "$output" | head -n1)
dd if="$filename" of="$out" bs=${bs:-512} count=${num_partition_sectors:-0} seek=$((start_sector-off)) status=none || exit 1
echo "filename=$filename num_partition_sectors=$num_partition_sectors start_sector=$((start_sector-off))"
done
dd if=/dev/zero of="$out" bs=${bs:-512} count=0 seek=$end status=none || exit 1
echo "filename=$out num_partition_sectors=$end start_sector=$off"
file "$out"
e2fsck -n "$out" | grep clean || exit 1
mv "$out" "${out%.}.raw"
img2simg "${out%.}.raw" "$out" || exit 1
file "$out"
echo "Done."
exit 0