17

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. And 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 adb and 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
...

Failure due to negative size!

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, -2147483648.

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?

No :-)

enter image description here

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-12.16.1.12-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...

4
  • 2
    The only good thing that you did not do here (and should've done) is to flash a custom Recovery and then take a nandroid backup of the partitions from it. That's one of the bulletproof methods out there to recover devices from such bricked state. That Over-the-air.zip (OTA zip) is a recovery flashable zip i.e to be flashed when booted into Recovery and they follow a different packaging format but achieves the same goal. Long story short, flash a custom Recovery (or boot into stock one), flash stock ROM and then experiment as much as you want.
    – Firelord
    Commented Sep 27, 2015 at 13:46
  • 1
    @Firelord: That's the thing - even though fastboot is still operational (responds to requests just fine) and I can therefore burn any recovery image, (a) I searched and found no CWM or TWRP recovery image for ME103K - I don't suppose there's a "generic" one that you are referring to, is there? (b) Powering off, pressing power button + volume down does not bring up the recovery image - I still just get to fastboot state. Mo idea why. In fact I have never seen the recovery process (kinda curious to see it)...
    – ttsiodras
    Commented Sep 27, 2015 at 13:56
  • 1
    Try other button combinations such as Power+Vol Up+Vol Down to boot into Recovery mode. If you've access to stock Recovery ZIP, then there may be the image file of stock Recovery somewhere which you can flash from fastboot or directly boot into it (fastboot boot <FILE>.img), then flash the whole stock ZIP file. Alternatively, see if there exists (on web) the stock ROM files which can be flashed using fastboot.
    – Firelord
    Commented Sep 27, 2015 at 14:00
  • 1
    @Firelord: No, Asus doesn't provide a recovery.zip. From the OTA file, there's nothing .img-y ( unzip -l UL-K01E-WW-12.16.1.12-user.zip | grep recovery shows only a couple of shell scripts - I'll have a look, but there's definitely no recovery.img there). Googling didn't help either - there are no recovery images of this tablet anywhere... Guess I'll have to wait for some kind soul to dd their recovery partition and share?
    – ttsiodras
    Commented Sep 27, 2015 at 14:09

3 Answers 3

8

Episode 3: Return of the Shell.

If I ever had any chance of solving this, I first had to figure out why the shell wasn't working. adbd itself was responding, so it was started on the tablet side - but it could not execute the shell, even when I hack-patched it to invoke a file (/sbin/sh) that I myself placed in the boot image - being 100% sure that it had the proper permissions and was accessible from the shell (id=2000) account that adbd uses.

Which left only one explanation - SELinux "cages".

So I checked how adbd was started from my boot image's init.rc:

# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
    class core
    socket adbd stream 660 system system
    disabled
    seclabel u:r:adbd:s0

...and tried an obvious change:

service adbd /sbin/adbd
    class core
    socket adbd stream 660 system system

I re-packed, and to my intense satisfaction, saw ...

linuxbox# adb shell
$ 

I finally got access to the tablet - from "inside".

Checking the mounted /system, it became clear that the flashing process - even though fastboot flash system ... reported that all was Ok - had failed spectacularly. It was a wonder that the partition was mounted in the first place.

That explained why the tablet was not booting, and gave me the final idea that solved the issue.

I needed to boot the tablet so that it used my pristine copy of the /system partition, but at this point, even though I had shell access, I was not root - (the changes I did in default.prop are apparently ignored by the Asus kernel - I'll have to recompile it soon...) so I could not mount the external sdcard and dd over my good copy.

But I did have my own boot image - which meant I could edit the /fstab.qcom inside it, and do this:

Original line that told the tablet how to mount /system

/dev/block/platform/msm_sdcc.1/by-name/system  /system  ext4 ro,barrier=1 wait

My edit

/dev/block/mmcblk1p2  /system ext4  rw,barrier=1 wait

...and back in my linux box, I dd-ed the pristine backup of the tablet's system partition to my external SD card's 2nd partition - which I created via gparted to be exactly 2GB.

That did it - the tablet booted from my external SD card.

EDIT: The journey continued - I eventually patched and compiled my own kernel and became root.

2
  • 2
    I swear to Episode 4, I would've offered a bounty if this answer wasn't posted, for the sake of fun from all these episodes. It's good to see you solved your problem on your own. :D
    – Firelord
    Commented Sep 30, 2015 at 12:28
  • 2
    @Firelord: Thanks, mate. In the process, I think I did something rather cool - I booted my tablet without touching it's insides ... the boot image comes from the outside (over fastboot boot ...) and the /system partition is on the SD card, tweakable to whatever I want. Sort of like, booting a PC from a USB stick :-)
    – ttsiodras
    Commented Sep 30, 2015 at 12:45
4

It seems you've already found some kind of solution to your problem (there's a lot of text to read on this page), but it seems this probably could have been resolved much more simply.

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

Among these variables, did your tablet return a max-download-size variable? If so, that might have provided a warning, outright, that the flashing process might have some issues with such a large image. The current fastboot code is made to work around a max-download-size that is too small, but I've experienced your same error even when the image is smaller than what the device says it can handle, so actually the point is kind of moot, I guess.

linux_box# fastboot flash system system.img  
error: cannot load 'system.img'

So, anyway, it seems here, that for whatever reason, you are unable to flash. If you and I are right, and it's about size (your tablet does only have 1 GB of RAM, and supposedly most devices try to read the whole image into RAM before flashing), this is where I think the mere adjustment of adding the -S option to fastboot might have fixed your flash as it has for me:

fastboot -S 512M flash system system.img  

Instead, however, it seems you tried to force your 2 GB image into a size that (1) might not be possible for it to be stuffed into and (2) is not the size that your device's system partition is supposed to be.

  • Regarding point #1, in my experience, I would not count on the brittle Android build tools to complain if you ask them to do something they will fail at, and it's possible that they might have here.

  • Regarding point #2, I don't believe you can't just do that; additional steps would be required to use a different system partition size.

Assuming your tablet expects sparse image files, I believe the command you wanted to try instead of make_ext4fs -l 1536M new_system.img /system was make_ext4fs -l 2048M -s new_system.img /system. The adjusted command would make an image that inflates to the correct size, but is stored temporarily stripped of any excess fat like big pockets of empty data: a "sparse image file" (see the page I linked to earlier for more info on them; I don't have enough reputation on this site to repeat the link).

This old readme someone wrote for a collection of the tools should help understand how the process goes.

Cheers.

3
  • 1
    Thanks for answering. As to your questions, (1) no, there was no max-download- anything in the output from getvar. (2) I will keep in mind the -S option in my future flashings - as it is, once I booted, I became root (via recompiling my kernel) and dd-ed over the old system partition, so whether flashing with -S would work will have to wait for my next tests (3) I did try with sparse images, got the same result (i.e. fastboot reported that flashing was OK, but the system partition was messed up).
    – ttsiodras
    Commented Oct 9, 2015 at 10:34
  • 1
    @ttsiodras No problem. I learned some things in the process. (1) Ah, okay. I doubted that it did, as at least on my device using the build of fastboot I have installed, that variable is printed first in the list (thanks, btw, for demonstrating that all can be passed to getvar-- that's helpful). (2) Ohh, okay. If it does work, let us know. (3) Whoops! I didn't notice that. It's a lot of text, sorry. Was that mentioned in your posts? (Was it like the make_ext4fs command I suggested, with -s and the full 2 GiB length specified?) Maybe the tablet doesn't deal with sparse files.
    – naki
    Commented Oct 10, 2015 at 4:05
  • 1
    (3) yep, I passed -s to make_ext4fs - fastboot reported 'OK' for burning, but /system was messed up. My theory is that, as you said, anything larger than the memory of the tablet (1GB) would not work, and needed the -S option in fastboot to properly work (which explains the half-broken state - the partition was mounted because the first part of the image fit in memory and was actually burned, allowing it to be mounted - but files inside it were... randomly corrupted, depending on whether their sectors were burned or not).
    – ttsiodras
    Commented Oct 10, 2015 at 15:57
2

With my Moto G I created a back up using dd like you did. I needed to restore my system partition the other day, so I booted TWRP (I didn't flash it, I just booted the image to RAM). I then used adb to connect while TWRP was running and I just pushed the img I made with dd to my SD card and then used dd to write the image to the system partition.

Check out the videos I've made about this here: https://youtu.be/BHCamV-sHx0?list=PLcUid3OP_4OVI1Rtuwxk1RjABh1PxXXQq

1
  • Unfortunately that doesn't help me - I can't get to my tablet's recovery no matter what combination of keys I tried (in contrast, I got it immediately on my MotoG2 - so this tablet's recovery is hosed somehow). I can flash the recovery partition (since flashboot is operational) but I have no recovery.img from Asus, and no CWM or TWRP exists (for an ME103K) either.
    – ttsiodras
    Commented Sep 28, 2015 at 16:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .