Sunday, November 25, 2012

WDTV Live -- Firmware Hacking Series -- Part 1

I have had WDTV Live for many years now. As with most devices at my home, the first thing I try to do is to upgrade to an unofficial firmware that gives more features and freedom. I was running it on WDLXTV (the most popular unofficial firmware for WDTV) for quite some time.

I had scripts that run on startup to do various things including
  •     Installing ntfs, wifi (custom built for my usb wifi dongle) drivers
  •     Choosing the wired vs wifi networks based on its availability
  •     WPA2 supplicant initialization
  •     FTP based NAS share mounts

WDLXTV hadn't been updated for more than a year now and there have been recent official updates from WD (Western Digital). I needed the latest WDTV core software with new features/bug-fixes but would like to keep all the hooks and privileges I enjoy with the unofficial firmware.  So decided to build one myself based on the latest official firmware. That's where it started.


Firmware package layout

The firmware is packaged with at least two files in it. The normal process is to put these two files in the root folder of a pen drive and plug it in. The current firmware (after it boots) will prompt for an upgrade if the new firmware is really newer (new version > old version).

wdtvlive.ver -- txt file, with the version number of the firmware. This is what is used to decide whether an upgrade is available or not.

wdtvlive.bin -- the root filesystem of the linux. The filesystem is in cramfs format to save space. Any writeable portion in the / filesystem is mounted on tmpfs filesystem (which is RAM based, and is lost on reboot).

wdtvlive.fff -- Optional. Kernel upgrade. In most updates, we won't see this and is required only if the kernel needs an upgrade.


What it takes to customize

In most cases it is more than enough to customize the root filesystem and provide hooks. For eg., I have modified the firmware to execute the script /wdtv/gerald_init if it finds one, on the USB drive. I can pack any software on the USB drive and make it run automatically on startup just by changing scripts on the pen drive, without really having to repack firmware.


There are two problems to solve

  1. What is the customization required.
  2. How to take the changes into the WDTV firmware and persist it across reboots. ie., How to rebuild a firmware for upgrade.
Problem 1 is highly subjective and is a common problem and is not specific to WDTV. It is just that any new binary that you bring in, needs to built for MIPSel (the hardware architecture on WDTV). Toolchains are available from WD. I had built my own device driver earlier and it worked just fine.

Problem 2 is what I'm mainly going to talk about. There are multiple ways to accomplish this. The easier the approach, the riskier it is (naturally).

Modify firmware - the easier approach

wdtvlive.bin is the root filesystem for WDTV Live and contains the complete filesystem that is live, post boot. There are few things you need to be aware to do this:

1. wdtvlive.bin has a header and signature parts which are mainly used for error checks. So any change to the file will invalidate these. But they can be recomputed.
wdtvlive.bin : < 32 byte md5sum header >  < rootfs in cramfs format > < 16 byte signature >

2. You need a slightly modified version of cramfsck and mkcramfs to unpack/repack this cramfs image respectively. I had to download the open source cramfs package and make the changes. The main issue is with the block size being different on WDTV -- discovered by the author of WDLXTV. To know the exact changes required in cramfs for this block size change, look here

3. There is a /md5sum.txt file at the root. You need to make sure that you update the md5sum of any file that you add or modify into the package; if not the package is not going to load. I see these checks during the system boot.

So if you can unpack wdtvlive.bin, add your own mods and repack it as required, you have a custom root filesystem ready for upgrade (you might need to tweak wdtvlive.ver to pretend to be a higher version). All you need to do is put these 2 files in the root directory of the pen drive and boot WDTV -- you will be prompted for firmware upgrade.

That sounds pretty straight forward, except that if we mess up anywhere in this process, there is a possibility of bricking the device (at least to the users). Your player will no longer boot as there are issues with the root filesystem and you can't revert back to old firmware as it doesn't even complete boot. I have not tried with a faulty rootfs image -- so I'm not sure to what extent the protection is available before upgrade against invalid images. I doubt though. You could potentially brick the device (although not beyond repair).

I wasn't comfortable doing this, as one mistake could cost the whole device. I don't know of anyone who can fix it for me. So decided to do it myself. I thought, If I could build the tools, knowledge to unbrick a WDTV,  I could go ahead with a custom firmware upgrade. That is what I have done now and I have later realized that if I can unbrick, I could even write the customization directly into the flash memory at right locations. I have built my own serial cable for the WDTV mother board; I have also discovered the internals of the flash filesystem/partitions and their formats to patch them correctly. There is no need for WDTV's firmware update tool ie., I don't need the device to boot, to write its partitions -- the crux of unbricking.

More details to come on the internals of how I did.. stay tuned..