从vmlinuz获得原始Linux内核程序
https://www.cnblogs.com/xiami-xm/articles/8417526.html
由于GEM5需要从原始的Linux内核可执行文件启动,不能使用压缩过的vmlinuz,所以一开始的想法是从当前发行版的软件包管理器下载压缩过的内核,然后从里面解压出完整版本的来。在Stackoverflow上看到了两种方法:
- 二进制暴力解法
https://superuser.com/questions/298826/how-do-i-uncompress-vmlinuz-to-vmlinux
分析vmlinuz的构成原理,可以得知其拆解方式。在此仅引用结论,原理学习还请暂时移步其他博客。
zImage
和bzImage
都是指的使用gzip压缩的内核,有无b
的主要区别在于内核文件的大小,实际上b就代表big。作为第一个在裸处理器上运行的程序,内核显然不能指望有其他程序能够替自己解压缩,因而vmlinuz是包含有gzip自解压的代码的。也就是说,vmlinuz文件至少由压缩的内核和预操作(比如解压)代码组成。在承认这些部分的数据是各自连续的情况下,可以通过在其中寻找gzip的文件头,来寻找压缩内核的位置,然后解压即可获得原始内核。
借用原文中的例子:
> od -A d -t x1 vmlinuz | grep '1f 8b 08 00' 0024576 24 26 27 00 ae 21 16 00 1f 8b 08 00 7f 2f 6b 45
其中1f 8b 08 00
是gzip文件的文件头,标识一个合法的gzip文件开头。
很幸运,在当前的vmlinuz中似乎还是只含有一个gzip文件,而这个文件正是我们所需要的,经过gzip压缩的vmlinux。
> dd if=vmlinuz bs=1 skip=24584 | zcat > vmlinux 1450414+0 records in 1450414+0 records out 1450414 bytes (1.5 MB) copied, 6.78127 s, 214 kB/s
使用dd
命令,从指定位置复制数据出来,bs=1
表示每次的数据操作量为1字节,使用这个值能够较为简便地确定开始位置(od
命令所提供的偏移量就是以字节为单位的)。比如上文中的0024576
表示十六进制数据“24”相对文件首部的偏移量为24576 * 1字节 = 24576字节。将偏移量定位到gzip文件首部的“1f”,相对“24”向后偏移了8字节,故dd
中的命令偏移量设置为24576 + 8 = 24584。使用管道将二进制内容直接发送到zcat
,在命令行内完成文件的解压,得到预期中的vmlinux文件。
- 使用Linux内核包提供的解压工具(天知道原理和1是不是一样的)
https://stackoverflow.com/questions/12002315/extract-vmlinux-from-vmlinuz-or-bzimage
简单说就是使用
scripts
目录下的extract-vmlinux
脚本来完成操作。不过这个我没试过。