Booting Kindle 3

02.02.2013 19:17

It seems I'm bound to hacking various ARM-based devices these days. I've been using a kindly donated Kindle 3 with a broken screen for a few months now as kind of sandbox machine. It's always nice to have a few systems on-line one can log into from various unfashionable corners of the Internet for bouncing connections or for running a service on a whim. A Debian-running Kindle is especially nice for an always-on machine, since it consumes very little power.

So far I've been running the Kindle with a stock system, only jailbroken and with the usbnet hack installed. I installed a basic, 1.5 GB Debian chroot into the FAT partition on Kindle's flash and had a ssh daemon running on the wireless LAN interface. While it's still quite useful, that's only a part of the 4 GB of built-in storage and the daemons running in the stock system consume a lot of RAM. Plus, they sometimes mess with the hardware in ways I don't like. For instance, the wireless LAN connection usually drops when USB power goes away. Obviously the way to go was to run Debian natively.

Before I could install Debian onto the flash drive directly, I had to find out how the Kindle actually boots and what facilities are there to recover in case something goes wrong.

Kindle 3 with an RS232 adapter

As seems to be the standard on Linux-running ARMs, the first visible thing that happens is U-boot. It's stored in boot flash memory that is mapped into CPU's address space (this flash is different from the built-in MMC drive that the operating system uses).

If you press a key on the serial console at the Hit any key to stop autoboot prompt, you get a simple command line. It allows you to inspect memory, load code or data via the serial port into RAM or flash and boot a kernel that is present somewhere in the address space. There seem to also be some facility for tftp network booting, but without a wired Ethernet adapter on board it appears useless. Although U-boot can also include functionality for accessing the MMC drive, version on my Kindle has that disabled.

If you don't want to mess with the boot flash (I don't want to for now), the only thing that you can do from U-boot is to boot the Linux kernel. Kernel and an initrd image are also stored in the boot flash and hence directly accessible in the ARM address space.

The initrd image contains some recovery utilities that can be accessed by pressing Enter at the Press [ENTER] for recovery menu... prompt. Since these run directly from the initrd, they work even if the MMC drive is completely corrupted. The most useful is option 3 from the recovery menu. It exports the MMC drive as an USB mass storage device, which can then be used to setup the root filesystem from another computer (with friendly still alive... messages periodically being sent to the serial line).

3. Load MMC0 over USB storage
4. Erase MMC0
I. Initialize Partition Table (fdisk) and format FAT
O. Format and overwrite FAT partition
E. Export FAT partition
U. Update using update*.bin file on FAT partition
M. Update using update*.bin file on FAT partition of second MMC port
D. dmesg / kernel printk ring buffer.
Q. quit 

Oh, and option 3 requires a password, which is the well-known fiona + four (not three as for the root password) hex digits of the MD5 digest of the serial number.

If you don't enter the recovery menu, the code in initrd mounts the root filesystem and executes /sbin/init. From there on things proceed as usual in a normal Linux system. Kernel parameters stored in U-boot set the root filesystem as the first partition on the built-in MMC drive.

This boot process seems to be completely compatible with an armel Debian Squeeze install. One snag I did encounter is that the root partition needs to have at least /dev/console and /dev/null special files. Other device files are created at boot time by udev, but without these two, I get a tried-to-kill-init kernel panic at boot. Also, it helps to double-check /etc/fstab and /etc/inittab, since debootstrap doesn't set these up for you. Root filesystem is /dev/mmcblk0p1. If you want to be able to log-in from the serial console, a line like this works in the inittab:

mxc0:2345:respawn:/sbin/getty -L 115200 ttymxc0

The original Kindle comes with a MBR-style partition table on the MMC drive (here it's called /dev/sdd since I was inspecting it from another computer - on Kindle it's /dev/mmcblk0):

Disk /dev/sdd: 4001 MB, 4001366016 bytes
4 heads, 16 sectors/track, 122112 cylinders, total 7815168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdd1   *        7688     1338943      665628   83  Linux
/dev/sdd2         1338944     1388095       24576   83  Linux
/dev/sdd3         1388096     1404479        8192   83  Linux
/dev/sdd4         1404480     7815167     3205344    b  W95 FAT32

sdd1 is the root partition for the stock Kindle OS with an ext3 filesystem. sdd2 contains another ext3 filesystem with some kind of configuration and log storage. sdd3 is empty and was all zeros on this Kindle. sdd4 contains the storage that is visible when you attach an un-modified Kindle to a computer. It contains another MBR partition table with a single, FAT32-formatted partition.

I removed all of these and just created a single ext3 partition over the complete drive. At boot this causes some scary messages from the initrd code which seems to attempt some sanity checks on the partition table and checks for possible system updates in the FAT32 partition. Apparently it tries to correct the situation, but luckily gives up without modifying the partition table before starting Debian's init process.

While I now have a basic Debian installation running directly on the Kindle, there are still things missing. For instance, I still have to get wireless LAN to work again and there are some oddities with power management which I hope to cover in another one of these posts. All in all, Kindle turned out to be much more hacker-friendly than the Chromebook, which is surprising considering that in contrast to the evil Kindle the former has been advertised as being developer friendly.

Posted by Tomaž | Categories: Code


It's i.MX35 and its from Freescale. The datasheet states it has an Ethernet adapter. Probably it is accessible somewhere on Kindle's board. Furthermore, probably it is supported by uBoot, as well as kernel (at least some flavour of it). Check out this i.MX35 board for more info.

Furthermore there's a good chance the Ethernet adapter is also supported by the kernel (at least I would assume that for the kernel from the Phytec's developement kit). Check out also

These guys do the development of the software (kernel, userspace) for Phytec. There's a good chance you will find something useful there, too.

Nice blog. I enjoy reading it very much.

Posted by A B

Thanks for the information. I might look into that.

I'm not optimistic though. Even if MX35 variant that Kindle uses has this peripheral integrated, I think it is unlikely that the pins are routed on the PCB in a way that would allow me to attach anything to them.

Amazon's uBoot claims it supports some kind of a wired Ethernet adapter, but says no devices are present.

Posted by Tomaž

Well look at it this way. If they flashed the kernel (and maybe even the filesystem image) using uBoot, they sure didn't do it via WLAN. :)

Posted by A B

Hi,I have tried to write the wheezy image on my k3 with dd , and now it refuse to start,it only show the orange led, the battery is charged but I can get it start, no uart output, nothing, any idea?

Posted by emuboy

I actually think that Uboot is stored directly in MMC drive. Just before fisrt partition (alongside with kernel and some other data), that is why the first partition does not start at block 1.

Posted by Vaclav Vanc

Add a new comment

(No HTML tags allowed. Separate paragraphs with a blank line.)