Please remember to add a category to the bottom of each page that you create.
See categories help for further details, but most will probably be [[Category:HTC ModelName]].
Extract initramfs from zImage
initramfs provides the rootfs when booting a Linux kernel on a mobile device.
Below script may be helpful if you are interested in extracting such an image from a zImage kernel file.
Tested on Ubuntu for Samsung Galaxy S firmware. Other zImages may have different archiving options - would require a modification to the script...
#!/bin/bash
zImage=$1
#========================================================
# find start of gziped kernel object in the zImage file:
#========================================================
pos=`grep -P -a -b -m 1 --only-matching $'\x1F\x8B\x08' $zImage | cut -f 1 -d :`
echo "-I- Extracting kernel image from $zImage (start = $pos)"
#========================================================================
# the cpio archive might be gzipped too, so two gunzips could be needed:
#========================================================================
dd if=$zImage bs=1 skip=$pos | gunzip > /tmp/kernel.img
pos=`grep -P -a -b -m 1 --only-matching $'\x1F\x8B\x08' /tmp/kernel.img | cut -f 1 -d :`
#===========================================================================
# find start and end of the "cpio" initramfs image inside the kernel object:
# ASCII cpio header starts with '070701'
# The end of the cpio archive is marked with an empty file named TRAILER!!!
#===========================================================================
if [ ! $pos = "" ]; then
echo "-I- Extracting compressed cpio image from kernel image (start = $pos)"
dd if=/tmp/kernel.img bs=1 skip=$pos | gunzip > /tmp/cpio.img
start=`grep -a -b -m 1 --only-matching '070701' /tmp/cpio.img | head -1 | cut -f 1 -d :`
end=`grep -a -b -m 1 --only-matching 'TRAILER!!!' /tmp/cpio.img | head -1 | cut -f 1 -d :`
inputfile=/tmp/cpio.img
else
echo "-I- Already uncompressed cpio.img, not decompressing"
start=`grep -a -b -m 1 --only-matching '070701' /tmp/kernel.img | head -1 | cut -f 1 -d :`
end=`grep -a -b -m 1 --only-matching 'TRAILER!!!' /tmp/kernel.img | head -1 | cut -f 1 -d :`
inputfile=/tmp/kernel.img
fi
# 11 bytes = length of TRAILER!!! zero terminated string, fixes premature end of file warning in CPIO
end=$((end + 11))
count=$((end - start))
if (($count < 0)); then
echo "-E- Couldn't match start/end of the initramfs image."
exit
fi
echo "-I- Extracting initramfs image from $inputfile (start = $start, end = $end)"
dd if=$inputfile bs=1 skip=$start count=$count > initramfs.cpio
After extracting the initramfs, it can be unpacked into the local directory with
cpio -v -i --no-absolute-filenames < <path-to-initramfs.img>
Note that, to the best of my knowledge, it is impossible (or maybe unreasonably difficult) to re-pack a modified initramfs image into existing zImage - the data is linked into the kernel object by the compiler with corresponding pointers to start/end initialized in the code. So the easiest way of modifying initramfs also requires recompiling the whole kernel from source.
Here are instructions on how to do it (assuming the new initramfs size is less or equal to the old one): http://forum.xda-developers.com/showthread.php?t=777380
for lzma compressed initramfs, this seems to work reasonably well for the second grep:
grep -P -a -b -m 1 --only-matching '\x{5D}\x{00}\x..\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}' /tmp/kernel.img
The simple magic number alone isn't enough but a couple of numbers after it are variable (describe compression options).. the FF's seem pretty robust, but just from looking at a few examples, not from studying lzma specs, so no promises. Of course you'd need to change the decompression command too inside the conditional.
For initramfs's modified by z4build (z4mod) some initramfs files are brute force stuck in a tar at the end of the zImage and unpacked early in the init script. To unpack the whole thing you need to do something like (basically taken from the z4build init wrapper script itself):
offset="`dd if=$zImagefile bs=4 skip=11 count=1 2>/dev/null | od -l|tr -s " "|head -n 1|cut -f2 -d " "`" offset=`echo $offset | cut -f 2 -d" "` dd if=$zImagefile bs=$offset skip=1 | tar xz normal_extraction_script.sh $zImagefile
If you get problems with the above script also have a look at this improved version: https://github.com/mistadman/Extract-Kernel-Initramfs