[Galaxy S I9000 Android Development] ttabbal:
Has anyone figured out how to find the end of the ramdisk when it's compressed? I'm fooling with some Java code to try it, but the inflater class doesn't like the data that should be the start of the compressed data. No idea why yet. I can parse the gzip header, and it's right, but no decompression. From what I have read, gzip doesn't have a trailer, the only way to find the end is to decompress it.

We can decompress it and get the ramdisk contents, but knowing where to put it back in the file is the tricky part.

heh... I convinced GzipInputStream to do my bidding. :)

humph.. I was going to attach the java code to do it, but XDA is pissing and moaning about me using up a lot of storage space, a whole 35MB apparently. sigh. I'll try to inline it in a code block, hopefully you get the idea. I'll see about creating a little utility to pull, extract, and put back the ramdisk image, basically the hex editor part without the hex editor. :)

This is a prototype, change the filenames for your system. This will output the decompressed cpio image as well as give you the offsets for where to put it in a hex editor. It's a bit on the slow side, as it uses byte-at-a-time reading. Much like the dd command earlier in the thread. I'll see about buffering the I/O as well, I just wanted to get it out there to hopefully help out.

Another update. I added input buffering and it's a LOT faster. :) Hope it helps.

Just to make sure there's no question on it, the code is GPL2 licensed. I should have included the banner. :)

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;

public class FindCompressedRamdisk
{
int numRead = 0;
int totRead = 0;

public FindCompressedRamdisk()
{
try
{
File f = new File("/home/travis/kernel.img");

if (f.exists())
{
FileInputStream in = new FileInputStream(f);
byte[] rData = new byte[4096];
byte[] oData = new byte[4096];
byte[] gzipKey = { 0x1F, (byte) 0x8B, 0x08, 0x00 };
int pos = 0;

while ((numRead = in.read(rData)) != -1)
{
pos = findBytes(rData, numRead, gzipKey);

if (pos != -1)
{
int start = pos + totRead;
System.out.println("GZIP Start: " + start);

in.close();
in = new FileInputStream(f);
in.skip(start);

InputStream gin = new BufferedInputStream(new GZIPInputStream(in));
int len = 0;

OutputStream out = new BufferedOutputStream(new FileOutputStream("/home/travis/out.img"));
int b;
for ( ; (b = gin.read()) != -1; len++)
{
out.write(b);
}

System.out.println("GZIP End: " + len);

out.close();

break;
}

totRead += numRead;

}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}

public int findBytes(byte[] data, int dSize, byte[] search)
{
int found = -1;

for (int i = 0; i < dSize && found == -1; i++)
{
if (data[i] == search [0])
{
for (int j = 1; j < search.length; j++)
{
if (data[i + j] != search[j])
break;

if (j == search.length-1)
found = i;
}
}
}

return found;
}

/**
* @param args
*/
public static void main(String[] args)
{
FindCompressedRamdisk rd = new FindCompressedRamdisk();

}