Saturday, February 25, 2017

Salvaging a Lost Soul: Recovering a Mlais MX28 after Factory Reset

As my Mlais MX28 has been serving me faithfully for nearly 3 years (with no cleanup managers, factory resets or anything of the sort), I thought it's time to give it a bit of cleansing (a factory reset). Turns out I should have been in too much of a haste (or call it overconfidence, of you prefer), and I didn't even Google the possible risks of a factory reset before hitting the Erase Phone button.

All went well, except that the phone refused to boot beyond the Mlais logo after restart. After about 10 minutes of waiting I became nervous enough to fire up an adb logcat to see what was going on. Things had become quite "loopy", with the same set of (mostly error) logs repeating over and over again.

Looking at an excerpt of the logs, it became clear that all the errors were based on a missing /data directory: a missing /data/nvram here, a missing /data/data there, and so on. After a bit of log analysis I came up with the following script for creating a minimal directory hierarchy for getting things past the bootloop:

adb wait-for-device && adb shell "mount -o rw,remount /; mkdir -p /data/misc/keystore; mkdir -p /data/misc/mblog; mkdir -p /data/anr; mkdir -p /data/aee_exp; mkdir -p /data/agps_supl; mkdir /data/app-lib; mkdir /data/dalvik-cache; mkdir /data/mdl; mkdir -p /data/media/obb; mkdir /data/misc/bluetooth; mkdir /data/misc/wifi; mkdir /data/data"

After the phone booted, I was greeted with a fully Chinese home screen, and the "factory defaults" for a Chinese phone if there was any: everything in Chinese, and nothing working quite the way it should:

  • Both SIMs were displaying "invalid IMEI" errors, and only SIM1 was actively in service.
  • SMSs were being received but getting rejected with an "insufficient memory" error.
  • No apps could be installed, due to the same "insufficient memory" error.
  • Bluetooth, WiFi, GPS, USB tethering all were busted.
  • Though you could change system settings, everything would get reset to the miserable "factory default" state after a restart.

After a while I managed to obtain internet connectivity by manually creating an APN profile for the active SIM. But there was no way to share the connection with my PC (as neither hotspots nor tethering were working). As I did not have any other source of internet access, I had to resort to the painful procedure of searching everything on my phone and trying them out on itself, via USB over an ADB session from my PC.

Unfortunately I happened to start my inquiry from the wrong end: invalid IMEI. The articles I came across put the blame on a corrupted NVRAM; some even claimed that there was no other solution than flashing a new NVRAM file, if your phone is MTK-based (which happened to be, in my case). As I didn't have access to a native Windows system, and almost all flashing tools are made for Windows, I thought I was out of options.

Luckily I came across this post that explains how to modify iptables rules for sharing internet connectivity (though not for Android). After a bit of customization I came up with the following script which, when run after enabling USB tethering on the phone, gave my PC internet access:

# I gave my laptop the IP 192.168.42.150 on the tether network
sudo ifconfig enp0s20f0u4 192.168.42.150
# my phone got the IP 192.168.42.129 when tethered
sudo route add default gw 192.168.42.129
adb shell iptables -F
adb shell iptables -t nat -F
adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward"
adb shell iptables -t nat -A POSTROUTING -o ccmni0 -j MASQUERADE
adb shell iptables -A FORWARD -i ccmni0 -o rndis0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
adb shell iptables -A FORWARD -i rndis0 -o ccmni0 -j ACCEPT
echo "nameserver 127.0.1.1" | sudo tee /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf

After this lifesaving discovery I started searching more openly, and went through several articles on the Android startup process to find any clue of the NVRAM (and general Android) initialization process. Though instructive, none of them could help me. Luckily, the "insufficient memory" errors and the initial missing-path errors involving /data led me to check why the partition was not getting mounted.

With help from this post I learned that my /data partition device was /dev/block/mmcblk0p7:

root@Mlais:/ # ls -l
...
lrwxrwxrwx root     root              1970-01-01 05:30 emmc@usrdata -> /dev/block/mmcblk0p7
...

And when I tried to scan and repair the partition, I got the following error, even with the -b option:

The superblock could not be read or does not describe a correct ext2
filesystem.  If the device is valid and it really contains an ext2
filesystem (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
    e2fsck -b 8193 

As suggested by a quick search, I then tried a mke2fs /dev/block/mmcblk0p7 to recreate the partition, and that finally did it!

Now my dear old MX28 is back in pristine condition, thanks to the robustness of the Linux core that powers it all along!

No comments: