From f230f1c0128166fc478eff8215da1a1f31498db9 Mon Sep 17 00:00:00 2001 From: harrytuttle Date: Mon, 25 Dec 2017 10:26:46 +0100 Subject: [PATCH 1/5] Pad runtime to multiple of 512 bytes If the squashfs filesystem starts at a multiple of 512bytes offset it is possible to replace the runtime (using fdisk) or possibly inject it (using dd) with a dos partition table at offset 446, similarly to how the 3 AppImage magic bytes are inserted at offset 8 (the partition table is only 64bytes long, and not all of those are actually needed) This way the appimage can be mounted by existing tools like gnome-disk-image-mounter which reads from the partition table the offset of the filesystem --- src/build-runtime.sh.in | 3 +++ src/runtime.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/build-runtime.sh.in b/src/build-runtime.sh.in index 8455f6683..9238a2f69 100755 --- a/src/build-runtime.sh.in +++ b/src/build-runtime.sh.in @@ -72,6 +72,9 @@ printf '\x41\x49\x02' | dd of=runtime bs=1 seek=8 count=3 conv=notrunc # Convert runtime into a data object that can be embedded into appimagetool ld -r -b binary -o data.o runtime +# Pad runtime to multiple of 512bytes +dd if=/dev/null of=runtime bs=1 count=1 seek=$(./runtime --appimage-offset) + # Show header for debugging purposes xxd runtime | head -n 1 diff --git a/src/runtime.c b/src/runtime.c index e3c69c138..99052fa83 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -289,7 +289,9 @@ main (int argc, char *argv[]) sprintf(argv0_path, argv[0]); fs_offset = get_elf_size(appimage_path); - + /*It's better to keep filesystems aligned at 512bytes intervals, like sectors on a real partitioned disk*/ + fs_offset = ((fs_offset-1)|511)+1; + arg=getArg(argc,argv,'-'); /* Print the help and then exit */ From 766fbc6471b396e29a6ff9c93c0fd02fff88e0d8 Mon Sep 17 00:00:00 2001 From: harrytuttle Date: Mon, 25 Dec 2017 19:10:39 +0100 Subject: [PATCH 2/5] added minimal partition table to the runtime 2 magic bytes are inserted at offset 510 to make the appimage into in a dos disk image 4 bytes are then written in little endian byte order at offset 454 representing the offset of the first partition (in 512bytes sectors) A total of only 6 bytes (or less) are changed, and these are sufficient for gnome-disk-image-mounter to find the squashfs filesystem. The rest isn't important: chs address, flats, partition type, lba size in sectors, etc... can be ignored. In case these 6 bytes impact too much the elf structure on other architectures (particolarly on 32bit ones, where elf have different sizes for internal data structures) it could still be possibile to inject the 4 bytes at offset 470, 486 or 502 (for the second, third and fourth primary dos partitions): tools like gnome-disk-image-mounter will search all of those and mount only the valid filesystems they will find. Tested only on x86_64 for now. --- src/build-runtime.sh.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/build-runtime.sh.in b/src/build-runtime.sh.in index 9238a2f69..807b73a79 100755 --- a/src/build-runtime.sh.in +++ b/src/build-runtime.sh.in @@ -75,6 +75,12 @@ ld -r -b binary -o data.o runtime # Pad runtime to multiple of 512bytes dd if=/dev/null of=runtime bs=1 count=1 seek=$(./runtime --appimage-offset) +# Add boot signature to runtime, this way fdisk recognize the appimage as a partitioned disk image +printf '\x55\xaa' | dd of=runtime bs=1 seek=510 count=2 conv=notrunc + +# Add partition entry to runtime, this way gnome-disk-image-mounter can open it. +printf "0x%08x" $(( $(./runtime --appimage-offset) / 512 )) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc + # Show header for debugging purposes xxd runtime | head -n 1 From ec55f1d46ad000e5b0f3058d9fc7e4021abf9018 Mon Sep 17 00:00:00 2001 From: harrytuttle Date: Sun, 31 Dec 2017 02:17:19 +0100 Subject: [PATCH 3/5] try to fix build failure calculate only once ./runtime --appimage-offset and store it in $APPIMAGEOFFSET use that variable both to pad the runtime and to inject the first sector of the first partition --- src/build-runtime.sh.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/build-runtime.sh.in b/src/build-runtime.sh.in index 807b73a79..c26aedd18 100755 --- a/src/build-runtime.sh.in +++ b/src/build-runtime.sh.in @@ -66,6 +66,8 @@ HEXOFFSET=$(objdump -h runtime | grep .upd_info | awk '{print $6}') HEXLENGTH=$(objdump -h runtime | grep .upd_info | awk '{print $3}') dd bs=1 if=runtime skip=$(($(echo 0x$HEXOFFSET)+0)) count=$(($(echo 0x$HEXLENGTH)+0)) | xxd +APPIMAGEOFFSET=$(./runtime --appimage-offset) + # Insert AppImage magic bytes printf '\x41\x49\x02' | dd of=runtime bs=1 seek=8 count=3 conv=notrunc @@ -73,13 +75,13 @@ printf '\x41\x49\x02' | dd of=runtime bs=1 seek=8 count=3 conv=notrunc ld -r -b binary -o data.o runtime # Pad runtime to multiple of 512bytes -dd if=/dev/null of=runtime bs=1 count=1 seek=$(./runtime --appimage-offset) +dd if=/dev/null of=runtime bs=1 count=1 seek=$APPIMAGEOFFSET # Add boot signature to runtime, this way fdisk recognize the appimage as a partitioned disk image printf '\x55\xaa' | dd of=runtime bs=1 seek=510 count=2 conv=notrunc # Add partition entry to runtime, this way gnome-disk-image-mounter can open it. -printf "0x%08x" $(( $(./runtime --appimage-offset) / 512 )) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc +printf "0x%08x" $(echo $APPIMAGEOFFSET / 512 | bc) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc # Show header for debugging purposes xxd runtime | head -n 1 From 0e92d5f7a7e65ad34b9f0e7b5d0f171bd42988ea Mon Sep 17 00:00:00 2001 From: harrytuttle Date: Sun, 31 Dec 2017 02:19:47 +0100 Subject: [PATCH 4/5] moved the ld step after partition table injection otherwise the embedded runtime will lack the partition table. --- src/build-runtime.sh.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/build-runtime.sh.in b/src/build-runtime.sh.in index c26aedd18..7b7902c42 100755 --- a/src/build-runtime.sh.in +++ b/src/build-runtime.sh.in @@ -71,9 +71,6 @@ APPIMAGEOFFSET=$(./runtime --appimage-offset) # Insert AppImage magic bytes printf '\x41\x49\x02' | dd of=runtime bs=1 seek=8 count=3 conv=notrunc -# Convert runtime into a data object that can be embedded into appimagetool -ld -r -b binary -o data.o runtime - # Pad runtime to multiple of 512bytes dd if=/dev/null of=runtime bs=1 count=1 seek=$APPIMAGEOFFSET @@ -83,6 +80,9 @@ printf '\x55\xaa' | dd of=runtime bs=1 seek=510 count=2 conv=notrunc # Add partition entry to runtime, this way gnome-disk-image-mounter can open it. printf "0x%08x" $(echo $APPIMAGEOFFSET / 512 | bc) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc +# Convert runtime into a data object that can be embedded into appimagetool +ld -r -b binary -o data.o runtime + # Show header for debugging purposes xxd runtime | head -n 1 From 5da7b5ef3772b09d5f75859eee7c6b043045dccc Mon Sep 17 00:00:00 2001 From: harrytuttle Date: Sun, 31 Dec 2017 11:02:45 +0100 Subject: [PATCH 5/5] bc missing from ci builder, let's try again bash arithmetic expansion --- src/build-runtime.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-runtime.sh.in b/src/build-runtime.sh.in index 7b7902c42..bc7d9b4ce 100755 --- a/src/build-runtime.sh.in +++ b/src/build-runtime.sh.in @@ -78,7 +78,7 @@ dd if=/dev/null of=runtime bs=1 count=1 seek=$APPIMAGEOFFSET printf '\x55\xaa' | dd of=runtime bs=1 seek=510 count=2 conv=notrunc # Add partition entry to runtime, this way gnome-disk-image-mounter can open it. -printf "0x%08x" $(echo $APPIMAGEOFFSET / 512 | bc) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc +printf "0x%08x" $((APPIMAGEOFFSET / 512 )) | xxd -r | tac -rs. | dd of=runtime bs=1 seek=454 count=4 conv=notrunc # Convert runtime into a data object that can be embedded into appimagetool ld -r -b binary -o data.o runtime