> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/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 大幅重写。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man4/fdc.4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
