View Single Post
Old 08-20-2010, 04:48 AM   #7
choff
Member
choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.choff walks where angels fear to fly.
 
Posts: 12
Karma: 152738
Join Date: Jul 2010
Device: Kindle DXG
initramfs from uImage

As chinaet already implied, the newer Kindles use an initramfs instead of an initrd. The Kindle's initramfs is linked statically into the Kernel image.

In this post I will describe how I managed to get the uImage from the device and extracted the initramfs from it.

Part 1: Get uImage from device
There are multiple ways to do this. chinaet use /dev/mtd1ro, but you can also fetch a memory dump from U-Boot if you have a serial connection to your Kindle(which will give you bootloader access).

Here are the instructions for fetching the uImage from the boot loader:
  1. Boot your Kindle via serial console and enter U-Boot.
  2. Type "imls" to get a list of all installed images on your device:
    Code:
    uboot> imls
    Image at A0060000:
       Image Name:   s049546-1006081846-TN2.1~2.6.22.
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    1887264 Bytes =  1.8 MB
       Load Address: 80008000
       Entry Point:  80008000
       Verifying Checksum ... OK
    Image at A0400000:
       Image Name:   s049546-1006081846-TN2.1~2.6.22.
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    1887264 Bytes =  1.8 MB
       Load Address: 80008000
       Entry Point:  80008000
       Verifying Checksum ... OK
  3. On my Kindle both recovery and normal image were identical, so we only have to get a dump of one of those images.
    First, change the address offset to the address of one of those kernel images (I used image 1):
    Code:
    uboot> base A0060000
    Base Address: 0xa0060000
  4. To check the base address, let's display the u-Boot header of the image at this position:
    Code:
    uboot> md.b 0 40
    a0060000: 27 05 19 56 07 97 c8 68 4c 0e f6 88 00 1c cc 20    '..V...hL...... 
    a0060010: 80 00 80 00 80 00 80 00 6b 87 43 35 05 02 02 00    ........k.C5....
    a0060020: 73 30 34 39 35 34 36 2d 31 30 30 36 30 38 31 38    s049546-10060818
    a0060030: 34 36 2d 54 4e 32 2e 31 7e 32 2e 36 2e 32 32 2e    46-TN2.1~2.6.22.
    md.b will display the memory from address 0x0 to 0x40 relative to the base address. If your are interested in the U-Boot header format, look at include/image.h in the U-Boot sources(included in Amazon's source code release).
  5. imls(or the above memory dump of the header) will give you the data size of your image. In my case, the data size is 1887264=0x001ccc20 Bytes.
    Add 64 Bits(the size of the header) to the data size and you get the size of your uImage.
    Now we will pull a dump of the whole uImage via the serial line. Minicom has a nice capture mode which can be enabled by typing CTRL-A, then Z and then L.
    After you have started capturing, we can get us the dump:
    Code:
    md.b 0 {size of uImage in hex, see above}
    And then allow some time to pass for the transmission(about 15 Mins).
  6. Now for the difficult part: First of all, stop capturing by pressing the same keys in Minicom again.
    Then let's have a look at your captured file. It should look something like this:
    Code:
    uboot> md.b 0 1ccc60
    a0060000: 27 05 19 56 07 97 c8 68 4c 0e f6 88 00 1c cc 20    '..V...hL...... 
    {very many lines}
    a022cc50: 44 4c 1d 00 00 00 00 00 00 00 00 00 00 00 00 00    DL..............
    Delete everything from the file that does not belong to the dump(in my case that would be the first line).
  7. Now that we have the uImage as memory dump, it would be nice to convert this output into a real file.
    I have written a C program which does this task for you(attached), but you still need to compile it with gcc or an IDE. I am too lazy too look up how to do this from command line via gcc, but there are probably tons of info on this in the internet.
  8. Now you can run the whole thing:
    Code:
    ./UBootMemeryDumpParser {path to dumpfile} > uImage
    It will probably complain about a few errors in you dump, but this is normal. Just use "base" from u-boot to jump to the address in the incorrect line and "md.b" to get the few wrong bytes. This way you can replace wrong lines in your dump without needing to get an entirely new copy of the uImage dump.
  9. Test if your image is valid:
    Code:
    mkimage -l uImage
    . If not, you will have to get the whole dump again(or did you forget to add the 64 Bits of the U-Boot header to the data size when running md.b?)

Part 2: Extract initramfs from uImage
  1. Don't worry, the rest is easy once you know how to do it. First of all, we need to extract the zImage from the uImage by stripping the 64-bytes uImage header:
    Code:
    dd if=uImage of=zImage bs=1 skip=64
  2. Now let's uncompress the zImage.
    Code:
    grep -P -a -b --only-matching $'\x1f\x8b\x08\x00' < zImage
    12896:�
    will search for the zcat header(in my case at position 12896).
    Then
    Code:
    dd if=zImage bs={number from above command} skip=1 | zcat - > Image
    will give you the uncompressed image.
  3. Now we use
    Code:
    grep -P -a -b --only-matching $'\x1f\x8b\x08' < Image
    84448:�
    2639420:�
    to determine the start of the initramfs by searching for the gzip-header. Only the first number is interesting.
    So now we can fetch the initramfs:
    Code:
    dd bs={your first number, in my case 84448} if=Image skip=1 | gzip -d -c > initramfs.cpio
  4. Now extract initramfs.cpio. If you want to have device nodes created, make sure you do it as root:
    Code:
    sudo cpio -i --no-absolute-filenames < ../initramfs.cpio
Attached Files
File Type: gz U-BootMemoryDumpParser.tar.gz (2.2 KB, 213 views)

Last edited by choff; 03-21-2012 at 01:07 PM.
choff is offline   Reply With Quote