如何从“.img”备份中提取Linux版本?

如何从“.img”备份中提取Linux版本?

简而言之:

如何从系统备份中提取 VERSION、SUBVERSION 和 PATCHLEVEl 编号.img?最好没有 root 权限。

扩展:

从以下页面:

https://www.raspberrypi.org/downloads/raspbian/

它提供了一个zip提取为 的Debian .img,它代表了 ARM 架构的 Debian/Raspian 系统的完整系统备份。

为了生成自定义内核,需要知道系统的VERSION、SUBVERSION和PATCHLEVEL,相当于典型内核提供的信息

$ uname -r
4.9.0-3-amd64

最简单的方法是直接加载系统并运行命令,但这不适用于本例。

目标:

镜像的内核需要打补丁和交叉编译。我的目的是为此过程创建一个脚本,因此当内核更新时它可以“轻松”地进一步应用。

答案1

如果这就是我所认为的磁盘映像,那么用新内核“修补映像”将非常困难,因为它不仅必须考虑实际的内核文件,还必须考虑文件系统的其余部分在图像上编码;由于碎片,内核可能不会以连续的方式存储在磁盘上,如果更新的内核更大(或更小),则映像上的文件系统需要相应更新。

即使您以某种方式在整个图像中搜索希望提取的变量,您也不知道任何命中是否来自图像文件系统上实际存在的文件或来自不再引用的旧文件。

最好的建议是安装映像并更新它,或者将其写入 SD 卡,更新它并重新创建它。

如果不以某种方式挂载映像来执行此操作,则必须包括模拟文件系统。

答案2

这似乎适用于2017-09-07-raspbian-stretch-lite.img该网站的图像:

$ sudo kpartx -rva 2017-09-07-raspbian-stretch-lite.img
add map loop0p1 (252:19): 0 85622 linear 7:0 8192
add map loop0p2 (252:20): 0 3528040 linear 7:0 94208
$ sudo mount -r /dev/mapper/loop0p1 mnt
$ LC_ALL=C gawk -v RS='\37\213\10\0' 'NR==2{printf "%s", RS $0; exit}
  ' < mnt/kernel.img | gunzip | grep -aPom1 'Linux version \S+'
Linux version 4.9.41+

(其中\37\213\10\0标识 gzip 压缩数据的开始位置)。

作为非 root,假设映像中的第一个分区始终为 4MiB,使用 GNU从该 vfat 分区中mtools提取:kernel.img

$ MTOOLS_SKIP_CHECK=1 mtype -i 2017-09-07-raspbian-stretch-lite.img@@4M ::kernel.img|
  LC_ALL=C gawk -v RS='\37\213\10\0' 'NR==2{printf "%s", RS $0; exit}' |
  gunzip | grep -aPom1 'Linux version \K\S+'
4.9.41+

如果没有,在/dev/fd支持(和 GNU grep)的系统上:

MTOOLS_SKIP_CHECK=1 MTOOLSRC=/dev/fd/3 mtype z:kernel.img \
  3<< EOF 4< 2017-09-07-raspbian-stretch-lite.img |
drive z:
  file="/dev/fd/4"
  partition=1

EOF
  LC_ALL=C gawk -v RS='\37\213\10\0' 'NR==2{printf "%s", RS $0; exit}' |
  gunzip | grep -aPom1 'Linux version \K\S+'

(在其他系统上,使用file="2017-09-07-raspbian-stretch-lite.img"/dev/fd/4只是为了更容易适应任意文件名)

从 zip 文件中,您应该能够在不提取整个图像的情况下离开,只需提取第一个分区:

#! /bin/zsh -
zip=${1?zip file missing}

MTOOLS_SKIP_CHECK=1 mtype -i =(
    unzip -p -- "$zip" | perl -ne '
      BEGIN{$/=\512}
      if ($. == 1) {
        ($offset, $size) = unpack("x454L<2",$_)
      } elsif ($. > $offset) {
        print;
        if ($. == $offset + $size - 1) {exit}
      }') ::kernel.img |
  LC_ALL=C gawk -v RS='\37\213\10\0' 'NR==2{printf "%s", RS $0; exit}' |
  gunzip | grep -aPom1 'Linux version \K\S+'

答案3

你可以尝试挂载一下。

fdisk -l /path/to/your.img

mount -o loop,offset=sector size * start of the partition  your.img /yourfolder

sector size * start of the partition:查看 fdisk 输出并乘以

然后你可以查看启动文件夹中的文件。

相关内容