How to unpack/repack initramfs in zImage

Search This thread

dkcldark

Senior Member
Jul 3, 2010
105
442
Here we go.

I'm saying that I'm not a very good developer so this information could be messy, contain unnecessary works or a bit wrong.
And also I'm not sure if this method will work with every zImage from every device.

I've tested with
I9000-JM2/JM7 : ECLAIR
JPC : FROYO
and they work like a charm.

OK, now we start.

Download this file

http://www.multiupload.com/GSVLO15WDL

It has cross-compiler in it so that it's slightly big.

------------------------------------------------------------

This is basically for devs so I won't tell you specifically. (or I can't...maybe)



1. Extract cpio'ed initramfs file from zImage.

## EDIT : In order to extract initramfs.cpio, go through from step4 to step11.
A file which starts with "30 37 30" means that this is a cpio'ed file.
So, trim the Image-Orig file from the beginning to the point just before "30" then, you've got a cpio compressed file.
You can now simply decompress it.

cat initramfs.cpio | cpio -i --no-absolute-filenames



2. Decompress and edit these files. Make sure you shouldn't go over the original size. (simply, I removed redbend_ua in /sbin forder)
3. Recompress to cpio. ( I've used scripts/gen_initramfs_list.sh which is in the kernel source for a safe bet)

## EDIT : What I've done is here. chdir to "zImage_repack/2.6.29" forder then

/bin/bash scripts/gen_initramfs_list.sh -o usr/initramfs_data.cpio -u 0 -g 0 /home/zero/Desktop/JPC/initramfs/i9000_initramfs_list







4. open the zImage with a hexeditor.
5. find "1f 8b 08".
6. cut off from the beginning to the point just before the "1f" so that this file begins with "1f 8b 08".
7. save as anyname.gz
8. in terminal >>>> gunzip anyname.gz

Now, you've got an Image file. I'll call this as an Image-Orig.

9. open the Image-Orig file with a hexeditor.
10. remember the entire size of this file. One of mine was "0xb9a5df".
11. find "30 37 30" hexademical code and "TRAILER!!!" text.
12. cut off from the first "30" to the last "!".
an example is here
111vl.png



13. open the cpio file you had recompressed with the hexeditor.
14. paste this codes to the exactly same place where the former initramfs was, in Image-Origin file. (Up to now, I feel like English is more difficult than this trick...sigh, sorry for my bad english!)
15. Almost done. We're gonna make the modified Image file's size identically to the Image-Orig. It's simple. just fill the hole with a bunch of NULLs. put your finger on "0" button and have a little sleep.


I think I need a visual assistant.


88509078.png



76205972.png



36302789.png



61057337.png



77523285.png



10411681.png



91666980.png


Save it as "Image".


At this point, you should have an Image file which size is the same as Image-Orig.


Now open the file you've downloaded at the first.

there is a forder called place_Image_here

yeah, place the Image there and execute the "Repack_kernel.sh" file.

In several seconds, you'll have a zImage file.

I'm so tired and I can't last this writing so, if you have any question, I'll give you a reply.

Thanks!




## PLUS : I've attached the modified JPC kernel which supports /system/etc/init.d/userscripts.sh

It's named JPC_modified_kernel.tar.zip and you should take the ".zip" off in order to use with Odin.

## PLUS2 : I've compiled gnu_parted! also attached. good luck, RyanZA!
-info : GNU parted v2.2 (original version, didn't apply bug fixes.)
disabled device-mapper and read-line while compiling, does this matter?



parted.jpg



partprobe.jpg
 

Attachments

  • JPC_modified_kernel.tar.zip
    4.5 MB · Views: 2,248
  • gnu_parted.zip
    2.9 MB · Views: 1,943
Last edited:

neldar

Retired Recognized Developer
Jul 4, 2010
569
363
twitter.com
@dkcldark: good job. nice pictures. :)



Thats what i do to extract initramfs, basically the same. But i have added instructions to extract from kernels compiled by kernel devs here at xda.
(kernels with gzipped cpio)

Uncompressing the zImage:
$ grep -a -b --only-matching $'\x1f\x8b\x08\x00' < zImage
12896:�
$ dd if=zImage bs=1 skip={number from above command} | zcat - > Image

if not gzipped cpio (this one for stock-samsung-kernel):
$ grep -a -b --only-matching '070701' Image
$ dd if=Image bs=1 skip={your first matching number from line above} > initramfs.cpio
else if cpio is gzipped:
$ grep -a -b --only-matching $'\x1f\x8b\x08' < Image
84448:�
2639420:�
Only the first number is interesting, so we can fetch the initramfs:
$ dd if=Image bs=1 skip={your first number, in my case 84448} | gzip -d -c - > initramfs.cpio

Now extract initramfs.cpio:
$ mkdir somedirtoextract
$ cd somedirtoextract/
$ cpio -i --no-absolute-filenames < ../initramfs.cpio

If you want to have device nodes created, make sure you do it as root:
sudo cpio -i --no-absolute-filenames < ../initramfs.cpio
 
Last edited:
  • Like
Reactions: Joeseph Mother

husq510

Senior Member
Jul 6, 2010
71
3
wondewring if theres a way to change this:

c002e660 T __initramfs_start
c035d949 T __initramfs_end
 

FadeFx

Senior Member
Mar 22, 2010
8,838
3,034
Vienna
hi dkcldark, as i sayed i try to do this with the kernel from i5800 galaxy3, but ran into first problem after saving the image-orig.gz, i get a gz filke with a file image-orig with 0 bytes size and extracting results in an error.
hope you can somehow help me. like i sayed already, i am not really used to such blackbelt stuff, just trying to get a working lagfix for the g3
 

dkcldark

Senior Member
Jul 3, 2010
105
442
hi dkcldark, as i sayed i try to do this with the kernel from i5800 galaxy3, but ran into first problem after saving the image-orig.gz, i get a gz filke with a file image-orig with 0 bytes size and extracting results in an error.
hope you can somehow help me. like i sayed already, i am not really used to such blackbelt stuff, just trying to get a working lagfix for the g3


hello would you give me the kernel file please?
I'll have a look and give you an instruction :D
 

xan

Retired Recognized Developer
May 21, 2006
1,407
455
Crack-ow
As far I understand this method -> Could we have JPK's kernel initramfs repacked in similar manner, to include EXT2/4 support?
 

a-son

Senior Member
Aug 17, 2008
183
11
Tierra del norte
www.softdevs.se
Hello.

dkcldark & neldar , What a great work you ´have done!

Unfortunately im lost at the point when to create the Image.

I followed neldar´s instructions to expand zImage to Image and
My files are extracted from JPK kernel and i have edit some files.


What to do?
 

jodue

Senior Member
Dec 15, 2009
453
37
vienna
As far I understand this method -> Could we have JPK's kernel initramfs repacked in similar manner, to include EXT2/4 support?

ext2 support is (most likely) already in the kernel. the problem with adding ext4 is that we don't have a ext4 module compatible with this kernel and no source (yet) to compile one ... so we have to wait for samsung to release the source ...

@dkcldark, neldar ... awesome tutorials, thanks! :)
 
