# 1) If input is .gz, decompress to tmp if [[ "$IN" =~ \.gz$ ]]; then echo"Decompressing $IN ..." gunzip -c "$IN" > "$TMPDIR/firm.img" SRC="$TMPDIR/firm.img" else SRC="$IN" fi
# 2) Create or truncate output to requested SIZE (sparse via truncate) echo"Creating output image $OUT of size $SIZE ..." truncate -s "$SIZE""$OUT"
# 3) Write firmware into head of OUT without truncating (notrunc) echo"Writing firmware into head of $OUT (notrunc) ..." ddif="$SRC" of="$OUT" bs=1M conv=fsync,notrunc status=progress
# 4) Ensure parted can see full size echo"Verifying output image size..." parted -s "$OUT" unit s print > "$TMPDIR/parted_before.txt" 2>/dev/null || true
# 5) Read original partition 2 start sector from the written image (use parted on temporary loop) # Use losetup to map image to loop so parted prints reliably LOOP=$(losetup --show -fP "$OUT") echo"Loop device: $LOOP" # Wait tiny bit sleep 0.2
# get partition start for partition 2 (in sectors) # parted prints lines like: " 2 66560s 680959s 614400s 300M 83 Linux" START_SECTOR=$(parted -s "$LOOP" unit s print | awk '/^ 2/ {gsub("s","",$2); print $2; exit}') if [ -z "$START_SECTOR" ]; then # fallback: parse sfdisk START_SECTOR=$(sfdisk -d "$LOOP" | awk -F'=''/start=/ {print $2; exit}' | awk -F',''{print $1}') fi
if [ -z "$START_SECTOR" ]; then losetup -d "$LOOP" echo"Failed to determine partition 2 start sector." exit 4 fi
# 6) Unmap loop before using parted to rewrite partition table on file losetup -d "$LOOP" sleep 0.2
# 7) Non-interactively recreate partition 2 with same start and end=100% # We'll use parted in script mode: remove partition 2, then mkpart with start in sectors and end 100%. echo"Rewriting partition 2 to start at ${START_SECTOR}s and end at 100%..." parted -s "$OUT"rm 2 # create new primary partition #2 using sector units parted -s "$OUT" unit s mkpart primary "${START_SECTOR}s" 100%
# 8) Keep the original partition type/boot flag for partition1 if needed (try to preserve FAT/boot) # If partition 1 had boot flag, ensure it remains # preserve boot flag of partition1 if it existed BOOT_FLAG=$(parted -s "$SRC"print | awk '/^ 1/ && /boot/ {print "on"; exit}') if [ -n "$BOOT_FLAG" ]; then parted -s "$OUT"set 1 boot on || true fi
# 9) sync to disk sync
# 10) Show final partition layout echo"Final partition table of $OUT:" parted -s "$OUT" unit s print
echo"Done. You can now write $OUT to a disk (dd or qm importdisk) and OpenWrt should auto-create an overlay on first boot."
Creating output image immortalwrt-24.10.4-x86-64-8g.img of size 8G ... Writing firmware into head of immortalwrt-24.10.4-x86-64-8g.img (notrunc) ... 332+1 records in 332+1 records out 348651520 bytes (349 MB, 332 MiB) copied, 0.375172 s, 929 MB/s Verifying output image size... Loop device: /dev/loop1 Detected partition 2 start sector: 66560 Rewriting partition 2 to start at 66560s and end at 100%... Warning: The resulting partition is not properly aligned for best performance: 66560s % 2048s != 0s Final partition table of immortalwrt-24.10.4-x86-64-8g.img: Model: (file) Disk /root/immortalwrt-24.10.4-x86-64-8g.img: 16777216s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags:
Number Start End Size Type File system Flags 1 512s 66047s 65536s primary ext2 boot 2 66560s 16777215s 16710656s primary
Done. You can now write immortalwrt-24.10.4-x86-64-8g.img to a disk (dd or qm importdisk) and OpenWrt should auto-create an overlay on first boot.
3. 关于对齐警告
输出中出现的警告:
1
Warning: The resulting partition is not properly aligned for best performance: 66560s % 2048s != 0s