[script] repack-zImage.sh: Unpack and repack a zImage without kernel source, V. 5

Search This thread

mizch

Senior Member
Nov 11, 2010
158
79
repack-zImage.sh is a bash script for Linux which allows you to unpack a kernel image (zImage) for modification and repack it afterwards into a new working kernel image.

You don't need a kernel tree for this program nor a compiler. It should work with any zImage that contains an initramfs, for whatever phone, operating system or CPU architecture you like.

My main purpose when I wrote it was to modify the initramfs of leaked Samsung i5800 firmware for which no kernel source is available.

Usage:
=====

Put the unzipped script into some directory along your $PATH (e.g., /usr/local/bin). Put the unpacked files from initramfs_utils.zip into /usr/local/bin.

Then simply run 'repack-zImage.sh -u' with your zImage in the current directory and it will create a directory named 'zImage_unpacked' which contains the unpacked blocks of your zImage. Refer to the comments near the start of the program to identify which file corresponds to which fragment of the original zImage. (The file name of the zImage should be "zImage". If it isn't, pass it as the only non-option argument. The subdirectory's name will change accordingly.)

Most notably, there will be a directory 'initramfs' in there, which contains all files from the original initramfs in their original tree. You can modify the contents as you like, but keep in mind that your initramfs cannot grow larger than the space reserved for it in the original zImage. So you're restricted to relatively small changes which should, however, satisfy many needs. You always can call a script or executable on some other partition (including the SD card if already mounted) if you need more room for your modifications.

After your modifications are done, cd back to the directory which contains zImage and zImage_unpacked and run 'repack-zImage.sh -p' to start the packing process.

This will create a directory called 'zImage_packing' which contains your new zImage (and a zImage.tar for loaders like ODIN). It will emit (between others) one or two messages about a padding being done and about how many bytes were padded. This number (or the lower number of the two) is an indication about how many compressed bytes are left for further additions to the initrd.

If your initramfs (or some other modified part) grows too large, the script will abort with an appropriate error message.

In initramfs-utils.zip, three programs are provided. They should be copied to /usr/local/bin:
* cpio_set0. This is a slightly modified cpio (compiled for 32 bit Linux). repack-zImage.sh will run without it, but there may be slightly more room in your initramfs if you use the modified one. It sets all file times in the archive to 0 (epoch), thus yielding better and consistent compression results. Else, the size of the compressed initramfs will differ from invocation to invocation due to differing atimes. Put it somewhere along your $PATH (e.g., /usr/local/bin).
* gen_init_cpio and
* gen_initramfs_list.sh. These are utilities copied from a kernel tree and used to support creation of an initramfs (in certain modes).

'repack-zImage.sh --help' will output usage information.


Happy hacking,

mizch


Current Version: 6
2011-05-03
('repack-zImage.sh --version' will output version information.)

- added support for lzma compressed ramdisks (both directions)

Version 4
2011-02-17

- Workaround for ambiguous gunzip result, see post #20
- Some code cleanup + CLI cleanup
- better error detection

Version 3
2011-01-06

- now also works with unzipped initramfs withing gzipped zImage part (i.e., all kinds of zImages)

Version 1
2011-01-05

- initial version. Works only for gzipped initramfs within gzipped zImage (e.g., G3 Eclair kernels)

-----------------------
repack-zImage.zip contains version 4 of the script.
For the newest version, download repack-zImage.v6.zip and initramfs-utils.zip.
 

Attachments

  • initramfs-utils.zip
    176.2 KB · Views: 15,474
  • repack-zImage.zip
    7.4 KB · Views: 8,879
  • repack-zImage.v6.zip
    7.9 KB · Views: 19,617
Last edited:

Gsam101

Senior Member
Oct 13, 2010
266
97
Paris
It didn't work on zImage from Froyo firmware i tried. Great work however :).

Works however for Eclair firmwares i've tested.
 
Last edited:

precurse

Senior Member
Aug 26, 2010
179
21
Good work.

Is this based off the i9000 script?

Also, I've noticed with the i5800 Eclair firmwares that the initramfs is gzipped AND cpio'd. So... Kernel + initramfs.cpio.gz are gzipped together.

Basically you need to extract [kernel+initramfs.cpio.gz].gz, extract initramfs.cpio.gz again, then extract initramfs with cpio.

On Froyo, the kernel + initramfs.cpio is gzipped together, but nothing more. So after you extract the kernel and initramfs, you just need to extract with cpio after that.

Hope that kind of helps..
 

mizch

Senior Member
Nov 11, 2010
158
79
In didn't go into Froyo for the i5800 until now. I used Eclair. It eases testing if you can compare things to a working kernel tree.

I see that Froyo doesn't use a compressed initramfs within the compressed kernel (which I doubt to make much sense anyway since compressing an already compressed part again is likely to produce a larger result). In theory, thus Froyo is easier to cope with than what I have now, but I have to write the code to handle it. This will need some time, maybe tomorrow, maybe the weekend.

And, no, this is not based on code from the i9000. It was written up from scratch. But I took some ideas from there and thank dkcldark for his good work.
 
Last edited:
  • Like
Reactions: forest1971

precurse

Senior Member
Aug 26, 2010
179
21
In didn't go into Froyo for the i5800 until now. I used Eclair. It eases testing if you can compare things to a working kernel tree.

I see that Froyo doesn't use a compressed initramfs within the compressed kernel (which I doubt to make much sense anyway since compressing an already compressed part again is likely to produce a larger result). In theory, thus Froyo is easier to cope with than what I have now, but I have to write the code to handle it. This will need some time, maybe tomorrow, maybe the weekend.

And, no, this is not based on code from the i9000. It was written up from scratch. But I took some ideas from there and thank dkcldark for his good work.

If we can get this modified for Froyo, it will allow for native ext2 mounting within the initramfs. Then we can add things to it like the way CWM works - busybox, adb, etc... So that we have a recovery adb setup before /system mounts.
 

Gsam101

Senior Member
Oct 13, 2010
266
97
Paris
If we can get this modified for Froyo, it will allow for native ext2 mounting within the initramfs. Then we can add things to it like the way CWM works - busybox, adb, etc... So that we have a recovery adb setup before /system mounts.
Exactly, that could be very useful, since we could get ext2 (ext4 maybe if we compile it as a module ?) in /data natively :)
 

precurse

Senior Member
Aug 26, 2010
179
21
Exactly, that could be very useful, since we could get ext2 (ext4 maybe if we compile it as a module ?) in /data natively :)

I already tried building ext4 and other modules off the i9000 sources... Didn't seem to work too well. Kept complaining about memmap or some random errors when I tried loading them.

Perhaps we can try them against JPF or something.
 

precurse

Senior Member
Aug 26, 2010
179
21
Heck.. or even allow a user to use a file off their SD card to loopback mount /system partitions... Or /data partitions - like how the i9000 has a (built-in) 16gb SD card.
 

Gsam101

Senior Member
Oct 13, 2010
266
97
Paris
I already tried building ext4 and other modules off the i9000 sources... Didn't seem to work too well. Kept complaining about memmap or some random errors when I tried loading them.

Perhaps we can try them against JPF or something.
I think so. Maybe we should just try to build an ext4 module with standard linux sources with armv6 as target ? Since i9000 has an armv7 processor..
 

precurse

Senior Member
Aug 26, 2010
179
21
I think so. Maybe we should just try to build an ext4 module with standard linux sources with armv6 as target ? Since i9000 has an armv7 processor..

I setup my .conf to use the same CPU as what the G3 uses. I can't compile a kernel, but the modules compile.

It's a much different error I got from these modules than when I tried loading i9000 modules.
 

FadeFx

Senior Member
Mar 22, 2010
8,838
3,034
Vienna
Heck.. or even allow a user to use a file off their SD card to loopback mount /system partitions... Or /data partitions - like how the i9000 has a (built-in) 16gb SD card.
Don't forget the internal SD of the sgs is on fast movienand SD memory, if one would loop back to his sdcard he would have to have a class 10 sdcard at least to get decent speed out of it.
 

