linux_iso镜像解析

Catalogue
  1. 1. ISO 9660
  2. 2. 引导
  3. 3. 光盘引导
  4. 4. EFI
  5. 5. images
  6. 6. LiveOS
  7. 7. linux启动顺序
  8. 8. 如何制作repodata
  9. 9. 如何下载软件所需的rpm包和依赖
  10. 10. 如何解压initrd.img
  11. 11. 如何搞squashfs.img
  12. 12. 系统打包
    1. 12.1. 参考链接:

最近要搞一下linux系统,每段时间总结记录一下吧

CentOS ISO 目录树如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost jusha_test]# tree -L 1
.
├── CentOS_BuildTag
├── EFI
├── EULA
├── GPL
├── images
├── isolinux
├── LiveOS
├── Packages
├── repodata
├── RPM-GPG-KEY-CentOS-7
└── RPM-GPG-KEY-CentOS-Testing-7

ISO 9660

ISO 9660 是一种文件系统,也是一种规范,它规定了 ISO 文件应该是什么样子,常见的 Linux 发行版 ISO 都符合该规范。

引导

有了 ISO,有了计算机,那么我们需要使用 ISO 安装想要的操作系统,通常我们会将 ISO 通过光盘/USB/网络等方式挂载到计算机上,通过设置 BIOS/UEFI 选项,将启动项设置为 ISO,然后启动进行安装。接下来一个一个来说。

BIOS/UEFI 通常存放在闪存中,在计算机开机自检完成后,加载引导程序(bootloader),这个初始化过程称为引导。BIOS/UEFI 通常允许用户设置加载选项,即从系统的众多设备中按照顺序进行加载,常见的比如:硬盘、光盘、网络、USB 等。当第一个设备加载失败后,会尝试第二个设备,以此类推,如果最终所有设备都无法加载,那么系统处于开机但未引导状态。

光盘引导

引导分为很多种,例如硬盘引导,光盘引导(iso),下面我们主要讲一下光盘引导

根据 El-Torito 规范,BIOS 会读取 ISO 的准确地址进行判断,ISO 是否可以进行引导启动(在第 71 字节地址保存引导目录)。如果判断可引导,那么就加载对应的引导程序(bootloader)。

常见的引导程序有:SYSLINUX,ISOLINUX(光盘安装),PXELINUX(网络安装),EXTLINUX 等,这些可以统称为 Syslinux,目前最常见的应该是 ISOLINUX。PXELINUX 用于从网络引导,EXTLINUX 用于 ext 系列文件系统引导。

注意:由于目前 UEFI 的普遍性,部分 LiveCD ISO 会同时带有 ISOLINUX 和 GRUB 两种引导程序。

isolinux 目录树如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

[root@localhost isolinux]# tree -L 1
.
├── boot.cat # 启动目录
├── boot.msg # 启动信息
├── grub.conf # GRUB 配置文件
├── initrd.img # 临时文件系统
├── isolinux.bin # ISOLINUX 引导程序
├── isolinux.cfg # ISOLINUX 引导配置文件
├── ks.cfg # kickstart配置文件
├── memtest # 内存测试可执行文件
├── vesamenu.c32 # 内存测试可执行文件
├── splash.png # ISOLINUX 引导背景图片
└── vmlinuz # 内核映像

光盘引导的大致流程是

  1. 加载 isolinux.bin
  2. 加载 isolinux.cfg,vesamenu.c32,splash.png 生成启动菜单
  3. 根据选项决定是否加载 vmlinuz, initrd.img

EFI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ tree 
.
├── BOOT
│ ├── BOOTIA32.EFI # 32位系统 EFI 启动程序
│ ├── BOOTX64.EFI # 64位系统 EFI 启动程序
│ ├── fonts # 字体
│ │ ├── TRANS.TBL
│ │ └── unicode.pf2
│ ├── grub.cfg # GRUB 配置
│ ├── grubia32.efi # GRUB 32位引导程序
│ ├── grubx64.efi # GRUB 64位引导程序
│ ├── mmia32.efi # 内存测试 32 位执行程序
│ ├── mmx64.efi # 内存测试 64 位执行程序
│ └── TRANS.TBL
└── TRANS.TBL

如果机器的启动方式为BIOS,则启动方式为isolinux
如果机器的启动方式为UEFI,则启动方式为grub(EFI)

