从压缩的内核镜像中获取内核版本号。

6
我正在编写一个shell脚本。我有一个预先构建的zImage。是否可能知道从哪个内核版本创建了这个zImage?
我已经尝试使用更新的命令 @ Getting uname information from a compressed kernel image,但两个命令都失败了。
$ 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

你能指导我如何从zImage中识别内核版本吗?

1
对于 ARM 目标,Makefile 指出可以使用 gzip、lzo、lzma、xz 或 lz4 方法压缩 zImage。你只尝试了其中的两种方法(gzip 和 xz)。 - sawdust
2个回答

13

检查内核压缩算法

很可能您的zImage是使用LZMA压缩器进行压缩的。 您可以在以下文件中检查:

  • .config文件中(如果您自己构建了内核)
  • /boot/config-`uname -r`文件中(如果您使用的是发行版)
  • /proc/config.gz文件中(如果启用了CONFIG_IKCONFIG_PROC

查找CONFIG_KERNEL_*参数:

$ cat .config | grep '^CONFIG_KERNEL_[^_]\+='

如果你设置了CONFIG_KERNEL_LZMA=y,那么它意味着使用LZMA压缩器。
解压zImage LZMA格式的头部签名5d 00 00。因此,可以通过以下方式在zImage文件中找到压缩的Image文件的位置:
$ grep -P -a -b -m 1 --only-matching '\x5D\x00\x00' zImage | cut -f 1 -d :

提取压缩的图像
$ 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

现在,请确保piggy.lzma实际上是LZMA存档文件:
$ file piggy.lzma 

piggy.lzma: 是LZMA压缩数据,流式传输

解压 piggy.lzma:

$ unlzma -c piggy.lzma > Image

查找Linux版本

现在您已经解压了Image,可以使用strings工具查找Linux版本:

$ strings Image | grep 'Linux version'

这应该给你类似于这样的东西:

Linux版本4.4.11-188843-g94c4bf5-dirty(joe@joe-laptop)(gcc版本4.8(GCC))#1 SMP PREEMPT Thu May 26 20:55:27 EEST 2016


谢谢您提供的详细信息,它起作用了。请问可以知道从zImage压缩中使用了哪种压缩技术吗? - Ravi A
3
  1. 尝试使用“binwalk”工具(应该在你的发行版存储库中)。
  2. 也可以尝试使用“file”工具检查图像。
  3. 您可以尝试使用所有已知的内核压缩算法(以及对应的头部魔法数字)提取“piggy”文件,然后使用“file”工具检查“piggy”文件,它应该告诉您是否是预期的压缩文件。除此之外,我不知道有什么简单的方法来确定压缩算法。
- Sam Protsenko
1
使用dd if=zImage of=piggy.lzma skip=$pos iflag=skip_bytes而不是dd if=zImage of=piggy.lzma bs=1 skip=$pos对我来说速度惊人地快。 - Alexandre Schmidt
对于xz压缩,搜索什么替代5d 00 00 - Darren Ng
1
@DarrenNg 请尝试查找 fd377a585a00,如此处所述(http://www.who.is.free.fr/wiki/doku.php?id=cli)。不过我没有检查过。 - Sam Protsenko

0

对Sam Protsenko的回答的补充:

由于您没有明确zImage文件中使用的压缩算法,因此建议您使用vmlinux-to-elf。 该工具可用于将zImage文件转换为ELF文件,并可识别多种压缩算法(不仅仅是LZMA)。

在简单的用例中,首先将zImage文件转换为ELF文件:

./vmlinux-to-elf ./zImage ./Image

file ./Image

./Image: ELF 32-bit LSB 可执行文件,ARM 架构,版本 1 (SYSV),静态链接,未剥离

然后,使用 strings 命令查找 Linux 版本。

strings ./Image | grep 'Linux version'

Linux版本3.4.0-gd59db4e(android-build@vpbs1.mtv.corp.google.com)(gcc版本4.7(GCC))#1 SMP PREEMPT Mon Mar 17 15:16:36 PDT 2014。

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。- 来自审查 - jiwopene
1
@jiwopene 感谢您的提醒,我已经对答案进行了一些修改。 :) - imlk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接