mizch

Senior Member
Nov 11, 2010
158
79
I've posted a new version of repack-zImage.sh and the associated utilities in the first article of this thread. This version lifts the restriction which until now allowed only compressed initramfs disks. Now uncompressed ones are also supported.

This modification got somewhat tricky, as a newly created initramfs, when compressed, yields sizes different from the original (even if it contains exactly the same files) due to different ordering of the files. For a 2 MB ramdisk, a difference of 3k may not sound like much, but it is - if it is too large by this number in a zImage where the initramfs must fit into the original's room.

Some black magic was needed. Now the files are ordered like in the original, with additional files (if created by the user) appended at the end. Options are provided to change the optimisations if needed.

I tried with JPF and with JPA-custom, so changes are really good that you won't have to bother with the above and can just go ahead and do your own initramfs modifications.
 

spdwiz18

Senior Member
have we (you all) found a way to unpack the froyo zimage yet? it worked great on eclair. thank you. and thanks for any help that you might provide.

i have tried on froyo for the epic but as it is unpacking it keeps looping 2 sets of numbers when i run the script. 5748017 5749018 and keeps repeating. any help would be great.
 
Last edited:

coolzarjun

Senior Member
Oct 24, 2010
377
33
New Delhi
/Data and /cache ext2 conversion script.

Exactly, that could be very useful, since we could get ext2 (ext4 maybe if we compile it as a module ?) in /data natively :)

hey here's a script that converts /data and /cache to ext2... i tried it.. worked for me.. i did not made this.. !
this is the work of MOTAFOCA !
quadarant score went from 305 to 515 and the best part.. internal memory shrunk from 176Mb to 161 Mb only :D
the script says its for i5508 but was made for 5800 as said by barquers

anyways.. here's the script.. hoping it will help :)

http://multiupload.com/O2ET4B8K0A

PS: im using MOTAFOCA's ROM... and script was made by MOTAFOCA not me :)
 

mizch

Senior Member
Nov 11, 2010
158
79
i have tried on froyo for the epic but as it is unpacking it keeps looping 2 sets of numbers when i run the script. 5748017 5749018 and keeps repeating. any help would be great.

It should work for any zImage. Sounds like a bug in the end detection for a compressed part. Can you provide me with a link to the zImage or contact me directly (PM/E-Mail) to pass me a copy? Then I'll go into it.
 
Last edited:

coolzarjun

Senior Member
Oct 24, 2010
377
33
New Delhi
hey. does the script allows us to tweak the kernel so that it can be overclocked? ??
or we still need to wait for the kernel sources?
 

mizch

Senior Member
Nov 11, 2010
158
79
Got the zImage, thanks. I could reproduce the problem. What happens:

Using gzip's magic number, I can tell the start of a gzipped section. To determine its end, I need the help of gunzip. It reports "trailing garbage" if its file is too long, "truncated file" if too small, "OK" otherwise.

With your zImage, gunzip reports "truncated" when fed with 5749017 bytes, "trailing garbage" at 5749018. Obviously, only one of the two (not both!) can be correct. But this is what gunzip reports in your case. I found that 5749016 is the correct size. Erm.

As a workaround, I now detect when the gunzip result is oscillating this way and if it does, I search nearby towards lower size values for an exact match. This is not an ideal solution but I have to deal with what gunzip returns and this fits it best.

I'll do some cleanup and some final tests now and if they succeed, I will post the new version in about an hour or so in the first posting of this thread.

