Issue
I am working on a shell script. I have a pre-built zImage. is it possible to know the kernel version from which this zImage was created?
I have tried with the commands updated @ href="https://stackoverflow.com/questions/9535227/getting-uname-information-from-a-compressed-kernel-image">Getting uname information from a compressed kernel image, but both commands are failing.
$ dd if=zImage bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' zImage | \
cut -d ':' -f 1) | zcat | grep -a 'Linux version'
dd: unrecognized operand `3165585'
Try `dd --help' for more information.
gzip: stdin: unexpected end of file
$ dd if=zImage bs=1 skip=$(LC_ALL=C grep -a -b -o $'\xFD\x37\x7A\x58\x5A\x00' zImage | \
head -n 1 | cut -d ':' -f 1) | xzcat | grep -a 'Linux version'
xzcat: (stdin): File format not recognized
Can you guide me to identify the kernel version from zImage.
Solution
Check kernel compression algorithm
Most likely your zImage
was compressed using LZMA compressor. You can check it in next files:
- in
.config
file (if you built kernel by yourself) - in
/boot/config-`uname -r`
file (if you are using your distribution) - in
/proc/config.gz
file (ifCONFIG_IKCONFIG_PROC
is enabled)
Look for CONFIG_KERNEL_*
param:
$ cat .config | grep '^CONFIG_KERNEL_[^_]\+='
If you have CONFIG_KERNEL_LZMA=y
set, it means LZMA compressor is used.
Unpack zImage
LZMA format has 5d 00 00
header signature. So one can find position of compressed Image
file in zImage
file this way:
$ grep -P -a -b -m 1 --only-matching '\x5D\x00\x00' zImage | cut -f 1 -d :
To extract compressed Image
:
$ pos=$(grep -P -a -b -m 1 --only-matching '\x5D\x00\x00' zImage | cut -f 1 -d :)
$ dd if=arch/arm/boot/zImage of=piggy.lzma bs=1 skip=$pos
Now make sure that piggy.lzma
is actually LZMA archive:
$ file piggy.lzma
piggy.lzma: LZMA compressed data, streamed
Decompress piggy.lzma
:
$ unlzma -c piggy.lzma > Image
Find the Linux version
Now that you have unpacked Image
, you can find the Linux version using strings
tool:
$ strings Image | grep 'Linux version'
which should give you something like this:
Linux version 4.4.11-188843-g94c4bf5-dirty (joe@joe-laptop) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Thu May 26 20:55:27 EEST 2016
Answered By - Sam Protsenko Answer Checked By - Robin (WPSolving Admin)