如何从 `.img` 备份中提取 linux 版本?

Adr*_*ire 5 kernel disk-image

简而言之:

如何从系统备份中提取 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
Run Code Online (Sandbox Code Playgroud)

最简单的方法是直接加载系统并运行命令,但在这种情况下不适用。

目标:

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

Kus*_*nda 5

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

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

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

在不以一种或另一种方式安装映像的情况下执行此操作必须包括模拟文件系统。


Sté*_*las 4

这似乎适用于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+
Run Code Online (Sandbox Code Playgroud)

(其中\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+
Run Code Online (Sandbox Code Playgroud)

如果没有,在/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+'
Run Code Online (Sandbox Code Playgroud)

(在其他系统上,使用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+'
Run Code Online (Sandbox Code Playgroud)