EDIT: New version posted.
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 36
    repack-zImage.sh is a bash script for Linux which allows you to unpack a kernel image (zImage) for modification and repack it afterwards into a new working kernel image.

    You don't need a kernel tree for this program nor a compiler. It should work with any zImage that contains an initramfs, for whatever phone, operating system or CPU architecture you like.

    My main purpose when I wrote it was to modify the initramfs of leaked Samsung i5800 firmware for which no kernel source is available.

    Usage:
    =====

    Put the unzipped script into some directory along your $PATH (e.g., /usr/local/bin). Put the unpacked files from initramfs_utils.zip into /usr/local/bin.

    Then simply run 'repack-zImage.sh -u' with your zImage in the current directory and it will create a directory named 'zImage_unpacked' which contains the unpacked blocks of your zImage. Refer to the comments near the start of the program to identify which file corresponds to which fragment of the original zImage. (The file name of the zImage should be "zImage". If it isn't, pass it as the only non-option argument. The subdirectory's name will change accordingly.)

    Most notably, there will be a directory 'initramfs' in there, which contains all files from the original initramfs in their original tree. You can modify the contents as you like, but keep in mind that your initramfs cannot grow larger than the space reserved for it in the original zImage. So you're restricted to relatively small changes which should, however, satisfy many needs. You always can call a script or executable on some other partition (including the SD card if already mounted) if you need more room for your modifications.

    After your modifications are done, cd back to the directory which contains zImage and zImage_unpacked and run 'repack-zImage.sh -p' to start the packing process.

    This will create a directory called 'zImage_packing' which contains your new zImage (and a zImage.tar for loaders like ODIN). It will emit (between others) one or two messages about a padding being done and about how many bytes were padded. This number (or the lower number of the two) is an indication about how many compressed bytes are left for further additions to the initrd.

    If your initramfs (or some other modified part) grows too large, the script will abort with an appropriate error message.

    In initramfs-utils.zip, three programs are provided. They should be copied to /usr/local/bin:
    * cpio_set0. This is a slightly modified cpio (compiled for 32 bit Linux). repack-zImage.sh will run without it, but there may be slightly more room in your initramfs if you use the modified one. It sets all file times in the archive to 0 (epoch), thus yielding better and consistent compression results. Else, the size of the compressed initramfs will differ from invocation to invocation due to differing atimes. Put it somewhere along your $PATH (e.g., /usr/local/bin).
    * gen_init_cpio and
    * gen_initramfs_list.sh. These are utilities copied from a kernel tree and used to support creation of an initramfs (in certain modes).

    'repack-zImage.sh --help' will output usage information.


    Happy hacking,

    mizch


    Current Version: 6
    2011-05-03
    ('repack-zImage.sh --version' will output version information.)

    - added support for lzma compressed ramdisks (both directions)

    Version 4
    2011-02-17

    - Workaround for ambiguous gunzip result, see post #20
    - Some code cleanup + CLI cleanup
    - better error detection

    Version 3
    2011-01-06

    - now also works with unzipped initramfs withing gzipped zImage part (i.e., all kinds of zImages)

    Version 1
    2011-01-05

    - initial version. Works only for gzipped initramfs within gzipped zImage (e.g., G3 Eclair kernels)

    -----------------------
    repack-zImage.zip contains version 4 of the script.
    For the newest version, download repack-zImage.v6.zip and initramfs-utils.zip.
    3
    Good work.

    Is this based off the i9000 script?

    Also, I've noticed with the i5800 Eclair firmwares that the initramfs is gzipped AND cpio'd. So... Kernel + initramfs.cpio.gz are gzipped together.

    Basically you need to extract [kernel+initramfs.cpio.gz].gz, extract initramfs.cpio.gz again, then extract initramfs with cpio.

    On Froyo, the kernel + initramfs.cpio is gzipped together, but nothing more. So after you extract the kernel and initramfs, you just need to extract with cpio after that.

    Hope that kind of helps..
    3
    repack-zImage.sh is a bash script for Linux which allows you to unpack a kernel image (zImage) for modification and repack it afterwards into a new working kernel image.

    You don't need a kernel tree for this program nor a compiler. It should work with any zImage that contains an initramfs, for whatever phone, operating system or CPU architecture you like.

    My main purpose when I wrote it was to modify the initramfs of leaked Samsung i5800 firmware for which no kernel source is available.

    Usage:
    =====

    Put the unzipped script into some directory along your $PATH (e.g., /usr/local/bin). Put the unpacked files from initramfs_utils.zip into /usr/local/bin.

    Then simply run 'repack-zImage.sh -u' with your zImage in the current directory and it will create a directory named 'zImage_unpacked' which contains the unpacked blocks of your zImage. Refer to the comments near the start of the program to identify which file corresponds to which fragment of the original zImage. (The file name of the zImage should be "zImage". If it isn't, pass it as the only non-option argument. The subdirectory's name will change accordingly.)

    Most notably, there will be a directory 'initramfs' in there, which contains all files from the original initramfs in their original tree. You can modify the contents as you like, but keep in mind that your initramfs cannot grow larger than the space reserved for it in the original zImage. So you're restricted to relatively small changes which should, however, satisfy many needs. You always can call a script or executable on some other partition (including the SD card if already mounted) if you need more room for your modifications.

    After your modifications are done, cd back to the directory which contains zImage and zImage_unpacked and run 'repack-zImage.sh -p' to start the packing process.

    This will create a directory called 'zImage_packing' which contains your new zImage (and a zImage.tar for loaders like ODIN). It will emit (between others) one or two messages about a padding being done and about how many bytes were padded. This number (or the lower number of the two) is an indication about how many compressed bytes are left for further additions to the initrd.

    If your initramfs (or some other modified part) grows too large, the script will abort with an appropriate error message.

    In initramfs-utils.zip, three programs are provided. They should be copied to /usr/local/bin:
    * cpio_set0. This is a slightly modified cpio (compiled for 32 bit Linux). repack-zImage.sh will run without it, but there may be slightly more room in your initramfs if you use the modified one. It sets all file times in the archive to 0 (epoch), thus yielding better and consistent compression results. Else, the size of the compressed initramfs will differ from invocation to invocation due to differing atimes. Put it somewhere along your $PATH (e.g., /usr/local/bin).
    * gen_init_cpio and
    * gen_initramfs_list.sh. These are utilities copied from a kernel tree and used to support creation of an initramfs (in certain modes).

    'repack-zImage.sh --help' will output usage information.


    Happy hacking,

    mizch


    Current Version: 6
    2011-05-03
    ('repack-zImage.sh --version' will output version information.)

    - added support for lzma compressed ramdisks (both directions)

    Version 4
    2011-02-17

    - Workaround for ambiguous gunzip result, see post #20
    - Some code cleanup + CLI cleanup
    - better error detection

    Version 3
    2011-01-06

    - now also works with unzipped initramfs withing gzipped zImage part (i.e., all kinds of zImages)

    Version 1
    2011-01-05

    - initial version. Works only for gzipped initramfs within gzipped zImage (e.g., G3 Eclair kernels)

    -----------------------
    repack-zImage.zip contains version 4 of the script.
    For the newest version, download repack-zImage.v6.zip and initramfs-utils.zip.

    Thank you for this utility. I've taken the liberty of making a couple of bugfixes - one to initialise compress_list in the -3 option case, and the other to initialise at_min to 0 rather than blank in gunzipWithTrailer. The first stops the -3 option hanging, and the second is cosmetic and prevents sh complaining.

    I can confirm it works with zImage 4.0.4 XWLPT for the Samsung Galaxy S II (i9100).

    Peter
    3
    I'm assuming this tool is dead, as I get same errors as last posters and seems no one can post the cause
    try following the same steps i've given in my kernel development tutorials and you shouldnt get any errors...
    2
    Got the zImage, thanks. I could reproduce the problem. What happens:

    Using gzip's magic number, I can tell the start of a gzipped section. To determine its end, I need the help of gunzip. It reports "trailing garbage" if its file is too long, "truncated file" if too small, "OK" otherwise.

    With your zImage, gunzip reports "truncated" when fed with 5749017 bytes, "trailing garbage" at 5749018. Obviously, only one of the two (not both!) can be correct. But this is what gunzip reports in your case. I found that 5749016 is the correct size. Erm.

    As a workaround, I now detect when the gunzip result is oscillating this way and if it does, I search nearby towards lower size values for an exact match. This is not an ideal solution but I have to deal with what gunzip returns and this fits it best.

    I'll do some cleanup and some final tests now and if they succeed, I will post the new version in about an hour or so in the first posting of this thread.

    EDIT: New version posted.