简介 在上世纪 90 年代中期,Microsoft® Windows® 等操作系统由于太大而无法装入软盘中时,引导 CD-ROM 的能力变得至关重要。(来自 Phoenix Technologies 和 IBM 的一项 1994 年的规范)描述了 BIOS 如何读取 CD-ROM 并运行引导过程。一个名为 的 ISO 9660 扩展是描述引导信息的数据格式的最常用方式之一。大多数 Intel® 固件都遵循 El Torito 规范。
但是,IBM® Power Systems™ 没有采用 ISO 9660 有关此引导过程的建议。要在 IBM Power® 服务器中引导一个 ISO 镜像,保存数据的介质需要在一个名为 的目录内提供一个名为 bootinfo.txt 的文件。此文件包含将用于引导该镜像的固件的操作说明。
在需要处理多个架构镜像的软件中,这一区别可能增加了复杂性,比如像 这样的 VM 管理器。通过反复试验 来引导镜像不是一种可行的选择。挂载镜像会提示我们存在文件 /ppc/bootinfo.txt,但挂载过程需要至少与 ISO 镜像相同的磁盘大小、特殊特权,而且还会花不少时间。一种替代解决方案是按原样、逐字节地读取 ISO 镜像,并尝试找到该文件。此方法之所以行得通,是因为所有 ISO 文件都需要实现 ISO9660 文件系统,提供一种标准方式来描述介质中的文件。本文剩余部分将通过编码示例分析这个替代方案。
下一节将介绍 ISO 9660 标准,所有 ISO 文件都要使用它,无论其架构如何。后续各节将介绍如何按照 ISO 9660 建议访问 ISO 文件中的所有文件。本文还提供了一个使用 Python 语言编写的编码示例,并讨论了其他备用的编码方案。最后一节将会总结并讨论结果。
ISO 9660 标准此标准不仅得到了 CD-ROM 的广泛使用、DVD、蓝光光盘以及甚至闪存驱动器也在使用它。尽管它对如今的需要而言具有严重的限制(这已通过其扩展修复),但它描述了一种在介质内存储和读取数据的简单方式。
从 ISO 文件的第一个字节开始,接下来的 32 KB 被标记为系统区域 且未被使用。在系统区域之后,我们有多个扇区(= 2048 字节,也称为逻辑块)描述镜像中存在的卷。每个卷拥有自己的类型和内容,但都采用了同样的布局:
图 1. ISO 9660 中通用的卷描述符格式 最重要的卷描述符是主要卷 (Primary Volume) 和引导记录卷 (Boot Record Volume)。主要卷包含如何读取文件系统的剩余部分的信息,包括目录位置、扇区数量等。引导记录卷告诉 BIOS 如何启动 ISO 镜像。在 El Torito 标准中,引导记录卷保存了引导目录 (Boot Catalog) 的位置,引导目录是可用磁盘镜像的索引。请注意,一个介质中可存在多个引导镜像,因此可能需要这样一种索引。终结卷 (Set Terminator Volume) 标记 ISO 文件的卷记录清单的结束。
图 2. ISO 9660 卷和引导目录在 ISO 9660 文件系统中找到一个文件如上一节中所述,主要卷记录包含该 ISO 中的文件的信息。一个信息就是路径表的大小和位置。此表包含介质中存在的所有记录的列表。此路径表中的数据的格式如下所示:
图 3. 路径表模型 标识符的长度为 ‘directory identifier’ 字段的大小,该字段在大多数情况下是该目录的名称。第二个字段提供该目录的额外信息,用在 ISO 9660 的一些扩展中。‘Location of extend’ 是表示此条目的目录记录的逻辑数据块。‘Directory number of parent directory’ 是表示父目录的逻辑地址的指针。如果目录标识符的长度为偶数,则会存在填充字段(值为 0),否则不存在填充字段。这可以确保每个条目都从一个偶数字节数开始。
可在路径表中找到 ISO 9660 文件系统的目录,但是,如果要查找特定文件,则需要搜索相应的目录记录。此记录保存了有关该目录中的每个文件和子目录的所有信息。
图 4. 目录记录模型 出于本文的用途,我们需要分析以下字段:
‘length of file identifier’ 和 ‘file identifier’ 用于读取文件/子目录的名称
‘padding’ 仅在记录的长度为偶数时存在
有了此信息,我们就可以定义一个算法来查找 /ppc/bootinfo.txt 文件,确定该 ISO 是否可以在 Power Systems 服务器中进行引导。
图 5. 查找 ‘/ppc/bootinfo.txt’ 文件的算法 请注意,此算法可调整来查找任何文件 - 只需按路径的逆向顺序查找该文件,查找所有目录,直到到达包含我们查找的文件的目录。
我们可以在下一节中的示例代码中看到此概念的实际应用,届时我们将打开一个 IBM Power 服务器 ISO 文件来检测它是否可引导。
一种 Python 实现以下代码是我们目前为止讨论的概念的实用示例。这段 Python 脚本加载了这个 ISO 文件作为参数,评估该镜像是否可由 Power Systems 固件引导。通过读取它的内部注释,可以了解此工作流。这个 是我提交到 Kimchi 项目的补丁的调整版本。
将内容保存在一个名为 detect_ppc_iso.py 的文件中,然后使用以下命令运行该文件。
1
$ python detect_ppc_iso.py <pc_iso>
请参阅 部分,以便获取 detect_ppc_iso.py 文件。
其他备用方案 上一节中提供的实现打开了一个 ISO 镜像文件,使用 ISO 9660 标准逐字节地读取它的内容,以便查找可引导的 Power Systems 文件 /ppc/bootinfo.txt。
还有一些开源库也能够读取 ISO 文件并提供相同的结果。在一些安装了 的 Linux® 发行版中,可以使用 isoinfo 命令从 ISO 文件检索相关信息,包括是否存在针对 Power Systems 固件的引导文件。
清单 1. 使用 isoinfo 在 ISO 文件中查找 ‘/ppc/bootinfo.txt’ 文件
第一个命令将会读取 ISO 镜像的主要卷描述符并检索其中的信息。第二个命令会查找 /ppc/bootinfo.txt 文件并将其内容转储到标准输出。
尽管使用 isoinfo 命令或其他任何备用方案可能更简单,但该命令是在 OS 中安装额外的包和在未来生成对它们的依赖关系的前提条件。除非您的软件大量使用了这些库所提供的 ISO 操作特性,但检查一个 ISO 文件能否在 Power Systems 服务器上进行引导,这是一个可以使用前一节中的代码完成的任务,该代码可跨操作系统和平台运行,仅依赖于 Python 核心库。