# 20.5.创建和使用 CD

光盘（CD）介质提供了一些功能，使其与传统磁盘有所不同。它们的设计使得可以连续读取，而无需像传统硬盘那样在轨道之间移动磁头。虽然 CD 媒体也有轨道，但这些轨道指的是一段连续读取的数据，而不是磁盘的物理属性。ISO 9660 文件系统就是为了处理这些差异而设计的。

FreeBSD 的 Ports 提供了多个工具，用于刻录和复制音频和数据 CD。本章展示了多个命令行工具的使用方法。如果需要带有图形界面的光盘刻录软件，可以考虑安装 [sysutils/xcdroast](https://cgit.freebsd.org/ports/tree/sysutils/xcdroast/) 或 [sysutils/k3b](https://cgit.freebsd.org/ports/tree/sysutils/k3b/) 软件包和 Ports 。

## 20.5.1. 支持的设备

**GENERIC** 内核提供了对 SCSI、USB 和 ATAPICD 读取器及刻录机的支持。如果使用自定义内核，内核配置文件中需要根据设备类型添加相应的选项。

对于 SCSI 刻录机，确保在配置文件中有以下选项：

```sh
device scbus	# SCSI 总线（ATA/SCSI 必须）
device da	# 直接访问（磁盘）
device pass	# 直通设备（直接 ATA/SCSI 访问）
device cd	# 需要 CD 和 DVD 刻录机
```

对于 USB 刻录机，确保在配置文件中有以下选项：

```sh
device scbus	# SCSI 总线（ATA/SCSI 必须）
device da	# 直接访问（磁盘）
device pass	# 直通设备（直接 ATA/SCSI 访问）
device cd	# 需要 CD 和 DVD 刻录机
device uhci	# 提供 USB 1.x 支持
device ohci	# 提供 USB 1.x 支持
device ehci	# 提供 USB 2.0 支持
device xhci	# 提供 USB 3.0 支持
device usb	# USB 总线（必须）
device umass	# 磁盘/大容量存储 - 需要 scbus 和 da
```

对于 ATAPI 刻录机，确保在配置文件中有以下选项：

```sh
device ata	# 传统 ATA/SATA 控制器
device scbus# SCSI 总线（ATA/SCSI 必须）
device pass	# 直通设备（直接 ATA/SCSI 访问）
device cd	# 需要 CD 和 DVD 刻录机
```

> **注意**
>
> 在 FreeBSD 10.x 之前的版本中，如果刻录机是 ATAPI 设备，还需要在内核配置文件中添加这一行：`device atapicam`。或者，可以通过将以下行添加到 **/boot/loader.conf** 来在启动时加载此驱动程序：`atapicam_load="YES"`。这需要重启系统，因为该驱动程序只能在启动时加载。

要验证 FreeBSD 是否识别了设备，可以运行 `dmesg` 并查找设备的条目。在 10.x 之前的系统中，输出的第一行设备名称将是 **acd0** 而不是 **cd0**。

```sh
% dmesg | grep cd
cd0 at ahcich1 bus 0 scbus1 target 0 lun 0
cd0: <HL-DT-ST DVDRAM GU70N LT20> Removable CD-ROM SCSI-0 device
cd0: Serial Number M3OD3S34152
cd0: 150.000MB/s transfers (SATA 1.x, UDMA6, ATAPI 12bytes, PIO 8192bytes)
cd0: Attempt to query device size failed: NOT READY, Medium not present - tray closed
```

## 20.5.2. 刻录光盘

在 FreeBSD 中，可以使用 `cdrecord` 来刻录光盘。这个命令是通过安装 [sysutils/cdrtools](https://cgit.freebsd.org/ports/tree/sysutils/cdrtools/) 软件包和 Ports 来获得的。

尽管 `cdrecord` 有很多选项，但基本用法非常简单。指定要刻录的 ISO 文件的名称，并且如果系统有多个刻录设备，还需要指定要使用的设备名称：

```sh
# cdrecord dev=device imagefile.iso
```

要确定刻录机的设备名称，可以使用 `-scanbus`，这会返回类似下面的结果：

```sh
# cdrecord -scanbus
ProDVD-ProBD-Clone 3.00 (amd64-unknown-freebsd10.0) Copyright (C) 1995-2010 Jörg Schilling
Using libscg version 'schily-0.9'
scsibus0:
        0,0,0     0) 'SEAGATE ' 'ST39236LW       ' '0004' Disk
        0,1,0     1) 'SEAGATE ' 'ST39173W        ' '5958' Disk
        0,2,0     2) *
        0,3,0     3) 'iomega  ' 'jaz 1GB         ' 'J.86' Removable Disk
        0,4,0     4) 'NEC     ' 'CD-ROM DRIVE:466' '1.26' Removable CD-ROM
        0,5,0     5) *
        0,6,0     6) *
        0,7,0     7) *
scsibus1:
        1,0,0   100) *
        1,1,0   101) *
        1,2,0   102) *
        1,3,0   103) *
        1,4,0   104) *
        1,5,0   105) 'YAMAHA  ' 'CRW4260         ' '1.0q' Removable CD-ROM
        1,6,0   106) 'ARTEC   ' 'AM12S           ' '1.06' Scanner
        1,7,0   107) *
```

找到 CD 刻录机的条目，并将三个由逗号分隔的数字作为 `dev` 的值。在此示例中，Yamaha 刻录机设备为 `1,5,0`，因此指定该设备时应该使用 `dev=1,5,0`。请参阅 `cdrecord` 的手册页，了解指定该值的其他方法，以及关于写入音频轨道和控制写入速度的更多信息。

另外，可以运行以下命令来获取刻录机的设备地址：

```sh
# camcontrol devlist
<MATSHITA CDRW/DVD UJDA740 1.00>   at scbus1 target 0 lun 0 (cd0,pass0)
```

使用 `scbus`、`target` 和 `lun` 的数字值。在此示例中，应使用 `1,0,0` 作为设备名称。

## 20.5.3. 写入数据到 ISO 文件系统

为了制作数据光盘，必须在刻录到光盘之前准备好将成为光盘轨道的数据文件。在 FreeBSD 中，安装了 [sysutils/cdrtools](https://cgit.freebsd.org/ports/tree/sysutils/cdrtools/) 包后，可以使用 `mkisofs` 来生成一个 ISO 9660 文件系统，该文件系统是 UNIX® 文件系统中目录树的镜像。最简单的用法是指定要创建的 ISO 文件的名称以及要放入 ISO 9660 文件系统中的文件路径：

```sh
# mkisofs -o imagefile.iso /path/to/tree
```

该命令将指定路径中的文件名映射到符合标准 ISO 9660 文件系统限制的名称，并排除不符合 ISO 文件系统标准的文件。

有许多选项可以克服该标准所施加的限制。特别是，`-R` 启用 UNIX® 系统常用的 Rock Ridge 扩展，`-J` 启用 Microsoft® 系统使用的 Joliet 扩展。

对于仅在 FreeBSD 系统上使用的光盘，可以使用 `-U` 来禁用所有文件名限制。当与 `-R` 一起使用时，它会生成一个与指定的 FreeBSD 目录树完全相同的文件系统镜像，即使它违反了 ISO 9660 标准。

另一个常用选项是 `-b`。此选项用于指定启动镜像的位置，用于制作 "El Torito" 启动光盘。该选项需要一个参数，即位于要写入光盘的树结构顶部的启动镜像路径。默认情况下，`mkisofs` 在“软盘仿真”模式下创建 ISO 镜像，因此期望启动镜像的大小恰好为 1200、1440 或 2880 KB。某些引导加载程序，如 FreeBSD 分发媒体所使用的引导加载程序，不使用仿真模式。在这种情况下，应使用 `-no-emul-boot`。因此，如果 **/tmp/myboot** 包含一个可引导的 FreeBSD 系统，并且引导镜像位于 **/tmp/myboot/boot/cdboot**，则此命令将生成 **/tmp/bootable.iso**：

```sh
# mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/bootable.iso /tmp/myboot
```

生成的 ISO 镜像可以通过以下方式作为内存磁盘挂载：

```sh
# mdconfig -a -t vnode -f /tmp/bootable.iso -u 0
# mount -t cd9660 /dev/md0 /mnt
```

然后可以验证 **/mnt** 和 **/tmp/myboot** 是否相同。

`mkisofs` 还有许多其他选项，可以进一步调整其行为。请参阅 [mkisofs(8)](https://man.freebsd.org/cgi/man.cgi?query=mkisofs\&sektion=8\&format=html) 获取详细信息。

> **注意**
>
> 可以将数据光盘复制为一个功能上等效于通过 `mkisofs` 创建的镜像文件。为此，可以使用 **dd**，将设备名称作为输入文件，将要创建的 ISO 文件名作为输出文件：
>
> ```sh
> # dd if=/dev/cd0 of=file.iso bs=2048
> ```
>
> 生成的镜像文件可以像在 [刻录光盘](https://docs.freebsd.org/en/books/handbook/disks/#cdrecord) 中描述的那样刻录到光盘上。

## 20.5.4. 使用数据光盘

待 ISO 被刻录到光盘，它可以通过指定文件系统类型、包含光盘的设备名称和现有挂载点来挂载：

```sh
# mount -t cd9660 /dev/cd0 /mnt
```

由于 `mount` 假定文件系统类型为 `ufs`，如果在挂载数据光盘时未包含 `-t cd9660`，则会出现 `Incorrect super block` 错误。

虽然可以通过这种方式挂载任何数据光盘，但具有某些 ISO 9660 扩展的磁盘可能会表现得不太正常。例如，Joliet 磁盘将所有文件名存储为双字节 Unicode 字符。如果某些非英文字符显示为问号，则可以使用 `-C` 指定本地字符集。有关更多信息，请参阅 [mount\_cd9660(8)](https://man.freebsd.org/cgi/man.cgi?query=mount_cd9660\&sektion=8\&format=html)。

> **注意**
>
> 为了使用 `-C` 进行字符转换，内核需要加载 **cd9660\_iconv.ko** 模块。可以通过将以下行添加到 **loader.conf** 来实现：
>
> ```sh
> cd9660_iconv_load="YES"
> ```
>
> 然后重启计算机，或者通过直接加载模块使用 `kldload`。

有时，在尝试挂载数据光盘时会显示 `Device not configured`。这通常意味着 CD 驱动器未检测到托盘中的光盘，或者驱动器在总线上不可见。光盘驱动器检测介质可能需要几秒钟的时间，所以请耐心等待。

有时，SCSI CD 驱动器可能会因为没有足够的时间响应总线重置而被忽略。为了解决这个问题，可以创建一个自定义内核，增加默认的 SCSI 延迟。在自定义内核配置文件中添加以下选项，并按照 [“构建和安装自定义内核”](https://docs.freebsd.org/en/books/handbook/kernelconfig/#kernelconfig-building) 中的说明重新构建内核：

```ini
options SCSI_DELAY=15000
```

这告诉 SCSI 总线在启动时暂停 15 秒，以便给 CD 驱动器尽可能多的时间来响应总线重置。

> **注意**
>
> 可以直接将文件刻录到光盘，而无需创建 ISO 9660 文件系统。这被称为刻录原始数据光盘，有些人会为备份目的这样做。这种类型的光盘不能像普通数据光盘那样挂载。为了检索刻录到这样的光盘上的数据，必须从原始设备节点读取数据。例如，以下命令将提取位于第二张 CD 设备上的压缩 tar 文件到当前工作目录：
>
> ```sh
> # tar xzvf /dev/cd1
> ```
>
> 为了挂载数据光盘，数据必须使用 `mkisofs` 写入。

## 20.5.5. 复制音频光盘

要复制音频光盘，需要将音频数据从光盘提取到一系列文件中，然后将这些文件刻录到空白光盘上。

[复制音频光盘](https://docs.freebsd.org/en/books/handbook/disks/#using-cdrecord) 描述了如何复制和刻录音频光盘。如果 FreeBSD 版本低于 10.0，并且设备是 ATAPI，那么必须先加载 `atapicam` 模块，加载方法可以参考 [支持的设备](https://docs.freebsd.org/en/books/handbook/disks/#atapicam)。

**操作步骤：复制音频光盘**

1. 安装 [sysutils/cdrtools](https://cgit.freebsd.org/ports/tree/sysutils/cdrtools/) 软件包和 Ports 后，提供了 `cdda2wav` 命令。此命令可以提取所有音频轨道，每个轨道都写入当前工作目录中的单独 WAV 文件：

   ```sh
   % cdda2wav -vall -B -Owav
   ```

   如果系统中只有一个光盘设备，则不需要指定设备名称。请参阅 `cdda2wav` 的手册页，了解如何指定设备及其他可用选项。
2. 使用 `cdrecord` 将 **.wav** 文件刻录到光盘：

   ```sh
   % cdrecord -v dev=2,0 -dao -useinfo  *.wav
   ```

   请确保根据 [刻录光盘](https://docs.freebsd.org/en/books/handbook/disks/#cdrecord) 中的描述正确设置 *2,0*。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://handbook.bsdcn.org/di-20-zhang-cun-chu/20.5.-chuang-jian-he-shi-yong-cd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
