Kindle 3W – 32GB memory expansion

20140716_032323I 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.

This is the main PCB:
20140622_020250

And this is its storage device:
20140622_020043

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.

This is a Toshiba eMMC chip with the same footprint:
20140622_020105

I decided to use another eMMC chip, N2M400*:
20140622_020134

With a more humane footprint:
20140622_020120

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.
20140622_024319
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).
20140622_020227

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.

Selection_059

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.

Selection_060

Eagle schematic and PCB are available here: Will upload when adding Rev A02 (corrected mini PCI-E connector, added voltage input diode!!).

Here are the etched PCBs:
1. eMMC type
20140622_020201

20140622_020206

2. uSD type
20140622_02021320140622_020220

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:
20140622_003045
20140622_003131
20140622_004123
20140622_003036

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):
20140622_031257

FAIL. To the PCB factory then!

Fast forward a couple of weeks, and the PCBs arrived from seeedstudio, gold plated. They look great, except the small text on the silkscreen, I’ve seen better silkscreen.
20140716_020702
20140716_020753
20140716_020802

Next step was soldering the components, for the BGA and the QFN chip I used a hot air gun, for the rest a regular soldering iron:
20140716_032315
20140716_032323
20140716_032346

I made a crude “USB adapter” to quickly test the board using my computer, one mini pci-e connector, one 3.3V regulator, one capacitor, and some wires:
20140716_035756

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

Some pictures with the memory expansion module inside the Kindle:
20140718_011700
20140718_011704 20140718_011708 20140718_011719 20140718_011744

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:

;debugOn

Press “Enter”, press “Del” again and type:

~usbNetwork

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 root@192.168.2.2

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:

CONFIG_INITRAMFS_SOURCE="../../initramfs/skeleton-luigi.list ../../initramfs/image/"

to

CONFIG_INITRAMFS_SOURCE=""

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.

make -j8

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 root@192.168.2.2:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/
scp drivers/scsi/scsi_mod.ko root@192.168.2.2:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/
scp drivers/scsi/scsi_wait_scan.ko root@192.168.2.2:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/
scp drivers/scsi/sg.ko root@192.168.2.2:/lib/modules/2.6.26-rt-lab126/kernel/drivers/scsi/
scp drivers/usb/storage/usb-storage.ko root@192.168.2.2:/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.

20140720_182017

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):

20140720_181247-red

Selection_066
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.

USBOTG_OC U7
USBOTG_PWR W7
USBPHY1_DM N19
USBPHY1_DP P19
USBPHY1_RREF R19
USBPHY1_UID N18
USBPHY1_UPLLGND N14
USBPHY1_UPLLVDD N15
USBPHY1_UPLLVDD P17
USBPHY1_VBUS P18
USBPHY1_VDDA_BIAS R20
USBPHY1_VSSA_BIAS R18

USBPHY2_DM Y17
USBPHY2_DP Y18

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

6 comments on “Kindle 3W – 32GB memory expansion

  1. Codeasm November 15, 2014 11:22 pm

    Looks realy awesome, especialy the selfmade mini PCI-E board. Was looking for controlling a eink paper I got but this is also cool. Good luck and have fun.

    • Daniel April 3, 2015 3:43 pm

      Thanks for your message! I have not yet worked with e-ink displays, but I have a few future projects in mind that will use them.

  2. Peter January 6, 2015 12:01 am

    Hello,
    this project is really nice! Could u please upload the egale files? I would like to create a similar project.
    Greating from Germany
    Peter

    • Daniel April 3, 2015 3:42 pm

      Hello Peter,

      Sorry for the late reply, I saw your message while deleting 1703 spam messages. I won’t upload the files here yet, since the project is not yet complete (works of in standard mini-PCIe socket with USB signals, but does not yet work in the Kindle.). I have to make a small correction to the boards first, and I’ll send you the files via e-mail.

      Greeting from Romania!

      • Stefan November 6, 2016 1:31 am

        How much would you charge to do it for a kindle touch. Thanks.

  3. Juan October 15, 2017 5:01 pm

    Hi Daniel.

    Can you upload the eagle schematic and PCB? I’m learning and this seems to be a perfect project to made my own usb flash drive memory.

    Bye and Thanks

Leave a Reply to Codeasm Cancel Reply

Your email address will not be published.


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>