Last edited:

ttabbal

Senior Member
Jul 1, 2009
2,076
723
Samsung Galaxy S21 Ultra
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. :)

Code:
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();

	}
 
Last edited:

xan

Retired Recognized Developer
May 21, 2006
1,407
455
Crack-ow
ext2 support is (most likely) already in the kernel. the problem with adding ext4 is that we don't have a ext4 module compatible with this kernel and no source (yet) to compile one ... so we have to wait for samsung to release the source ...

@dkcldark, neldar ... awesome tutorials, thanks! :)

I am perfectly happy with either EXT2/4 (no comments here).
 

sharetop

Member
Oct 20, 2005
16
0
can you tell me how to unpack the factoryfs.rfs ?

I grep the '1F8B0B' and cut the bytes (between '1F8B0B' and 'another 1F8B0B') to a file,,,,a.img,,,,then gunzip it,,,but console println " gzip: a.img is encrypted -- not supported "

why?
 
Last edited:

ttabbal

Senior Member
Jul 1, 2009
2,076
723
Samsung Galaxy S21 Ultra
can you tell me how to unpack the factoryfs.rfs ?

I grep the '1F8B0B' and cut the bytes (between '1F8B0B' and 'another 1F8B0B') to a file,,,,a.img,,,,then gunzip it,,,but console println " gzip: a.img is encrypted -- not supported "

why?


That's a filesystem image for the /system partition IIRC. I have used it on my phone via a loopback mount, but you can't extract stuff from it using this method. This is for zImage files.
 

sztupy

Inactive Recognized Developer
Dec 21, 2008
1,061
877
Edinburgh
sztupy.hu
can you tell me how to unpack the factoryfs.rfs ?

I grep the '1F8B0B' and cut the bytes (between '1F8B0B' and 'another 1F8B0B') to a file,,,,a.img,,,,then gunzip it,,,but console println " gzip: a.img is encrypted -- not supported "

why?

You can't. The easiest way to unpack factory.rfs (if you don't have linux) is to copy it to your phone, mount it in a directory using a loopback device, and copy everything from it to another directory on your sdcard.
 

sharetop

Member
Oct 20, 2005
16
0
thank you. If i have a linux system, can i copy the .rfs to ubuntu, then mount it as a virtual device?
 