images

1
2
3
4
5
6
[root@localhost images]# tree -L 2
.
├── efiboot.img
└── pxeboot
├── initrd.img
└── vmlinuz

这个文件夹就是把 vmlinuz 和 initrd.img 提取出来了,在 EFI 路径下的 BOOT/grub.cfg 中有很多选项都是使用的 pxeboot/vmlinuz 。当然它最大的作用也是跟路径名一样,images,当你要配置一个发行版作为网络安装时,需要对应的 vmlinuz 和 initrd.img,那么可以从这个路径下获取,不会造成我要通过 PXELINUX 引导,却需要去 EFI 路径下获取文件的困扰。

LiveOS

1
2
3
[root@localhost LiveOS]# tree -L 2
.
└── squashfs.img

可以理解为完整版的initrd.img,也就是完整版的文件系统

linux启动顺序

  1. 开机
  2. BIOS 检测(硬件检测、引导顺序等)
  3. 读取并运行装置内 MBR 的 boot Loader
  4. 加载内核
  5. 启动 liveCD 或 Anaconda
  6. 由用户配置安装选项或解析 kickstart 配置
  7. 分区并挂载文件系统
  8. 完成安装,重启

让我们看一下isolinux.cfg配置文件

1
2
3
4
5
6
7
8
[root@localhost jusha_test]# cat isolinux/isolinux.cfg 
default linux #默认的label是linux
display boot.msg #开机显示的信息(可编辑)

label linux
kernel vmlinuz #加载内核
append initrd=initrd.img inst.stage2=hd:LABEL=CENTOS7_STD inst.ks=hd:LABEL=CENTOS7_STD:/isolinux/ks.cfg net.ifnames=0 biosdevname=0 quiet inst.noshell

系统内核 vmlinuz被加载到内存后开始提供底层支持,在内核的支持下各种模块,服务等被加载运行。

假设你的硬盘是scsi 接口而你的内核又不支持这种接口时,你的内核就没有办法访问硬盘,当然也没法加载硬盘上的文件系统,怎么办?好办!把内核加入scsi驱动源码然后重新编译出一个新的内核文件替换原来vmlinuz。

需要改变标准内核默认提供支持的例子还有很多,如果每次都需要编译内核就太麻烦了。所以后来的linux就提供了一个灵活的方法来解决这些问题—initrd.img

ininrd.img是什么呢?initrd 的含义是initialized ram disk.

ramdisk是用一部分内存模拟成磁盘,让操作系统访问。举个例子,PE系统就是在内存中运行的系统,进入系统中你会发现有一个文件系统B:/分区,这个就是内存模拟出来的硬盘

initrd.img文件就是个ramdisk的映像文件,也就是PE系统

加载内核————>运行initrd.img(加载PE系统)————>运行某个装机脚本(例如ks.cfg,或者是默认的那个)————> 把 squashfs.img 解包到loop设备,挂载为根目录,chroot到根目录上————> 根据安装脚本,把所需的文件从 根目录 中拷贝到硬盘的分区中(也就是把系统拷贝过去,并不会把 根目录 中所有的文件都拷过去)

如何制作repodata

1
2
3
4
5
6
7
8
9
10
11
repodata/
├── 2f0a01d165af065cbd008f1ef26733def65e2cb3fc5586246caea7f57bc026b1-filelists.xml.gz
├── 4e0837df911f9763b3f638d73192531321b02dc95cc8e8a32151c5de2055a284-std.xml.gz
├── 56c81c83e52761e2075faf327dd441629993248ac1db939aa252eeea69c0b795-other.xml.gz
├── 6dbc623e7a6dc19dc382c0b461b1890d008ceb190828466f3e7ff9a0cde3b63c-other.sqlite.bz2
├── 723e3f42aa3acb6937c9d4466e2da92a6792091b98e7cb8355c84c422c2c03cc-std.xml
├── 733efc4dd0dd3a361fb3c2be99163255a1366a29ab704a88bf337a1ddbf3771b-primary.xml.gz
├── a571bb0313b8632e69d483d0cc139a08ca3eb1ba0e80016023447b85d45654a6-filelists.sqlite.bz2
├── ebd90cbe99f59185bd0b5b7af499e799db86f4aaf86eb4bd49868027f5b43670-primary.sqlite.bz2
└── repomd.xml

