Thursday, January 27, 2011

Taking a disk image of the Kobo Wifi without opening the device

This article is part of an extended series on Kobo development and investigation


Any attempt to modify your device is risky. Your device might be permanently destroyed. If you cannot risk the permanent loss of your device, so not attempt to modify it. Something can easily go wrong if you do the wrong thing - or follow out of date instructions. I don't continually maintain and test these instructions, so they might well qualify.

If you can't afford to lose it forever, physically open your Kobo up before doing anything, remove the SD card, and take a disk image of it using a PC with a card reader. I use `dd` with a Linux box to make sure I get a complete image of the entire card.

Note that you could break the case or retaining clips when opening your Kobo. I didn't and I opened mine quite a few times, but who knows if they've changed assembly techniques, plastics, etc since then.

Messing with embedded devices that aren't designed to be hacker-friendly is risky. Deal with it, or don't mess with the device.


Once you've enabled telnet on your Kobo Wifi, you can use it to transfer a disk image of the Kobo's entire firmware image on the internal MicroSD card. This will give you a backup copy of your Kobo's firmware on your computer.

You can't restore the firmware image without physically opening your Kobo if you mess things up badly enough for it not to boot, but hopefully you won't do that. The Kobo seems to be amazingly hard to break unless you corrupt its file systems, overwrite its kernel, etc. Anyway, this way you can avoid opening the Kobo until/unless you ever need a total firmware restore.

Imaging the Kobo's firmware over wifi

To image the disk of a running system, we need all its file systems in read only mode. This turns out to be trivial to achieve with the Kobo, though it requires terminating the main eReader process ("nickel") so you'll want to reboot after you've done it. During the process, the screen will display whatever was on it before you ran the commands to image the system and none of the keys will respond. Just:

pkill nickel
mount -o ro,remount /mnt/onboard
mount -o ro,remount /
nc -l 9984 < /dev/mmcblk0

Now, take note of the IP address printed by the commands above and use it in this command on your main computer:

nc IP_OF_KOBO 9984 > kobo_internal_microsd.img

The disk imaging process will take a while over wifi, and won't show any progress. Mine took about twenty minutes. If you want progress indication, open a second terminal and run:

watch "du -ms kobo_internal_microsd.img"

... to get a count in megabytes of data transferred so far.

Finally, reboot the kobo to bring it back to normal. You can do this by pressing and holding the power button for 6+ seconds, or by typing control-C then "reboot" and enter into the telnet command line on the kobo.

The image saved on your computer should be 1977614336 bytes for a Kobo Wifi with a 2GB internal card (~1.1GB user accessible memory).

If you have any issues, try a different port number with nc.

^C
reboot

Once you have the Kobo's disk image, you can mount the partitions within it to examine them, and you can extract some individual components of the unpartitioned space in the card.

Imaging the Kobo's firmware to an SD card

In principle you can also image the Kobo's firmware to an SD card instead of using wifi. This will be much easier if you don't run Linux. You need a 2GB or larger card.

To image the Kobo's firmware to an SD card you can telnet in to the kobo and make the file systems read-only as above. Make sure you unmount the external sd card /mnt/sd if it is mounted. Then, instead of getting the IP address and running netcat in listen mode, you can just `dd' the internal mmc card to the external sd card, `sync' to force it to flush, and `reboot'.

Alternately, you may prefer to leave the external SD card mounted, remount everything else read only, then run:

dd if=/dev/mmcblk0 | gzip > /mnt/sd/kobo.img.gz

... to make a compressed image (slow!) on the file system on the SD card. This will be easier to work with under Windows, which doesn't work well with raw devices.

Examining the firmware image

gunzip the image if it's compressed. Either back up a copy of the firmware image that you will not touch, or make the firmware image read-only with chattr +i.

You may now mount the three file systems on the image using this little script - or by hand by using "fdisk -l" to dump the partition table, then calculating the offsets to pass to losetup. If you want to use my script, I make no promises that it won't eat your system and your cat, so be careful. Save the following to "kobomount.sh" and mark it executable:

#!/bin/bash
set -e -u
if test $# -ne 1 ; then
  echo "Usage: $0 firmware.img"
  exit 1
fi
IMG=$1
i=0
sudo -v
for offset in $(sfdisk -d kobo_2gb_microsd_image_v174.img | grep start | cut -d : -f 2 | awk '{print $2}' | sed 's/,//g' |grep -v ^0$); do
  sudo losetup --offset $(( $offset * 512 )) /dev/loop$i "$IMG"
  sudo mkdir -p /mnt/kobo/$i
  sudo mount -o ro /dev/loop$i /mnt/kobo/$i
  ((i++))||true
done

You may then aim it at your firmware image and it'll mount the contained partitions on /mnt/kobo/0 (the recovery partition), /mnt/kobo/1 (the main OS) and /mnt/kobo/2 (the user flash partition). All will be read-only.

