I own a Kindle 3, WiFi only version and I really like this device. I also like to plug my heaphones in and listen to music while reading, and here is the problem, the 4GB internal storage space is not enough for me, I would like to add more flacs. This hack is intented for the Kindle 3W, this will not work on the 3G version, unless you remove the 3G modem.
Part1: The hardware
So I tore my Kindle apart to see whan kind of memory it uses.
It’s an eMMC chip, made by Samsung, part number KLM4G1EEHM, 4GB size. My first thought was to replace this, if I can’t somehow dd the images from the Kindle itself, I would just unsolder it, solder a few wires dead bug style and connect it to a SD slot or to some T30 CPU SD bus. Usually these devices work in 1/4/8 bit mode, so the minimum amount of wires that needed to be soldered would be about 5 (GND, VCC, CLK, DAT0, CMD) or 6 if it’s a dual voltage device. After that I would just dd the images to a new larger eMMC/format/resize/etc and solder it on the PCB. I soldered wires to some eMMC chips in the past, but as soon as I downloaded the datasheet of this chip and looked at the footprint I changed my mind, while I could solder wires on it, my hot air skills are not enough to solder the chip back in.
Now what remains is to see where to attach this eMMC. The first thing that I saw when I tore apart my Kindle was the unpopulated mini PCI-E slot, in the 3G version this is used for the 3G modem, but on the WiFi only version it’s unpopulated. After google-ing a little I found pictures with the modem and was able to find its datasheet, it uses USB via a standard mini PCI-E interface, I also poked around the pads on the PCB and everything seemed in order.
Here you cand find the standard mini PCI-E pinout: http://pinoutsguide.com/Slots/mini_pcie_pinout.shtml
Two things needed to be done on the Kindle’s PCB:
1. Solder two zero ohm resistors.
R95 and R96 on the PCB. Solder two zero ohm resistors here, or make solder straps.
2. Solder low profile mini PCI-E connector. It is important to use a low profile part, otherwise the back cover won’t fit back in. A 3.9mm height connector is needed (like this one: http://ro.farnell.com/jae/mm60-ezh039-b5-r850/mini-pci-express-latch-3-9mm/dp/1698822).
Next step was designing a mini PCI-E board to plug in there, USB interface, to eMMC. For this purpose I used the SMSC/MICROCHIP USB2240 IC, which is an Ultra Fast USB 2.0 Multi-Format, SD/MMC,
and MS Flash Media Controller. Only the SD/MMC interface is used.
This is the designed board. Eagle schematic and PCB are available here: Will upload when adding Rev A02 (corrected mini PCI-E connector, added voltage input diode!!).
This board can be equipped with eMMCs from 4GB up to 32GB.
I also designed this version, which should be somewhat cheaper to reproduce, and the PCB can be etched/soldered at home easily. This version uses a uSD card instead of an eMMC chip.
Eagle schematic and PCB are available here: Will upload when adding Rev A02 (corrected mini PCI-E connector, added voltage input diode!!).
The uSD type can be made by using a DIY PCB, the eMMC one cannot (at least I am not able to).
I made the vias with fine wire and soldered it on both sides, after that I sanded it down so that the BGA chip would land nicely:
The problem is that those solders joints will also heat when soldering the eMMC chip, since they were sanded off, the joints would simply break because of the surface tension (the brown-ish residue is from some crappy flux that I’ve used):
FAIL. To the PCB factory then!
Plug it in and.. :
usb 3-1: new high-speed USB device number 52 using xhci_hcd usb 3-1: New USB device found, idVendor=0424, idProduct=2240 usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 3-1: Product: Ultra Fast Media usb 3-1: Manufacturer: Generic usb 3-1: SerialNumber: 000000225001 usb-storage 3-1:1.0: USB Mass Storage device detected scsi20 : usb-storage 3-1:1.0 scsi 20:0:0:0: Direct-Access Generic Ultra HS-COMBO 1.98 PQ: 0 ANSI: 0 sd 20:0:0:0: Attached scsi generic sg3 type 0 sd 20:0:0:0: [sdd] 61997056 512-byte logical blocks: (31.7 GB/29.5 GiB) sd 20:0:0:0: [sdd] Write Protect is off sd 20:0:0:0: [sdd] Mode Sense: 23 00 00 00 sd 20:0:0:0: [sdd] No Caching mode page found sd 20:0:0:0: [sdd] Assuming drive cache: write through
It works, 32GB of storage, quite high speed, ~18MB/s WR and ~33MB/s RD, connected via USB to a PC (not to a Kindle).
Part2: The software
Many thanks to the guys at mobileread.com for the jailbreak and usbnetwork. I will mirror those archives here.
Latest firmware. First thing, update the Kindle to the latest available firmware version (3.4), files and instructions are available here: http://www.amazon.com/gp/help/customer/display.html/ref=surl_sw_31?nodeId=200529700 . Copy the proper update bin via USB directly under the root directory (mount point). Umount and and from the Kindle and press [HOME] -> [MENU] -> select “SETTINGS” -> [MENU] – > Select “Update your Kindle” . After the process is complete it will self-reboot.
Jailbreak it. After updating to firmware 3.4, jailbreak it. Download jailbreak 0.12, copy the proper file to the kindle and update. Mirroring the archive here: kindle-jailbreak-0.12.N . For the Kindle 3 wireless only version, the proper file is : Update_jailbreak_0.12.N_k3w_install.bin . Copy this file via USB directly under the root directory (mount point). Umount and and from the Kindle and press [HOME] -> [MENU] -> select “SETTINGS” -> [MENU] – > Select “Update your Kindle” . After the process is complete it will self-reboot.
USB Network. To ssh in. Serial console can also be used. 0.5.4 version is used. Mirroring the archive here: kindle-usbnetwork-0.54.N-k3 . file to the kindle and update. For the Kindle 3 wireless only version, the proper file is : Update_usbnetwork_0.54.N_k3w_install.bin . Umount and and from the Kindle and press [HOME] -> [MENU] -> select “SETTINGS” -> [MENU] – > Select “Update your Kindle” . After the process is complete it will self-reboot.
After it boots, under the Home screen, press “Del” on the keyboard and type:
Press “Enter”, press “Del” again and type:
Followed by another Enter. Now connect Kindle via USB to a PC and a new interface should appear (on the PC side), usb0.
If you have a network manager, it would be a good ideea to stop it so it doesn’t mess up the connection. Or just use the network manager to handle the connection.
In a local terminal, do :
sudo ifconfig usb0 up && sudo ifconfig usb0 192.168.2.1 ssh email@example.com
At this point, it should ask for the root password, which is “root” and we should be logged in.
Poke around. If we check the dmesg log we can see the following:
[root@kindle kernel]# dmesg | head CPU: ARMv6-compatible processor [4117b363] revision 3 (ARMv6TEJ), cr=00c5387f Machine: Amazon MX35 Luigi Board [root@kindle kernel]# uname -a Linux kindle 2.6.26-rt-lab126 #5 Sat Sep 1 14:28:26 PDT 2012 armv6l unknown
The CPU is an IMX35, ARMv6, clocked at 532MHz. Sytem RAM is 256MB. The “Luigi” part is useful to know which defconfig to use.
# lsmod Module Size Used by g_ether 21096 0 ar6000 161076 0 volume 8900 0 fiveway 23552 0 mxc_keyb 15904 0 uinput 7776 0 fuse 48348 2 arcotg_udc 38628 1 g_ether mwan 7324 0 eink_fb_shim 116732 0 eink_fb_hal_broads 397532 0 eink_fb_hal 59764 6 eink_fb_shim,eink_fb_hal_broads
[root@kindle modules]# cd /lib/modules/2.6.26-rt-lab126/ [root@kindle 2.6.26-rt-lab126]# find | grep usb ./kernel/drivers/usb ./kernel/drivers/usb/host ./kernel/drivers/usb/host/ehci-hcd.ko ./kernel/drivers/usb/serial ./kernel/drivers/usb/serial/option.ko ./kernel/drivers/usb/serial/usbserial.ko ./kernel/drivers/usb/gadget ./kernel/drivers/usb/gadget/g_ether.ko ./kernel/drivers/usb/gadget/g_serial.ko ./kernel/drivers/usb/gadget/g_file_storage.ko ./kernel/drivers/usb/gadget/arcotg_udc.ko ./kernel/drivers/usb/core ./kernel/drivers/usb/core/usbcore.ko ./kernel/drivers/usb/mon ./kernel/drivers/usb/mon/usbmon.ko ./modules.usbmap [root@kindle 2.6.26-rt-lab126]# find | grep scsi [root@kindle 2.6.26-rt-lab126]#
So no modules for scsi or usb storage. Check if they are built-in:
[root@kindle 2.6.26-rt-lab126]# zcat /proc/config.gz | grep -i scsi # SCSI device support # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' [root@kindle 2.6.26-rt-lab126]# zcat /proc/config.gz | grep -i usb_storage # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # may also be needed; see USB_STORAGE Help for more information
And they are not built-in. We need to compile those, preferably as modules so we don’t need to mess with the kindle’s kernel (which is written at the beginning of the eMMC, before any partitions start).
Kernel stuff. First step is to get the sources for the 3.4 firmware. Download link here (local mirror): Kindle_src_3.4_1725970040.tar.gz . I have found this archive somewhere on the amazon servers. And it seems that it also appears(finally, after some years) http://www.amazon.com/gp/help/customer/display.html?nodeId=200203720, this after a bunch of calls and a lot of e-mails requesting the GPL sources for the 3.4 firmware version. Thank you Amazon!
After extracting this archive, the kernel src archive can be found, linux-2.6.26-lab126.tar.bz2. Extract this also.
For loading/inserting a freshly compiled kernel module, the module needs to be compiled with a very very similar gcc version as the kernel. To find out which version, I copied one binary (some kernel module) from the Kindle to my PC, and used objdump:
$ objdump -s --section .comment eink_fb_hal.ko eink_fb_hal.ko: file format elf32-little Contents of section .comment: 0000 00474343 3a202847 4e552920 342e312e .GCC: (GNU) 4.1. 0010 32000047 43433a20 28474e55 2920342e 2..GCC: (GNU) 4. 0020 312e3200 00474343 3a202847 4e552920 1.2..GCC: (GNU) 0030 342e312e 32000047 43433a20 28474e55 4.1.2..GCC: (GNU 0040 2920342e 312e3200 00474343 3a202847 ) 4.1.2..GCC: (G 0050 4e552920 342e312e 32000047 43433a20 NU) 4.1.2..GCC: 0060 28474e55 2920342e 312e3200 00474343 (GNU) 4.1.2..GCC 0070 3a202847 4e552920 342e312e 32000047 : (GNU) 4.1.2..G 0080 43433a20 28474e55 2920342e 312e3200 CC: (GNU) 4.1.2.
So GCC version is 4.1.2 . Since it's a kernel module that needs to be compiled, the libc version of the toolchain does not matter.
Toolchain. One can always compile a toolchain, or just download one from CodeSourcery. I have used this version: arm-2006q3-26-arm-none-linux-gnueabi.bin .
Install the toolchain by running the .bin file:
$ bash ./arm-2006q3-26-arm-none-linux-gnueabi.bin
Under a 64-bit Ubuntu system the following error will appear :
java.lang.UnsatisfiedLinkError: /tmp/install.dir.20318/Linux/resource/jre/lib/i386/libawt.so: libXp.so.6: wrong ELF class: ELFCLASS64
This can be resolved by installing the 32 bit version of libXp, by:
$ sudo apt-get install libxp6:i386
I have installed the toolchain in my home dir, under ~/CodeSourcery/Sourcery_G++ .
Quick version check:
:~/CodeSourcery/Sourcery_G++/bin$ ./arm-none-linux-gnueabi-gcc --version arm-none-linux-gnueabi-gcc (CodeSourcery ARM Sourcery G++ 2006q3-26) 4.1.1
Close enough! (I hope).
Compiling the kernel. Change directory to the kernel sources, export the needed stuff, use the proper defconfig.
cd gplrelease/linux-2.6.26 export ARCH=arm export CROSS_COMPILE=~/CodeSourcery/Sourcery_G++/bin/arm-none-linux-gnueabi- make imx35_luigi_defconfig
Open the .config file in a text editor and change the following:
While we could extract the initramfs from the Kindle and add the files here, this is not needed, as we need only some kernel modules. Exit the text editor and paste the following:
cat> include/linux/kindle_version.h << EOF # ifndef __KINDLE_VERSION_H__ # define __KINDLE_VERSION_H__ # define VERSION_TAG "000000" # endif EOF
Type “make menuconfig” and select the following:
Under “Device drivers” ->> “SCSI device support” : check “SCSI device support” as module, “SCSI disk support” as module, “SCSI generic support” as module.
Under “Device drivers” ->> “USB support” : check “USB Mass Storage support” as module.
On the Kindle ssh terminal. Mount the rootfs as writeable, since we will copy stuff here, and also create some directories:
mntroot rw mkdir -p /lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi mkdir -p /lib/modules/2.6.26-rt-lab126/kernel/drivers/usb/storage
Back to the local therminal where the kernel was compiled. The following modules need to be copied to the Kindle:
scp drivers/scsi/sd_mod.ko firstname.lastname@example.org:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/ scp drivers/scsi/scsi_mod.ko email@example.com:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/ scp drivers/scsi/scsi_wait_scan.ko firstname.lastname@example.org:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/ scp drivers/scsi/sg.ko email@example.com:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/ scp drivers/usb/storage/usb-storage.ko firstname.lastname@example.org:/lib/modules/2.6.26-rt-lab126/kernel/drivers/usb/storage/
Back to the Kindle ssh terminal:
[root@kindle usb]# depmod -a [root@kindle kernel]# modprobe usbcore [root@kindle kernel]# modprobe usb-storage [root@kindle kernel]# modprobe scsi-mod [root@kindle kernel]# modprobe sd_mod [root@kindle kernel]# dmesg | tail usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1 fsl-ehci fsl-ehci.0: irq 35, io mem 0x53ff4400 fsl-ehci fsl-ehci.0: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected SCSI subsystem initialized Initializing USB Mass Storage driver... usbcore: registered new interface driver usb-storage USB Mass Storage support registered. Driver 'sd' needs updating - please use bus_type methods [root@kindle kernel]# lsmod Module Size Used by sd_mod 20976 0 usb_storage 37792 0 scsi_mod 107552 2 sd_mod,usb_storage usbcore 136388 1 usb_storage g_ether 21096 0 ar6000 161076 0 volume 8900 0 fiveway 23552 0 mxc_keyb 15904 0 uinput 7776 0 fuse 48348 2 arcotg_udc 38628 1 g_ether mwan 7324 0 eink_fb_shim 116732 0 eink_fb_hal_broads 397532 0 eink_fb_hal 59764 6 eink_fb_shim,eink_fb_hal_broads
Good! No errors when loading, modules are in place. One USB hub with one port is detected. Time to insert the hardware… again. Right after swapping one USB2240. Apparently the Kindle does not provide 3.3V via the mini PCI-E connector, but directly the battery voltage! About 4.2V when the battery is fully charged. This was enough to fry one controller, luckily the eMMC chip is still alive. As a temporary fix until I think of a way to get 3.3V out of ~3V to 4.2V (at full charge), I had cut the power traces and added two diodes, when the battery is fully charged, the eMMC chip and the controller will be powered by ~3.6V, which is well within safe specs.
Good, plug the bastard in the Kindle.. and.. nothing happens. No kernel messages regarding new usb devices. Maybe on the Kindle 3W verion that USB is not connected, however I don’t see any missing components that are connected to the USB signals at the mini PCI-E connector. Trace the DP and DM signals from the mini PCI-E connector pads on a dead Kindle board (piece of advice, do NOT plug in the eink display while the board is powered on, it may fry the epson eink controller and the PSU):
They go directly in the IMX35 CPU (see the pads within the red outline). Those pads correspond to BGA balls Y17 and Y18. Just a quick look at the IMX35 datasheet and those are USB port 2 DATAP and DATAM.
Somome sporadic messages appear in dmesg when usbcore and echi-hcd modules are loaded and the mini PCI-E card is plugged in :
Enter LPM ehci exiting lpm Enter LPM ehci exiting lpm Enter LPM
These messages come from linux-2.6.26/drivers/usb/host/ehci-hcd.c, however no other messages, something is wrong.
First guess, inverted DP with DM, so I cut the traces and switched DP with DM on the mini PCI-E board, modprobe usbcore and ehci-hcd and get the following:
fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1 fsl-ehci fsl-ehci.0: irq 35, io mem 0x53ff4400 fsl-ehci fsl-ehci.0: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected usb 1-1: new low speed USB device using fsl-ehci and address 2 usb 1-1: device descriptor read/64, error -71 usb 1-1: device descriptor read/64, error -71 usb 1-1: new low speed USB device using fsl-ehci and address 3 usb 1-1: device descriptor read/64, error -71 usb 1-1: device descriptor read/64, error -71 usb 1-1: new low speed USB device using fsl-ehci and address 4 usb 1-1: device not accepting address 4, error -71 usb 1-1: new low speed USB device using fsl-ehci and address 5 usb 1-1: device not accepting address 5, error -71 hub 1-0:1.0: unable to enumerate USB device on port 1
Quite curious, why the device is reported as a low speed USB device instead of a “high speed” or a “full speed” one.
The USB2240 controller is a USB2.0 only device, and regarding the IMX35, in the datasheet it says:
•1 USB 2.0 host with ULPI interface or internal full-speed PHY. Up to 480 Mbps if external HS
PHY is used.
• 1 USB 2.0 OTG (up to 480 Mbps) controller with internal high-speed OTG PHY
Up to 480Mbps if an external PHY is used, I don’t see any external PHY on the PCB.
480Mbps – High speed (USB2.0 only) – won’t work on the Kindle
12Mbps – Full speed (USB1.1 and USB2.0) – should work on the Kindle
1.5Mbps – Low speed (USB1.1 and USB2.0) – should work on the Kindle
The “high speed” is not available, because of the lack of an external HS PHY. Judging from the kernel log, the device does not appear to work under “Full speed” but under “Low speed” . However, the USB2240 controller seems to work only under “high speed”.
The USB2240 has all required USB related resistors internal, it has a pull-up on D+ to notify the host that this is a full speed device. If the pull-up was on D-, then it would notify the host that it’s a low speed device. The above errors and the fact that it was detected as a low speed 1.5MBps device, made me think that maybe D+ and D- were right at the beginning, so I swapped them again.
Plugged in the module, loaded the modules, again nothing.
mwan: I mwan_init:init:mario WAN hardware driver 1.2.0
GPIO port 1 (0-based), pin 14 is already reserved!
GPIO port 0 (0-based), pin 19 is already reserved!
GPIO port 1 (0-based), pin 0 is already reserved!
(?°?°??? ??? . So much better, so much full speed!
hub 1-0:1.0: port 1, status 0109, change 0001, 12 Mb/s usb 1-1: new full speed USB device using fsl-ehci and address 2 fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes usb 1-1: device descriptor read/64, error -71 fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes usb 1-1: device descriptor read/64, error -71 usb 1-1: new full speed USB device using fsl-ehci and address 3 fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes fsl-ehci fsl-ehci.0: devpath 1 ep0in 3strikes