repodata就是 软件库索引,对应的就是Packages里的rpm包
其中的 *-std.xml就是索引文件
如果要在系统里预设一些软件,可以把相应的rpm包和依赖打入Packages里,然后把repodata里的索引文件复制、编辑,最后使用 createrepo重新生成即可

1
2
3
4
5
6
7
8
9
cp /centos_std/repodata/*-std.xml /centos_std/std.xml

编辑std.xml,把要加的软件加进去
把要打的rpm包加到Packages里

rm -rf /centos_std/repodata

createrepo -g /centos_std/std.xml /centos_std/

如何下载软件所需的rpm包和依赖

推荐使用repotrack(该软件在yum-utils包里)

1
2
3
4
5
6
7
8
9
10
11
12
yum -y install yum-utils

repotrack <package-name> -p <下载路径>

<package-name>可以使用 yum install <软件名>查找
例1:
yum install vim,找到包为vim-enhanced-7.4.629-8.el7_9.x86_64
repotrack vim-enhanced -p /centos_std/Packages

这就会下载vim-enhanced包和这个包的依赖

要打的包和依赖都下载完后,要更新软件库索引

也可以使用yum来安装(不过依赖可能会有问题)

1
2
3
4
5
6
显示依赖
yum deplist vim

yum install --downloadonly --downloaddir=Packages <package-name>

如果是已安装的软件,则用reinstall

如何解压initrd.img

查看文件类型

1
2
3
4
5
6
7
8
9
10
11
[root@localhost jusha_test]# file isolinux/initrd.img 
isolinux/initrd.img: XZ compressed data

发现是xz的压缩类型
mv initrd.img initrd.img.xz
xz -d initrd.img.xz
解压出来是cpio archive文件,然后文件解压出来:
cpio -i -d < initrd.img

打包成cpio archive文件并压缩为gzip格式
find . | cpio -H newc --create --verbose | gzip -9 > ../initrd.img

如何搞squashfs.img

看一下文件类型

1
2
[root@localhost jusha_test]# file LiveOS/squashfs.img 
LiveOS/squashfs.img: Squashfs filesystem, little endian, version 4.0, 640503068 bytes, 3 inodes, blocksize: 1048576 bytes, created: Mon Aug 23 03:28:08 2021

这个就是一个Squashfs的文件系统

我们来解压一下看看

1
2
3
4
5
6
7
8
9
unsquashfs squashfs.img
会得到一个squashfs-root的文件夹

[root@localhost squashfs-root]# tree -L 2
.
└── LiveOS
└── rootfs.img

1 directory, 1 file

看一下rootfs.img的文件类型

1
2
[root@localhost LiveOS]# file rootfs.img 
rootfs.img: Linux rev 1.0 ext4 filesystem data, UUID=b44bfac8-86bb-4036-a6f4-bdcf6988f4ad, volume name "Anaconda" (extents) (64bit) (huge files)

发现这是一个ext4的文件系统,如果要修改这个文件的话,直接挂载然后修改就行

1
2
3
4
5
mount -o loop root.img std
然后cd进去修改就可以了,改好了之后umount std

最后打包成squashfs.img
mksquashfs squashfs-root squashfs.img -b 1024k -comp xz

系统打包

如果有TRANS.TBL文件,提前删掉,打包时会自动生成的

1
2
3
rm -rf `find ./ -name TRANS.TBL`

mkisofs -o ../STD.iso -b isolinux/isolinux.bin -c isolinux/boot.cat --no-emul-boot --boot-load-size 4 --boot-info-table -J -R -T -V "CENTOS7_STD" .

参考链接:

roofs.img的制作

https://www.codenong.com/cs106751361/

https://blog.csdn.net/prownd/article/details/53422977

linux引导
https://zdyxry.github.io/2019/12/01/Linux-%E5%BC%95%E5%AF%BC%E9%82%A3%E4%BA%9B%E4%BA%8B%E5%84%BF/

http://blog.zxh.site/2018/02/16/Linux%E5%AE%9A%E5%88%B6%E5%8C%96%E9%95%9C%E5%83%8F%E5%88%B6%E4%BD%9C%E6%8C%87%E5%8D%97/