Top Liked Posts

  • There are no posts matching your filters.
  • 10
    Here we go.

    I'm saying that I'm not a very good developer so this information could be messy, contain unnecessary works or a bit wrong.
    And also I'm not sure if this method will work with every zImage from every device.

    I've tested with
    I9000-JM2/JM7 : ECLAIR
    JPC : FROYO
    and they work like a charm.

    OK, now we start.

    Download this file

    http://www.multiupload.com/GSVLO15WDL

    It has cross-compiler in it so that it's slightly big.

    ------------------------------------------------------------

    This is basically for devs so I won't tell you specifically. (or I can't...maybe)



    1. Extract cpio'ed initramfs file from zImage.

    ## EDIT : In order to extract initramfs.cpio, go through from step4 to step11.
    A file which starts with "30 37 30" means that this is a cpio'ed file.
    So, trim the Image-Orig file from the beginning to the point just before "30" then, you've got a cpio compressed file.
    You can now simply decompress it.

    cat initramfs.cpio | cpio -i --no-absolute-filenames



    2. Decompress and edit these files. Make sure you shouldn't go over the original size. (simply, I removed redbend_ua in /sbin forder)
    3. Recompress to cpio. ( I've used scripts/gen_initramfs_list.sh which is in the kernel source for a safe bet)

    ## EDIT : What I've done is here. chdir to "zImage_repack/2.6.29" forder then

    /bin/bash scripts/gen_initramfs_list.sh -o usr/initramfs_data.cpio -u 0 -g 0 /home/zero/Desktop/JPC/initramfs/i9000_initramfs_list







    4. open the zImage with a hexeditor.
    5. find "1f 8b 08".
    6. cut off from the beginning to the point just before the "1f" so that this file begins with "1f 8b 08".
    7. save as anyname.gz
    8. in terminal >>>> gunzip anyname.gz

    Now, you've got an Image file. I'll call this as an Image-Orig.

    9. open the Image-Orig file with a hexeditor.
    10. remember the entire size of this file. One of mine was "0xb9a5df".
    11. find "30 37 30" hexademical code and "TRAILER!!!" text.
    12. cut off from the first "30" to the last "!".
    an example is here
    111vl.png



    13. open the cpio file you had recompressed with the hexeditor.
    14. paste this codes to the exactly same place where the former initramfs was, in Image-Origin file. (Up to now, I feel like English is more difficult than this trick...sigh, sorry for my bad english!)
    15. Almost done. We're gonna make the modified Image file's size identically to the Image-Orig. It's simple. just fill the hole with a bunch of NULLs. put your finger on "0" button and have a little sleep.


    I think I need a visual assistant.


    88509078.png



    76205972.png



    36302789.png



    61057337.png



    77523285.png



    10411681.png



    91666980.png


    Save it as "Image".


    At this point, you should have an Image file which size is the same as Image-Orig.


    Now open the file you've downloaded at the first.

    there is a forder called place_Image_here

    yeah, place the Image there and execute the "Repack_kernel.sh" file.

    In several seconds, you'll have a zImage file.

    I'm so tired and I can't last this writing so, if you have any question, I'll give you a reply.

    Thanks!




    ## PLUS : I've attached the modified JPC kernel which supports /system/etc/init.d/userscripts.sh

    It's named JPC_modified_kernel.tar.zip and you should take the ".zip" off in order to use with Odin.

    ## PLUS2 : I've compiled gnu_parted! also attached. good luck, RyanZA!
    -info : GNU parted v2.2 (original version, didn't apply bug fixes.)
    disabled device-mapper and read-line while compiling, does this matter?



    parted.jpg



    partprobe.jpg
    1
    ...Wow.

    Good job, sir. Good job. :D

    1. Extract cpio'ed initramfs file from zImage.

    I mostly followed along through the later steps and I don't see any issues, but unfortunately the first step leaves me clueless. How would you do that?! :D
    1
    @dkcldark: good job. nice pictures. :)



    Thats what i do to extract initramfs, basically the same. But i have added instructions to extract from kernels compiled by kernel devs here at xda.
    (kernels with gzipped cpio)

    Uncompressing the zImage:
    $ grep -a -b --only-matching $'\x1f\x8b\x08\x00' < zImage
    12896:�
    $ dd if=zImage bs=1 skip={number from above command} | zcat - > Image

    if not gzipped cpio (this one for stock-samsung-kernel):
    $ grep -a -b --only-matching '070701' Image
    $ dd if=Image bs=1 skip={your first matching number from line above} > initramfs.cpio
    else if cpio is gzipped:
    $ grep -a -b --only-matching $'\x1f\x8b\x08' < Image
    84448:�
    2639420:�
    Only the first number is interesting, so we can fetch the initramfs:
    $ dd if=Image bs=1 skip={your first number, in my case 84448} | gzip -d -c - > initramfs.cpio

    Now extract initramfs.cpio:
    $ mkdir somedirtoextract
    $ cd somedirtoextract/
    $ cpio -i --no-absolute-filenames < ../initramfs.cpio

    If you want to have device nodes created, make sure you do it as root:
    sudo cpio -i --no-absolute-filenames < ../initramfs.cpio
    1
    I've compiled a short page about extracting initramfs some time ago here: http://xdaforums.com/wiki/index.php?title=Extract_initramfs_from_zImage
    (also accessible from the SGS wiki page).

    Please feel free to extend this page with more instructions / scripts on how also re-pack it back.