You may also want to extract some blobs from the unpartitioned space at the start of the image. That's where the kernel, boot splash image, etc live. I don't have official documentation on the layout of this space, but reading the upgrade scripts in /etc/init.d suggests that these values should be about right. They are UNVERIFIED except for the boot splash image, which I've been able to edit and replace.

IMG=kobo_2gb_microsd_image_v174.img
dd if=$IMG of=serialnumber.bin bs=512 count=1 skip=1
dd if=$IMG of=hwconfig.bin bs=512 count=1 skip=1024 count=2
# The image that ships with the kobo is < 470 512 byte blocks long. It's not clear
# if something else takes the space between the end of the image and the start of
# the epson display binaries, if it's dead space, or if there's room for bigger
# images.
dd if=$IMG of=bootlogo.bmp bs=512 skip=1026 count=470 
dd if=$IMG of=epson_display_setup.bin bs=512 count=1 skip=1920 count=8
dd if=$IMG of=epson_waveform.bin bs=512 count=1 skip=1928 count=$((2048 - 1928))
dd if=$IMG of=kernel.bin bs=512 count=1 skip=2048 count=$((7564-2048))

The Kobo's kernel

We can now examine the existing kernel to learn more about it. This post tells us how to extract the kernel (but it's more easily done with scripts/extract-ikconfig from a kernel tree)

The hard way (which lets us extract the image, not just the config) in brief:

od -A d -t x1 kernel.bin | grep '1f 8b 08 00'
# Note the (decimal) offset, correct for offset of deflate header into line
dd if=kernel.bin bs=1 skip=0013076 | zcat > vmlinux

The easy way to dump the config:

scripts/extract-ikconfig $HOME/kobo/kobofirmwaredump/kernel.img

Boot loading is apparently performed by RedBoot (2.0 according to shipped sources), which should offer tools like `fis list' to report on the structure of the redboot-managed areas of flash storage. Building redboot is a nightmare, so I haven't investigated this yet.

10 comments:

  1. On my version of Busybox I needed"busybox nc -l -p 9984 < /dev/mmcblk0" (adding "busybox" and the -p specifier)

    ReplyDelete
  2. Did you try to boot from SD? If so, how?
    I tried to use the image taken from the micro-sd, without success.
    Copying only the boot partition didn't help either.

    Am I missing something obvious?

    Sorry to drag you back to the kobo, but it seems you're the best source of information about it.

    ReplyDelete
  3. No, I never really messed with the SD support. Theoretically it boots off SD if you hold down the "enter" button (middle button of the D-Pad) until at least the first five bars have appeared during boot. See:

    http://www.mobileread.com/forums/showpost.php?p=1152496&postcount=20

    The fact that it requires the first 5 bars suggests that at least uBoot and probably the kernel are still loaded off the onboard MicroSD. I suspect it only loads the root file system and (maybe) user accessible flash off the external SD when "booted" off SD.

    It's possible that it loads the kernel too, but given how uBoot works I doubt it.

    ReplyDelete
  4. Sorry, Redboot for the Kobo Wifi.

    ReplyDelete
  5. I've seen that post, but I don't think it applies to the Kobo Wifi.

    When I try to load from SD card, it just stops after the black squares and doesn't respond anymore (until I turn it off).

    ReplyDelete
  6. What are you trying to load?

    I don't know what the required partition structure and layout are for booting off the external SD card. I doubt it's the same as the internal SD, which has a copy of redboot on it, a kernel, etc.

    You'd probably have to unpack the initramfs/initrd and read its scripts to see what it expects to find.

    ReplyDelete
  7. (Did I reply before? Not sure anymore. Hope not.)

    I tried to load the whole SD image and just the system itself.

    I might be a step further - I now think that Redboot needs a FAT formatted SD card. And it expects *something*.
    With an Ext3 SD, it will just stop. With a FAT SD card with the system copied to it, the black squares go around, but endlessly so.
    With a FAT SD without any content, or not enough, it'll stop too.

    It's too bad I don't have any upgrade scripts like on the EB600.
    I tried to find them, and I might have found something, but it's not working. The Greenbook *might* be the same hardware. Perhaps it's just coincidence...

    Regarding initramfs/initrd - I hate to ask, but how can I find them? I know what they are, but I have no clue how to find them. I'd suppose either in the unpartitioned segment of the disc, or inside the (Redboot?) kernel?
    The actual system kernel doesn't seem to use an initrd file, so it should be somewhere near redboot.

    ReplyDelete
  8. Kind of late, but can anyone send me their SD backup image if they still have it? --robosteve at gmail.com

    ReplyDelete
  9. I also searching for it's firmware and can't find it anywhere...if somebody have it please share ...
    Thank you.

    ReplyDelete
    Replies
    1. Even if I had it, which I no longer do, I could not distribute it without violating Kobo's copyright. That is why there's that big disclaimer on the top of this article warning you that if you break it, well, bad luck.

      I don't know how to make this any clearer. I cannot give you the firmware. You must take your own firmware image from a working Kobo.

      Delete