先简单说明下 vmlinux 和 vmlinuz 的关系

vmlinux是一个包含linux kernel的静态链接的可执行文件,文件类型是linux接受的可执行文件格式之一(ELF、COFF或a.out)。

vmlinuz是可引导的,压缩的linux内核,“vm”代表的“virtual memory”。vmlinuz是vmlinux经过gzip和objcopy(*)制作出来的压缩文件。vmlinuz不仅是一个压缩文件,而且在文件的开头部分内嵌有gzip解压缩代码。所以你不能用gunzip 或 gzip –dc解包vmlinuz。

查看 vmlinuz 文件信息(包含架构和内核版本等信息)

# 如下以 CentOS7 为示例
[root@middleware3 002]# file /boot/vmlinuz-3.10.0-1127.el7.x86_64 
vmlinuz-3.10.0-1127.el7.x86_64: Linux kernel x86 boot executable bzImage, version 3.10.0-1127.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) #1 , RO-rootFS, swap_dev 0x6, Normal VGA

通过查看输出可以判断这个 vmlinuz 是 zImage 还是 bzImage。

接下来的内容是针对 zImage 的操作方法,如果你是 bzImage,请直接往下看,操作方法在文章后半段有。

拿到一个 vmlinuz 后解压缩的方法如下

[root@centos boot]# od -t x1 -A d vmlinuz | grep "1f 8b 08"
0013408 ff e0 1f 8b 08 00 ea 80 b9 52 02 03 ec 5b 7f 74
[root@centos boot]# dd if=vmlinuz bs=1 skip=0013410 | zcat > vmlinux
gzip: stdin: decompression OK, trailing garbage ignored
记录了9195934+0 的读入
记录了9195934+0 的写出
9195934字节(9.2 MB)已复制,51.5023 秒,179 kB/秒

以上是两步命令,合并为一个命令后为:

dd if=./vmlinuz skip=`grep -a -b -o -m 1 -e $'\x1f\x8b\x08\x00' ./vmlinuz | cut -d: -f 1` bs=1 | zcat > /tmp/vmlinux

这里特别解释一下 skip=0013410 这个数的计算方法,就是0013408这个数 + 0013408与1f 8b 08 00之间间隔的数字个数 = 得出的结果

示例中间隔了2个数字 ff e0,所以是 0013408+2=0013410

再举一个例子

[root@centos boot]# od -t x1 -A d vmlinuz-2.6.32-358.el6.x86_64 | grep "1f 8b 08"
0014432 48 8d 83 e0 3e 3d 00 ff e0 1f 8b 08 00 78 bc 26

根据输出可以得出 skip=0014432+9=001441=0014441


(上面是 zImage 格式的 vmlinuz)华丽丽分割线(下面还有 bzImage 格式的 vmlinuz)

注:vmlinuz 就是 zImage 这样的文件,只不过重命名为 vmlinuz 而已


zImage 和 bzImage

zImage是vmlinuz经过gzip压缩后的文件,适用于小内核(512KB以内),加载到内存的开始640KB处。

bzimage(not bzizp but big)是vmlinuz经过gzip压缩后的文件,适用于大内核。

从 bzImage 中提取 vmlinux 就更简单了,因为有现成的工具,工具位于Linux源代码中的可执行文件 scripts/extract-vmlinux,你将它拷贝出来就行了(点击这里可以直接下载)

使用方法:

chmod +x extract-vmlinux
./extract-vmlinux vmlinuz > vmlinux

执行命令 `` 效果如下,可以说明我们得到了一个正常的 vmlinux 文件

[root@test demo]# strings vmlinux | grep sbin
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PATH=/sbin:/bin:/usr/sbin:/usr/bin
/sbin/bridge-stp
/sbin/modprobe
/sbin/poweroff
/sbin/hotplug

(END)

Logo

更多推荐