Long-time UNIX guy here, but relatively new to the world of Android. Read on.
EPISODE 1: A New Backup (I hoped)
I have recently purchased an Asus MemoPAD (ME103K) ; I then became root, and took a
dd image of the read-only
system partition to the external SD card:
$ su # dd if=/dev/block/platform/msm_sdcc.1/by-name/system \ of=/storage/MicroSD/system.img bs=1M # ls -l /storage/MicroSD/system.img -rw-r--r-- 1 root root 2147483648 Sep 27 13:15 system.img
The size (exactly 2GiB) was a bit suspicious - could it be that this was because of the FAT32 partition on the SD card?
No, it was not -
tune2fs -l revealed that this was indeed, a valid EXT4 image, exactly sized at 2GiB, which passed
fsck -f with no errors at all.
fastboot (from the linux machine attached to the tablet) concurred, after an
adb reboot bootloader:
linuxbox# fastboot getvar all (bootloader) version-bootloader: 3.03 (bootloader) version-hardware: rev_c (bootloader) variant: LEOPARDCAT 16G (bootloader) version-baseband: H00_0.16.F_0521 (bootloader) serialno: 0a3dXXXX ... (bootloader) partition-type:system: ext4 (bootloader) partition-size:system: 0x0000000080000000
That size, is indeed 2GB:
linuxbox# python2 -c 'print 0x0000000080000000' 2147483648
So, all is good - I have a backup of the image. Now to test restoring it.
I try to flash the system.img back to the tablet - to make sure I can recover from anything, the sort of bullet-proof backup we do in the Unix world (e.g. restore contents of a drive via
dd if=backup.image of=/dev/sdXXX).
Everything related to
fastboot work flawlessly - so I try...
linux_box# fastboot devices 0a3dXXXX fastboot linux_box# mount /dev/sdcard /mnt/sdcard linux_box# cp /mnt/sdcard/system.img . linux_box# fastboot flash system system.img error: cannot load 'system.img'
Hmm. I download and build the
android-tools-5.1.1 of my distribution from sources, adding debug information - and step in the debugger, to see this failure:
linuxbox# gdb --args fastboot flash system system.img ...
Interesting - even though I am in a 64bit machine, apparently there are issues that turn the file size "negative" (in a 32bit world, the file size of my image, 2^31, is indeed considered negative - to be exact,
OK, fine - how do they flash large image files in Android?
Googling, searching - turns out they use this
make_ext4fs tool, that creates flashable images. In fact it is part of what I just compiled, so I might as well use it:
linuxbox# mkdir /system linuxbox# mount -o loop,ro system.img /system linuxbox# ls -l /system total 208 drwxr-xr-x 106 root root 8192 Sep 17 22:24 app drwxr-xr-x 3 root 2000 8192 Sep 26 21:08 bin -rw-r--r-- 1 root root 6847 Sep 12 16:59 build.prop drwxr-xr-x 19 root root 4096 Sep 26 21:08 etc drwxr-xr-x 2 root root 4096 Aug 11 22:27 fonts drwxr-xr-x 4 root root 4096 Sep 12 16:56 framework drwxr-xr-x 10 root root 16384 Sep 12 16:59 lib drwxr-xr-x 2 root root 4096 Jan 1 1970 lost+found drwxr-xr-x 3 root root 4096 Aug 11 22:18 media drwxr-xr-x 59 root root 4096 Aug 11 22:29 priv-app -rw-r--r-- 1 root root 126951 Aug 1 2008 recovery-from-boot.p drwxr-xr-x 3 root root 4096 Aug 11 21:02 scripts drwxr-xr-x 3 root root 4096 Aug 11 21:02 tts drwxr-xr-x 11 root root 4096 Sep 26 21:08 usr drwxr-xr-x 8 root 2000 4096 Aug 11 22:29 vendor drwxr-xr-x 2 root 2000 4096 Sep 26 21:09 xbin linuxbox# ../extras/source/extras/ext4_utils/make_ext4fs \ -l 2048M new_system.img /system Creating filesystem with parameters: Size: 2147483648 Block size: 4096 Blocks per group: 32768 Inodes per group: 8192 Inode size: 256 Journal blocks: 8192 Label: Blocks: 524288 Block groups: 16 Reserved block group size: 127 Created filesystem with 2666/131072 inodes and 375014/524288 blocks
Cool - so I can apparently build system images from plain old folders. The sky will be my limit - I'll be able to add anything I want to this image.
Let's burn it...
linuxbox# fastboot flash system new_system.img erasing 'system'... OKAY [ 0.064s] sending 'system' (2088960 KB)... ^C
I waited for 1h before hitting that Ctrl-C. And had to power-cycle the tablet, which booted back in fastboot mode.
This is not looking good.
What if I build a smaller image? Maybe the 2GB are somehow an issue, and this partition is not used to full capacity - it has free space:
linuxbox# ../extras/source/extras/ext4_utils/make_ext4fs \ -l 1536M new_system.img /system linuxbox# ./fastboot flash system system.img erasing 'system'... OKAY [ 0.065s] sending 'system' (1572864 KB)... OKAY [ 51.039s] writing 'system'... OKAY [235.080s] finished. total time: 286.183s
OK, this looks very promising (and only took 5 min). I guess I can now reboot back and everything should be normal, yes?
I don't mind a temporarily bricked device, as long as I do get to control it in the end (machines that I am not a master of, are machines I don't care to operate ;-)
Any ideas on what I did wrong and what I can do to fix this?
Thanks in advance.
P.S. I checked the Asus support page for my tablet - they only provide the sources for the kernel, and the Over-the-air .zip file. That in turn contains a file-system level backup from the root - i.e. the
system folder exists in there as just a folder, not an image, not a
system.img that I can flash - so that doesn't really help me.
EPISODE 2: Attack of the Custom Boots
In the absense of any sort of
recovery.img from Asus (why would a manufacturer bother to publish a fastboot-flashable
recovery.img? Why indeed...) and a similar absence on recovery images from the CWM and TWRP sites... I am left to battle all alone.
Thankfully, the Over-the-air update file from Asus includes inside it...
linuxbox# unzip -l /opt/Asus/firmware/UL-K01E-WW-220.127.116.11-user.zip |\ grep boot.img$ 7368704 2011-03-22 11:21 boot.img
...my tablet's boot image. Now maybe - just maybe - I can do something with this.
linuxbox$ mkdir rootfs linuxbox$ cd rootfs linuxbox$ abootimg -x /path/to/boot.img linuxbox$ ls -l bootimg.cfg initrd.img zImage
Expanding the ramdisk...
linuxbox$ mkdir initrd linuxbox$ cd initrd linuxbox$ gzip -cd ../initrd.img | cpio -ivd ... linuxbox$ vi default.prop
I set up
default.prop to be root when the kernel boots:
ro.secure=0 ro.debuggable=1 ro.adb.secure=0 androidboot.selinux=disabled
I also copied
/system/bin/sh (from the over-the-air Asus .zip file) into
/sbin/sh. I did the same with busybox - quite handy tool.
And repacked the boot.img...
busybox$ find . | cpio --create --format='newc' | gzip -9 > ../initrd.custom.gz busybox$ cd .. busybox$ abootimg --create ../new_boot_busybox.img \ -f bootimg.cfg -k zImage -r initrd.custom.gz
abootimg actually failed the first time I run this, since
bootimg.cfg had to be updated - the
bootsize parameter had to be changed, since the package is bigger now.
abootimg reports what it needs, so that's easy enough.
And now, I boot my custom image...
linuxbox# fastboot boot new_boot_busybox.img
...and witness the following...
linuxbox# adb logcat - exec '/system/bin/sh' failed: Permission denied (13) - linuxbox# adb shell - exec '/system/bin/sh' failed: Permission denied (13) -
Hmm... Maybe adbd is not run as root?
linuxbox# adb root restarting adbd as root linuxbox# adb shell - exec '/system/bin/sh' failed: Permission denied (13) -
Fine... I hexedit adbd, and patch /system/bin/sh to be /sbin/sh (I copied the /system/bin/sh from the OTA image to the rootfs of the initrd): Reboot, fastboot...
linuxbox# adb shell - exec '/sbin/sh' failed: Permission denied (13) -
Darn. Is this thing able to do anything?
linuxbox# adb pull /proc/partitions 15 KB/s (1272 bytes in 0.079s)
It is... let's see:
linuxbox# adb pull /proc/mounts 16 KB/s (1358 bytes in 0.079s) linuxbox# grep system mounts /dev/block/platform/msm_sdcc.1/by-name/system /system ext4 rw,seclabel,relatime,data=ordered 0 0
OK, so /system is mounted. Can I see what's inside?
linuxbox# adb pull /system remote object '/system' does not exist
What the... Maybe I can check what /proc/kmsg contains (what "dmesg" would output)
linuxbox# adb pull /proc/kmsg failed to copy '/proc/kmsg' to './kmsg': Operation not permitted
Nah, I need to be root to do that.
linuxbox# adb push /sbin/sh /system/bin/sh failed to copy '/sbin/sh' to '/system/bin/sh': Permission denied
And that, too.
This is turning out to be quite a puzzle...