If you are interested in building your own kernels (from the Samsung-released open-source code, or any other source), you may need to extract initramfs ramdiscs from existing kernels.
There is a well-known script to achieve that goal, but it only supports uncompressed and gzip'ed kernels, and it doesn't unpack the CPIO archive for further inspection of the actual initramfs "source code" (the output trace is also not easy to debug when working with "weird" zImages). The original script is explained in the XDA wiki: http://forum.xda-developers.com/wiki/index.php?title=Extract_initramfs_from_zImage.
For my personal convenience, I tweaked the original bash script so I thought I'd share it with the XDA devs. I added support for lzma-compressed initramfs ramdiscs (thanks to koxudaxi for reminding me of the lzma "magic string"), please let me know if you know the "magic string" for bzip2 archives (EDIT: "0x314159265359" 6 bytes "start of block", 4 bytes header at the beginning...experimental untested support is now available in the script below).
Note that the latest Samfirmware ROMs include encrypted boot.bin and Sbl.bin bootloaders, but I'm not sure how the zImage kernels are encoded...so this script may not work.
Also note that zImage files patched with z4mod require further decoding work, see the XDA wiki page mentioned above for instructions.
There is a well-known script to achieve that goal, but it only supports uncompressed and gzip'ed kernels, and it doesn't unpack the CPIO archive for further inspection of the actual initramfs "source code" (the output trace is also not easy to debug when working with "weird" zImages). The original script is explained in the XDA wiki: http://forum.xda-developers.com/wiki/index.php?title=Extract_initramfs_from_zImage.
For my personal convenience, I tweaked the original bash script so I thought I'd share it with the XDA devs. I added support for lzma-compressed initramfs ramdiscs (thanks to koxudaxi for reminding me of the lzma "magic string"), please let me know if you know the "magic string" for bzip2 archives (EDIT: "0x314159265359" 6 bytes "start of block", 4 bytes header at the beginning...experimental untested support is now available in the script below).
Note that the latest Samfirmware ROMs include encrypted boot.bin and Sbl.bin bootloaders, but I'm not sure how the zImage kernels are encoded...so this script may not work.
Also note that zImage files patched with z4mod require further decoding work, see the XDA wiki page mentioned above for instructions.
Code:
#!/bin/bash
zImage=$1
read -rp "Enter any text to skip extraction (assumes /tmp/kernel2.img already exists): " input
if [ ${input}" " = " " ]; then
echo "==> deleting /tmp/kernel1.img"
rm /tmp/kernel1.img
echo "==> deleting /tmp/kernel2.img"
rm /tmp/kernel2.img
echo "==> searching for gzip header in $zImage"
skip=`grep -P -a -b -m 1 --only-matching $'\x1F\x8B\x08' $zImage | cut -f 1 -d :`
echo "==> found gzip header at $skip"
echo "==> unzipping $zImage to /tmp/kernel1.img"
dd if=$zImage bs=1 skip=$skip | gunzip > /tmp/kernel1.img
echo "==> searching for gzip header in /tmp/kernel1.img"
poszip=`grep -P -a -b -m 1 --only-matching $'\x1F\x8B\x08' /tmp/kernel1.img | cut -f 1 -d :`
if [ ! $poszip = "" ]; then
echo "==> gzip header at $poszip in /tmp/kernel1.img"
echo "==> extracting /tmp/kernel2.img from /tmp/kernel1.img using gunzip"
dd if=/tmp/kernel1.img bs=1 skip=$poszip | gunzip > /tmp/kernel2.img
else
echo "==> no gzip header in /tmp/kernel1.img"
echo "==> searching for lzma header in /tmp/kernel1.img"
poslzma=`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/kernel1.img | cut -f 1 -d :`
if [ ! $poslzma = "" ]; then
echo "==> lzma header at $poslzma in /tmp/kernel1.img"
echo "==> extracting /tmp/kernel2.img from /tmp/kernel1.img using lzma"
dd if=/tmp/kernel1.img bs=1 skip=$poslzma | unlzma > /tmp/kernel2.img
else
echo "==> no lzma header in /tmp/kernel1.img"
echo "==> searching for bzip2 header in /tmp/kernel1.img"
posbzip2=`grep -P -a -b -m 1 --only-matching $'\x{42}\x{5A}\x{68}\x{39}\x{31}\x{41}\x{59}\x{26}\ x{53}\x{59}' /tmp/kernel1.img | cut -f 1 -d :`
if [ ! $posbzip2 = "" ]; then
echo "==> bzip2 header at $posbzip2 in /tmp/kernel1.img"
posbzip2=$((posbzip2 - 4))
echo "==> adjusted bzip2 header with -4 bytes offset: $posbzip2"
echo "==> extracting /tmp/kernel2.img from /tmp/kernel1.img using bzip2"
dd if=/tmp/kernel1.img bs=1 skip=$posbzip2 | bunzip2 > /tmp/kernel2.img
else
echo "==> no bzip2 header in /tmp/kernel1.img"
echo "==> assuming no compression for /tmp/kernel1.img, copying to /tmp/kernel2.img"
cp /tmp/kernel1.img /tmp/kernel2.img
fi
fi
fi
fi
# '070701' == $'\x30\x37\x30' == '\x{30}\x{37}\x{30}'
echo "==> searching for cpio header in /tmp/kernel2.img"
start=`grep -a -b -m 1 --only-matching '070701' /tmp/kernel2.img | head -1 | cut -f 1 -d :`
echo "==> cpio header at $start in /tmp/kernel2.img"
echo "==> searching for cpio footer in /tmp/kernel2.img"
end=`grep -a -b -m 1 --only-matching 'TRAILER!!!' /tmp/kernel2.img | head -1 | cut -f 1 -d :`
echo "==> cpio footer at $end in /tmp/kernel2.img"
# 14 bytes = length of "TRAILER!!!" (zero-terminated string) + padding => fixes premature end of file warning in CPIO
end=$((end + 14))
echo "==> adjusted cpio footer with 14 bytes offset: $end"
count=$((end - start))
echo "==> cpio size is $count bytes ($end - $start)"
if (($count < 0)); then
echo "==> error in cpio positions, aborting"
exit
fi
cpio_file="initramfs.cpio"
cpio_dir=`echo "${cpio_file}.expanded"`
cpio_ls=`echo "${cpio_file}.ls"`
echo "==> deleting ${zImage}_${cpio_file}"
rm ${zImage}_${cpio_file}
echo "==> deleting ${zImage}_${cpio_dir}"
rm -r ${zImage}_${cpio_dir}
echo "==> deleting ${zImage}_${cpio_ls}"
rm -r ${zImage}_${cpio_ls}
echo "==> extracting initramfs ramdisc from /tmp/kernel2.img to ${zImage}_${cpio_file}"
dd if=/tmp/kernel2.img bs=1 skip=$start count=$count > ${zImage}_${cpio_file}
echo "==> expanding ${zImage}_${cpio_file} into ${zImage}_${cpio_dir} directory"
mkdir ${zImage}_${cpio_dir}
curdir=`pwd`
(cd ${zImage}_${cpio_dir} && cpio --quiet -id --no-absolute-filenames < ${curdir}/${zImage}_${cpio_file})
echo "==> generating ls-like file list in ${zImage}_${cpio_ls}"
cpio --quiet -tvnF ${zImage}_${cpio_file} > ${zImage}_${cpio_ls}
echo "==> DONE."
Last edited: