> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/man4/fdc.4.md).

# fdc(4)

`fdc` — PC 架构软盘控制器驱动程序

## 名称

`fdc`

## 概要

`device fdc`

`在 /boot/device.hints 中： hint.fdc.0.at="isa" hint.fdc.0.port="0x3F0" hint.fdc.0.irq="6" hint.fdc.0.drq="2" hint.fdc.0.flags="0x0" hint.fd.0.at="fdc0" hint.fd.0.drive="0" hint.fd.0.flags="0x0" hint.fd.1.at="fdc0" hint.fd.1.drive="1" hint.fd.1.flags="0x0"`

## 弃用通知

`fdc` 驱动程序已弃用，在 FreeBSD 16.0 及以后版本中可能不再存在。

## 描述

### 设备用法

本驱动程序提供对软盘驱动器的访问。可处理使用 FM（单密度）或 MFM（双密度或高密度）记录的软盘。

每个软盘控制器最多可连接四台驱动器。`fdc` 驱动程序目前每个控制器最多可处理两台驱动器（在 ACPI 上为四台）。驱动程序初始化时会尝试确定所用软盘控制器的类型。已知控制器类型包括原始的 NE765 或 i8272 芯片，或者与 NE72065 或 i82077 芯片兼容的*增强型*控制器。这些增强型控制器（除其他增强功能外）实现了用于软盘数据传输的 FIFO，一旦检测到增强型芯片就会自动启用。此 FIFO 激活可通过控制器标志值 `0x1` 禁用。

默认情况下，本驱动程序为每台已连接的、编号为 `N` 的驱动器创建单个设备节点 **/dev/fd**`N`。由于历史原因，也可以访问使用尾部 UFS 风格分区字母（从‘a’到‘h’）的设备节点，这些节点将作为主设备节点的符号链接实现。

访问主设备节点时会尝试自动检测多密度设备的可用介质密度。因此，可在高密度 3.5 英寸标准软盘驱动器中使用 720 KB 或 1440 KB 介质。通常，此自动检测仅在插入介质后首次调用 open(2) 时进行一次。这假定驱动器提供正确的换盘支持，以便驱动程序能检测到介质更换。对于没有换盘支持的驱动器，可通过驱动器设备标志值 `0x10` 覆盖（使每次调用 open(2) 都执行自动检测）。

尝试使用特殊密度介质的软盘设备时，可创建形式为 **/dev/fd**`N`.`MMMM` 的其他设备节点，其中 `N` 为驱动器号，`MMMM` 为描述设备密度的一到四位数字。每台驱动器最多可创建 15 个此类附加子设备。管理员可自行决定如何分配这些编号的策略。两种常见策略是实现编号 1 到 15 的子设备，或使用描述介质密度（千字节为单位）的数字。初始时，每个此类设备将配置为该驱动器类型可达到的最大密度（如 5.25 英寸 HD 驱动器为 1200 KB，3.5 英寸 HD 驱动器为 1440 KB）。需要使用 fdcontrol(8) 配置在该子设备上使用的所需密度。

驱动器类型通过驱动器设备标志的低四位配置。可指定以下值：

**`1`** 5.25 英寸双密度设备，40 磁道（原生容量 360 KB）

**`2`** 5.25 英寸高密度设备，80 磁道（原生容量 1200 KB）

**`3`** 3.5 英寸双密度设备，80 磁道（原生容量 720 KB）

**`4`** 3.5 英寸高密度设备，80 磁道（原生容量 1440 KB）

**`5`** 3.5 英寸超高密度设备，80 磁道（原生容量 2880 KB，目前使用限制为最多 1440 KB 介质）

**`6`** 与类型 5 相同，用于与某些 BIOS 兼容

在 IA32 架构上，驱动器类型可指定为 0。此时将查询 CMOS 配置内存以获取该驱动器的值。ACPI 探测会通过 \_FDE 和\_FDI 方法自动确定这些值，但可通过指定驱动器类型 hint 来覆盖。

通常，每个已配置的驱动器在初始化时会通过短寻道序列进行探测，以发现已配置但实际缺失或无响应的驱动器。（ACPI 探测方法不执行此寻道。）在某些环境（如带可拆卸驱动器的笔记本电脑）中，可能需要绕过此驱动器探测，假装驱动器存在，以便即使驱动器当前不存在驱动程序自动配置也能工作。为此，需指定驱动器设备标志值 `0x20`。

### 编程接口

除正常的读写功能外，`fdc` 驱动程序还通过 ioctl(2) 提供许多可配置选项。要访问这些功能，程序员需要在其程序中包含头文件

`#include <sys/fdcio.h>`

调用 open(2) 有两种方式。在未设置 `O_NONBLOCK` 标志的情况下打开设备时，以正常方式打开，主设备节点会执行自动介质密度选择，并返回一个完全可用于任何 I/O 操作或以下 ioctl(2) 命令的文件描述符。

设置 `O_NONBLOCK` 打开设备时，将绕过自动介质密度选择，设备保持半开状态。不能进行实际 I/O 操作，但可以执行下述许多 ioctl(2) 命令。此模式用于在无需可访问介质的情况下访问设备，如查询驱动器状态或格式化介质。在描述符上进行 I/O 操作前需清除 `O_NONBLOCK`，这要求事先使用 `FD_STYPE` 命令指定密度（见下文）。半开描述符上不允许的操作将导致错误码 Er EAGAIN。

目前可用的 ioctl(2) 命令如下：

**`FDOPT_NORETRY`** 失败时不自动重试操作。

**`FDOPT_NOERRLOG`** 不为失败的 I/O 操作记录“硬错误”内核日志。

**`FDOPT_NOERROR`** 从 read(2) 或 write(2) 系统调用返回时不指示 I/O 错误。假定调用者使用 `FD_GSTAT` 调用查询每个操作是否成功。这允许通过正常 I/O 操作检索坏块的错误数据。

**`FDOPT_AUTOSEL`** 设备执行自动密度选择。与上述标志不同，此标志为只读。

**`FD_FORM`** 用于格式化软盘介质。第三个参数是指向 `struct fd_formb` 的指针，指定要格式化的磁道及填入软盘介质 ID 字段的参数。

**`FD_GTYPE`** 返回所选设备的当前密度定义记录。第三个参数是指向 `struct fd_type` 的指针。

**`FD_STYPE`** 调整所选设备的密度定义。第三个参数是指向 `struct fd_type` 的指针。对于固定密度子设备（每台驱动器 1 到 15），此操作仅限具有超级用户权限的进程。对于自动选择子设备 0，临时允许任何进程执行此操作，但此设置在下一次自动选择时会丢失。这可用于格式化新介质时（需要使用 `O_NONBLOCK` 打开设备，随后使用 `FD_STYPE` 调整密度）。

**`FD_GOPTS`** 获取当前驱动器选项。第三个参数是指向 `int` 的指针，包含以下可能标志值的按位组合：

**`FD_SOPTS`** 设置设备选项，含义见上文。第三个参数是指向 `int` 的指针。关闭描述符时驱动器选项始终会被清除。

**`FD_CLRERR`** 清除内部低级错误计数器。通常，控制器级 I/O 错误最多记录到 `FDC_ERRMAX` 次（当前定义为 100）。此命令重置计数器。需要超级用户权限。

**`FD_READID`** 从软盘介质读取一个扇区 ID 字段。第三个参数是指向 `struct fdc_readid` 的指针，读取的数据将返回到此结构。可用于分析软盘介质。

**`FD_GSTAT`** 返回最近的软盘控制器状态（如果可用）。第三个参数是指向 `struct fdc_status` 的指针，返回状态寄存器（ST0、ST1、ST2、C、H、R 和 N）。若无最近状态可用则导致 Er EINVAL。

**`FD_GDTYPE`** 返回软盘驱动器类型。第三个参数是指向 `enum fd_drivetype` 的指针。此类型与驱动器配置标志中使用的类型相同，或在 IA32 系统上与 CMOS 配置数据或 ACPI 命名空间中使用的相同。

## SYSCTL 变量

**`0x01`** 复位时转储设备寄存器。

**`0x02`** 当 IO 操作完成且重试次数大于零时，打印重试次数。

**`0x04`** 当重试次数超过 `debug.fdc.retries`（`EIO`）时打印。当设置了 `FDOPT_NOERROR` 选项且写操作本应返回错误时打印。

**`0x08`** 打印详细的 IO 命令信息。

**`0x10`** 打印状态寄存器。

**`0x20`** 中断完成时打印详细状态寄存器。打印线程工作者操作非零返回附近的源代码行号。

**`0x40`** 当磁盘似乎丢失时打印。读取 ID 字段请求后打印柱面、磁头、扇区和扇区移位信息。通知磁盘探测是否找到磁盘。检测存在的介质密度时，指示自动感应是否成功，若成功则指示介质大小（千字节为单位）。设置驱动器类型时打印详细类型信息。

**`0x80`** 使用未知 IOCTL 时打印。

**`debug.fdc.debugflags`** 通过设置一个或多个标志来选择性启用调试。

**`debug.fdc.fifo`** 对于增强型控制器，允许设置非默认 FIFO 阈值。默认为 8 字节。

**`debug.fdc.retries`** 尝试的最大重试次数。默认为 10。

**`debug.fdc.spec1`** 规格字节一（步进速率 + 磁头卸载）。默认步进速率为 6 毫秒。默认磁头卸载时间为 240 毫秒。

**`debug.fdc.spec2`** 规格字节二（磁头加载时间 + no-dma）。默认磁头加载时间为 16 毫秒，no-dma 为 0（禁用）。

**`debug.fdc.settle`** 磁头稳定时间，单位为 **settle** / hz 秒。默认值在设备 attach 时设置。

## 文件

**`/dev/fd*`** 软盘设备节点

## 参见

fdread(1), fdwrite(1), ioctl(2), open(2), read(2), write(2), fdcontrol(8), fdformat(8)

## 作者

本手册页最初由 Wilko Bulte 编写，后由 J(:org Wunsch 大幅重写。
