概述与注意事项
ISO 9660 并不是一个复杂的文件系统,但有一些值得记住的特点。似乎有些作系统还会生成不合规的光盘,所以要小心!主要例子是可用于文件名的字符集。严格来说,文件名只能由大写字母 A-Z 组成,数字, 点和划线。此外,文件名和版本号后缀之间还有分号。许多作系统还允许使用小写字母和其他字符。Linux 的 VFS 向用户显示小写文件名,尽管 CD 内容实际上包含大写字符。
扇区规模
ISO 9660扇区通常长2 KiB。虽然规范允许不同的扇区大小,但你很少会看到超过2 KiB的。
数字格式
该系统的另一个特点是它有多种编号格式,多字节数字通常以双端格式表示。ISO 9660标准规定了三种编码16位和32位整数的方法,分别使用小端序(最小有效字节优先)、大端序(最有效字节优先),或两者结合(小端序后大端序)。因此,双端序(LSB-MSB)场宽度是其两倍。因此,32位LBA通常以8字节字段的形式出现。在存在双端格式时,x86架构采用第一个小端序列,忽略大端序列。
| 编码 | 描述 |
|---|---|
| IN8 | 无符号8位整数。 |
| SINT8 | 带符号的8位整数。 |
| int16_LSB | 小端编码的无符号16位整数。 |
| int16_MSB | 大端编码的无符号16位整数。 |
| int16_LSB-MSB | 小端序后接大端编码的无符号16位整数。 |
| sint16_LSB | 小端编码带符号16位整数。 |
| sint16_MSB | 大端编码的带符号16位整数。 |
| sint16_LSB-MSB | 小端序后接大端编码带符号16位整数。 |
| int32_LSB | 小端编码的无符号32位整数。 |
| int32_MSB | 大端编码的无符号32位整数。 |
| int32_LSB-MSB | 小端序后接大端序编码的无符号32位整数。 |
| sint32_LSB | 小端编码带符号32位整数。 |
| sint32_MSB | 大端编码的带符号32位整数。 |
| sint32_LSB-MSB | 小端序后接大端编码的带符号32位整数。 |
日期/时间格式
主卷描述符中使用的日期/时间格式表示为dec-datetime,并使用ASCII数字表示日期/时间的主要部分:
| 抵消 | 大小 | 数据类型 | 描述 |
|---|---|---|---|
| 0 | 4 | strD | 年份从1年到9999年。 |
| 4 | 2 | strD | 从1月到12日。 |
| 6 | 2 | strD | 从1点到31号。 |
| 8 | 2 | strD | 从0到23小时。 |
| 10 | 2 | strD | 从0到59的一分钟。 |
| 12 | 2 | strD | 第二名从0到59。 |
| 14 | 2 | strD | 0到99的百分之一秒。 |
| 16 | 1 | IN8 | 时区与格林威治标准时间以15分钟为间隔,从西边-48秒开始,一直到东边时区52秒。因此,值0表示区间-48,即GMT至12小时,值100表示区间52,即GMT+13小时。 |
除GMT偏移外,所有字段均为ASCII数字。当日期和时间未指定时,所有字符串字段均为ASCII为“0”(共16个ASCII零),最后一个字段为二进制零。
字符串格式
字符字符串采用 ASCII 编码。规范不允许所有字符。它定义了两组字符:“a字符”和“d字符”。你将在本文的描述符表中看到这些术语的使用。字符集如下:
a-characters: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _
! " % & ' ( ) * + , - . / : ; < = > ?
d-characters: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _
| 编码 | 描述 |
|---|---|
| strA | 字符串仅包含ASCII的a字符,右侧填充空格。 |
| strD | 字符串仅包含ASCII的d字符,右侧填充空格。 |
请注意,并非所有光盘都严格遵循ISO 9660规定的字符集。
文件名
文件名必须使用 d 字符编码(strD),加上点和分号 每个文件名必须恰好发生一次。 文件名由一个文件名、一个点、一个文件扩展名组成, 分号;以及一个以十进制数字表示的版本号。后两者 通常不会向用户显示。
交换分为三个层级。一级允许文件名 文件名长度为8,扩展名为3(类似MS-DOS)。 第2和第3级允许文件名和文件名扩展名合并 长度最多可达30个字符。
ECMA-119目录记录格式可容纳最多222个组合名称 字符。这会违反规范,但必须处理 由文件系统的读者读取。
尺寸限制
ISO 9660 文件系统最多可包含 2 个 exp 32 块,即 8 TiB。 通常它们的尺寸会被限制在光学介质的尺寸范围内。 (目前4层BD-R时最高可达100 GiB。)
数据文件的最大大小取决于交换级别 该系统旨在用于ISO文件系统。第1级和第2级允许 4 GiB - 1,因为单个目录记录最多可申报 字节数。三级允许多个连续 同名目录记录。它们都必须被串联 映射到单个数据文件。这意味着单个数据文件几乎可以 填满完整的8 TiB图像尺寸。
系统区域
ISO 9660文件系统以32 KiB开头,可用于任意 数据。这通常用于存储 ISO 9660 文件系统不存储在光学介质上,而是存储在 类似硬盘的设备,例如USB驱动器。
所以要准备好在那个地点找到主引导记录 (MBR,代表BIOS)、GUID分区表(GPT,用于EFI),或 苹果分区地图(APM)。
卷描述符
准备安装CD时,你的第一个动作是读取音量描述符(具体来说,你要寻找主音量描述符)。
由于CD的扇区0x00-0x0F被保留为系统区, 卷描述符从扇区0x10(16)开始。卷描述符的格式如下:
| 抵消 | 长度(字节) | 场地名称 | 数据类型 | 描述 |
|---|---|---|---|---|
| 0 | 1 | 类型 | IN8 | 卷描述符类型代码(见下文)。 |
| 1 | 5 | 标识符 | strA | 总是“CD001”。 |
| 6 | 1 | 版本 | IN8 | 卷描述符版本(0x01)。 |
| 7 | 2041 | 数据 | - | 这取决于卷描述符类型。 |
这意味着每个卷描述符因此是一个扇区(2 KiB)。
卷描述符类型代码
卷描述符类型字段指定卷描述符的类型:
| 价值 | 描述 |
|---|---|
| 0 | 启动记录 |
| 1 | 主卷描述符 |
| 2 | 补充卷描述 |
| 3 | 卷分区描述符 |
| 4-254 | 保留 |
| 255 | 卷描述符集合终结器 |
在开始使用基础光盘时,我们会关注主卷描述符,它指向根目录表和路径表,这两者都允许我们查找光盘上的任何文件。使用路径表非常适合不希望逐节点搜索目录层级的最小实现。这虽然慢一些(整个文件系统中字符串比较),但实现起来更简单。
靴子唱片
第一种类型的卷描述符是“启动记录”。描述符格式如下:
| 抵消 | 长度(字节) | 场地名称 | 数据类型 | 描述 |
|---|---|---|---|---|
| 0 | 1 | 类型 | IN8 | 零表示启动记录。 |
| 1 | 5 | 标识符 | strA | 总是“CD001”。 |
| 6 | 1 | 版本 | IN8 | 卷描述符版本(0x01)。 |
| 7 | 32 | 启动系统标识符 | strA | 系统的ID,可以从启动记录中作并启动系统。 |
| 39 | 32 | 启动标识符 | strA | 识别该描述符中定义的启动系统。 |
| 71 | 1977 | 启动系统的使用 | - | 自定义——启动系统使用。 |
最常见的启动系统使用规范是El Torito。 它在第71至74字节处记录为小端序32位数字 埃尔托里托靴子目录的块地址。本目录列出了 可用的启动镜像,作为启动系统的起点。
主卷描述符
这是一个较长的描述,但它包含了一些非常有用的信息,用于读取文件系统的其余部分。
| 抵消 | 长度(字节) | 场地名称 | 数据类型 | 描述 |
|---|---|---|---|---|
| 0 | 1 | 类型代码 | IN8 | 一定要0x01主要卷描述。 |
| 1 | 5 | 标准标识符 | strA | 总是“CD001”。 |
| 6 | 1 | 版本 | IN8 | 总是0x01。 |
| 7 | 1 | 闲置 | - | 总是0x00。 |
| 8 | 32 | 系统标识符 | strA | 该系统名称,可以作用于该卷的扇区0x00-0x0F。 |
| 40 | 32 | 卷标识符 | strD | 本卷的识别。 |
| 72 | 8 | 未使用场地 | - | 全是零。 |
| 80 | 8 | 卷空间大小 | int32_LSB-MSB | 记录该卷的逻辑块数量。 |
| 88 | 32 | 未使用场地 | - | 全是零。 |
| 120 | 4 | 卷集大小 | int16_LSB-MSB | 该逻辑卷集合的大小(磁盘数量)。 |
| 124 | 4 | 卷序号 | int16_LSB-MSB | 该磁盘在卷集中的编号。 |
| 128 | 4 | 逻辑块大小 | int16_LSB-MSB | 逻辑块的字节大小。注意:这意味着CD上的逻辑块可以不是2 KiB! |
| 132 | 8 | 路径表大小 | int32_LSB-MSB | 路径表的字节大小。 |
| 140 | 4 | Type-L 路径表的位置 | int32_LSB | 路径表的LBA位置。所指向的路径表仅包含小端值。 |
| 144 | 4 | 可选的Type-L路径表的位置 | int32_LSB | 可选路径表的LBA位置。所指向的路径表仅包含小端值。零表示不存在可选路径表。 |
| 148 | 4 | 类型M路径表的位置 | int32_MSB | 路径表的LBA位置。所指向的路径表只包含大端值。 |
| 152 | 4 | 可选 Type M 路径表的位置 | int32_MSB | 可选路径表的LBA位置。所指向的路径表只包含大端值。零表示不存在可选路径表。 |
| 156 | 34 | 根目录的目录条目 | - | 注意,这不是 LBA 地址,而是实际的目录记录,包含一个字节的目录标识符(0x00),因此固定为 34 字节大小。 |
| 190 | 128 | 卷集标识符 | strD | 该卷所属卷集的标识符。 |
| 318 | 128 | 出版商标识 | strA | 卷册出版商。对于扩展发布者信息,应先0x5F第一个字节,后面是根目录中文件的文件名。如果未指定,所有字节都应0x20。 |
| 446 | 128 | 数据预报器标识符 | strA | 为本卷准备数据的人员标识。为了获得扩展的准备信息,第一个字节应被0x5F,后面是根目录中文件的文件名。如果未指定,所有字节都应0x20。 |
| 574 | 128 | 应用标识符 | strA | 识别数据如何记录在本卷上。为了获取扩展信息,应先0x5F第一个字节,后面是根目录中文件名。如果未指定,所有字节都应0x20。 |
| 702 | 37 | 版权文件标识符 | strD | 根目录中包含该卷集版权信息的文件名。如果未指定,所有字节都应0x20。 |
| 739 | 37 | 抽象文件标识符 | strD | 根目录中包含该卷集抽象信息的文件名。如果未指定,所有字节都应0x20。 |
| 776 | 37 | 书目文件标识符 | strD | 根目录中包含该卷集书目信息的文件名。如果未指定,所有字节都应0x20。 |
| 813 | 17 | 卷册创建日期和时间 | 十二月-日期时间 | 卷的创建日期和时间。 |
| 830 | 17 | 卷次修改日期和时间 | 十二月-日期时间 | 该卷被修改的日期和时间。 |
| 847 | 17 | 卷册到期日期和时间 | 十二月-日期时间 | 该卷册之后被视为过时的时间和日期。如果未指定,则该卷永远不会被视为过时。 |
| 864 | 17 | 批量生效日期和时间 | 十二月-日期时间 | 该卷可使用的时间和日期。如果未特别说明,可以立即使用该卷。 |
| 881 | 1 | 文件结构版本 | IN8 | 目录记录和路径表版本(始终0x01)。 |
| 882 | 1 | 闲置 | - | 总是0x00。 |
| 883 | 512 | 应用 | - | 内容未被ISO 9660定义。 |
| 1395 | 653 | 保留 | - | 由ISO预留。 |
卷描述符集合终结器
卷描述符集终结符目前不定义其卷描述符的字节7-2047。这意味着卷集终端码仅使用类型代码(255)、标准标识符(“CD001”)和描述符版本(0x01)。
| 抵消 | 长度(字节) | 场地名称 | 数据类型 | 描述 |
|---|---|---|---|---|
| 0 | 1 | 类型 | IN8 | 255表示卷描述符集终端。 |
| 1 | 5 | 标识符 | strA | 总是“CD001”。 |
| 6 | 1 | 版本 | IN8 | 卷描述符版本(0x01)。 |
路径表
路径表包含一个有序的记录序列,描述光盘上每个目录范围。但有一些例外:路径表只能包含65536条记录,这主要是由于“父目录号”字段的长度。如果光盘上的目录数量超过这个数,一些CD制作软件会忽略这一限制,生成不合规的CD(例如,某些早期版本的Nero也是如此)。如果你的文件系统使用路径表,你应该注意这种可能性。Windows 使用路径表,遇到不合规的 CD 会失败(虽然存在额外节点但显示为零字节)。使用目录表的Linux不受此问题影响。
路径表的位置可在主卷描述符中找到。有两种表类型——L-Path 表(与 x86 相关)和 M-Path 表。这两个表的唯一区别是,L表中的多字节值优先为 LSB,而 M 表中的值为 MSB 优先。
路径表条目的结构如下:
| 抵消 | 大小 | 描述 |
|---|---|---|
| 0 | 1 | 目录标识符的长度 |
| 1 | 1 | 扩展属性记录长度 |
| 2 | 4 | 范围位置(LBA)。根据是L表还是M表,格式不同(见上文解释)。 |
| 6 | 2 | 父目录的目录号(路径表中的索引)。这是将表格限制为65536条记录的字段。 |
| 8 | (变量) | 目录标识符(名称)以d字符表示。 |
| (变量) | 1 | 填充字段——如果目录标识符长度字段为奇数,则包含零,否则不存在。这意味着每个表条目始终从偶数字节开始。 |
路径表按目录层级的升序排列,并在每个目录层级内按字母顺序排序。
目录
在从 ISO 9660 CD 读取时,某个阶段你需要目录记录来定位文件,即使你通常最初使用路径表来定位该目录。与路径表不同,每个目录表只有一个版本,且多字节编号采用双端序格式。每个目录开头有两个特殊条目:一个空字符串,描述“.”条目;字符串“\1”,描述“..”条目。目录记录的布局如下:
| 抵消 | 大小 | 类型 | 描述 |
|---|---|---|---|
| 0 | 1 | IN8 | 目录记录长度。 |
| 1 | 1 | IN8 | 扩展属性记录长度。 |
| 2 | 8 | int32_LSB-MSB | 范围位置(LBA)双端格式。 |
| 10 | 8 | int32_LSB_MSB | 数据长度(范围大小)以双端格式表示。 |
| 18 | 7 | 格式见下文 | 录制日期和时间。 |
| 25 | 1 | 见下文 | 归档旗标。 |
| 26 | 1 | IN8 | 在交错模式下记录的文件单元大小为零。 |
| 27 | 1 | IN8 | 以交错模式记录的文件为间隙大小,否则为零。 |
| 28 | 4 | int16_LSB-MSB | 卷序列号——该区段记录的卷,采用16位双端格式。 |
| 32 | 1 | IN8 | 文件标识符(文件名)长度。该序列以 ';' 字符结束,后跟文件 ID 编号(ASCII 编码的十进制数字 '1')。 |
| 33 | (变量) | strD | 文件标识符。 |
| (变量) | 1 | -- | 填充字段——如果文件标识符长度为偶数,则为零,否则该字段不存在。这意味着目录条目总是从偶数字节开始。 |
| (变量) | (变量) | -- | 系统使用—— 剩余的字节可使用,最大记录大小为255 用于ISO 9660的扩展。最常见的是系统使用共享 协议(SUSP)及其应用,洛克岭交换协议 (RRIP) |
即使目录跨越多个扇区,目录条目也不允许跨越扇区边界(不同于路径表)。当一个扇区末尾没有足够空间记录整个目录条目时,该扇区填充为零,使用下一个连续扇区。上述一些字段需要解释。遗憾的是,日期/时间格式与主卷描述符中使用的不同。日期/时间格式如下:
| 抵消 | 大小 | 描述 |
|---|---|---|
| 0 | 1 | 自1900年以来的年数。 |
| 1 | 1 | 一年中的月份,从1点到12点。 |
| 2 | 1 | 每月1号到31号。 |
| 3 | 1 | 一天中的一个小时,从0到23。 |
| 4 | 1 | 0到59分钟。 |
| 5 | 1 | 第二分钟,从0到59。 |
| 6 | 1 | 格林威治标准时间以15分钟为间隔偏移,从-48(西)到+52(东)。 |
这与包含ASCII编码十进制值的PVD形成了鲜明对比,但这种格式大概是为了节省大量条目中的光盘空间。
另一个需要解释的字段是文件标志字段。这用一位标志表示如下:
| 位 | 描述 |
|---|---|
| 0 | 如果设置为,用户无需知道该文件的存在(基本上是一个“隐藏”标志)。 |
| 1 | 如果设置为,该记录描述一个目录(换句话说,它是一个子目录的扩展)。 |
| 2 | 如果设置为,该文件是一个“关联文件”。 |
| 3 | 如果设置为,扩展属性记录包含该文件格式的信息。 |
| 4 | 如果设置,扩展属性记录中会设置所有者和组权限。 |
| 5 和 6 | 保留 |
| 7 | 如果设置为如此,这不是该文件的最终目录记录(对于跨多个时段的文件,例如超过4GiB的文件)。 |
在光盘上定位数据
到现在为止,你应该能看到有两种主要方式可以导航到文件记录。你可以搜索路径表,或者搜索完整的目录结构。你可能会发现缓存路径表更方便、更快,只在必要时加载目录。
路径表搜索
如果你使用路径表方法,仍然需要了解目录记录来找到你想要的文件。基本上,你要逆序搜索路径,沿着路径表中的“父目录”链接。找到包含你想要文件的目录后,加载该目录并扫描合适的文件名。
从根目录递归
或者,你可以忽略路径表,只缓存主卷描述符里的根目录。然后你依次加载每个目录。例如,对于路径 '/BOOT/MYLOADER/STAGE2.垃圾
- 把PVD读入内存。字节156-189包含根目录条目。
- 通过读取根目录条目中的 LBA 和 Length 值来加载根目录。
- 扫描目录条目标识符中的“BOOT;1'.
- 如果找到,使用LBA和长度值将“BOOT”目录加载到内存中。
- 重复步骤3和4,以识别文件标识符“MYLOADER;1'.
- 扫描“MYLOADER”目录中的“STAGE2”。站;1'。如果找到了,你现在可以用LBA值将文件加载到内存中。
洛克岭与乔利埃特
ISO 9660有两项改进,使其更适合 Unix和MS-Windows的世界。两者可以合并成同一类 文件系统。所以读者通常可以选择三个文件名 空间:Plain ISO、Rock Ridge、Joliet。
ISO 和 Rock Ridge 会显示相同的文件树,但名称不同。 Joliet可以显示与ISO完全不同的树。
Rock Ridge 支持最多 255 字符的 8 位文件名。只 0字节和斜杠(“/”)不可使用。进一步添加 文件属性由POSIX指定(所有者、组、权限,...) 并且允许符号性联系。
Rock Ridge 是 SUSP 的一个应用。它可能伴随其他 SUSP应用如zisofs(数据文件压缩,Linux 特定)、Apple ISO 9660扩展、Amiga AS条目或任意 属换协议(AAIP:扩展属性与ACL)。 SUSP 条目读取者应直接忽略所有条目类型 而这并非它的预期。
Joliet 由 Microsoft Inc. 定义,允许文件名为 最多支持64个UCS-2字符(16位)。它是独立实现的 目录记录树,该树以根记录开始于 补充卷描述。该描述符类似于 主卷描述符,但类型代码为2。
6791

被折叠的 条评论
为什么被折叠?



