# ATAPI CD-ROM + ISO 9660 (boot-time reader)

This is a provenance map for the boot-time CD-ROM read path: it cites the
specs, summarizes only the wire-format subset the code actually implements, and
points into the implementation. It is not a re-spec. Unlike the PCI/virtio
device pages, this is a **legacy port-I/O** hardware transport used only during
boot or install-source proofs to read ELF/package bytes from an ISO; the
capOS-mapping section reflects its boot-only, kernel-owned status. The boot
source itself is planned CD-ROM/ISO support, not a deprecated path. The driver
is concise and feature-gated (`boot_iso_read` / `boot_iso`), so the treatment is
a short map rather than exhaustive register tables.

The whole reader lives in `kernel/src/iso/mod.rs`.

## 1. Spec basis

- **Device**: ATAPI CD-ROM on a legacy IDE (Parallel ATA) channel, accessed by
  polled PIO over the legacy I/O ports. Not a PCI/virtio device and not
  enumerated through PCI; the two legacy channels are probed at fixed port
  bases (`PRIMARY_CMD`/`PRIMARY_CTRL` `0x1F0`/`0x3F6`,
  `SECONDARY_CMD`/`SECONDARY_CTRL` `0x170`/`0x376`). QEMU's `-cdrom` shorthand
  attaches the disc on the secondary channel (master), which `AtapiDevice::probe`
  scans first.
- **Authoritative specs**:
  - *ATA Packet Interface* — the PACKET command transport and the
    ATA/ATAPI register protocol, as standardized in the SFF-8020i /
    ATA/ATAPI-4+ family (INCITS T13). The PACKET data-in handshake, the ATAPI
    signature in the cylinder-low/high (LBA mid/high) registers, and the
    `READ(12)` / `READ CAPACITY(10)` command-descriptor blocks come from this
    basis. The signature the driver matches is `ATAPI_SIG_MID` (`0x14`) in the
    LBA-mid register and `ATAPI_SIG_HIGH` (`0xEB`) in the LBA-high register.
  - *ECMA-119* (equivalently ISO 9660), *Volume and File Structure of CDROM for
    Information Interchange* — the volume-descriptor and directory-record
    on-disk layout the `IsoFs` parser indexes. The relevant structures are the
    primary volume descriptor (PVD) and the directory record.
- **Reference**: the legacy IDE/ATAPI PIO sequence and the ISO 9660 fixed-offset
  field layout are the well-documented OSDev-wiki "ATAPI"/"ISO 9660" baseline;
  cross-checked against the QEMU IDE/ATAPI device behavior the proofs run
  against.

## 2. Wire format (implemented subset)

Only the polled-PIO read subset the driver uses is summarized; ATA features the
driver never issues (DMA transfers, write commands, the full SCSI command set)
are not implemented and are not transcribed here.

### ATAPI PACKET read path

- **Channel register map**: command-block register offsets relative to the
  channel command base — `REG_DATA` (0), `REG_FEATURES` (1), `REG_SECCOUNT` (2),
  `REG_LBA_LOW` (3), `REG_LBA_MID` (4), `REG_LBA_HIGH` (5), `REG_DRIVE` (6),
  `REG_STATUS`/`REG_COMMAND` (7). In the ATAPI PACKET protocol `REG_LBA_MID` /
  `REG_LBA_HIGH` carry the **byte-count** low/high for the data phase, not an
  LBA.
- **Status / control bits**: `STATUS_BSY` (`0x80`), `STATUS_DRQ` (`0x08`),
  `STATUS_ERR` (`0x01`); control-block `CTRL_NIEN` (`0x02`, interrupts disabled —
  this path is polled only) and `CTRL_SRST` (`0x04`, soft reset in `soft_reset`).
  Drive select is `DRIVE_MASTER` (`0xA0`) / `DRIVE_SLAVE` (`0xB0`).
- **Probe / detect**: `AtapiDevice::probe` soft-resets each channel and calls
  `detect`, which selects a drive and matches the `ATAPI_SIG_MID` /
  `ATAPI_SIG_HIGH` signature; a `0xFF` status is treated as a floating (empty)
  bus. Every status spin is bounded by `SPIN_LIMIT` (`wait_not_busy` /
  `wait_drq`), so an absent or wedged device fails closed rather than hanging
  boot.
- **PACKET command issue** (`AtapiDevice::packet_data_in`): writes `CMD_PACKET`
  (`0xA0`) to the command register, programs the per-block byte-count limit
  `BYTE_LIMIT` (`2048`, one CD logical sector) into the LBA mid/high registers,
  waits for DRQ, then writes the 12-byte command-descriptor block (CDB) as six
  16-bit words. The data-in phase reads each DRQ block, taking its byte count
  from the LBA mid/high registers; it rejects a byte count over `BYTE_LIMIT`, an
  odd byte count, or one that would overflow the destination buffer
  (`IsoError::Protocol` / `BufferTooSmall`).
- **CDBs implemented**: `CDB_READ12` (`0xA8`) with the big-endian LBA at bytes
  2..6 and transfer length at bytes 6..10 (built in `AtapiDevice::read_sectors`),
  and `CDB_READ_CAPACITY10` (`0x25`, in `AtapiDevice::read_capacity`) returning
  the last addressable LBA and the logical block size. A reported block size is
  range-checked against `MIN_BLOCK_SIZE` (`2048`) / `MAX_BLOCK_SIZE` (`4096`).
- **Bounded sector read** (`AtapiDevice::read_sectors`): rejects a zero count,
  arithmetic overflow (`IsoError::InvalidRequest`), an LBA range past the
  reported capacity (`OutOfRange`), and a destination buffer shorter than
  `count * block_size` (`BufferTooSmall`), all before any device access. A device
  that returns fewer bytes than requested is rejected (`ShortRead`).

### ISO 9660 volume structure

- **Primary volume descriptor**: `IsoFs::mount` reads `PVD_LBA` (sector 16, after
  the reserved system area) through `read_sectors` and validates the descriptor
  type (`pvd[0] == 1`), the `CD001` standard identifier (`pvd[1..6]`), and the
  version (`pvd[6] == 1`). ISO 9660 stores integers **both-endian** (a
  little-endian half followed by a big-endian half); the driver reads the
  little-endian half with `le_u16` / `le_u32`. It indexes the logical block size
  (both-endian `u16` at offset 128, which must equal the device block size), the
  volume space size (both-endian `u32` at offset 80), and the embedded root
  directory record (34-byte `MIN_DIR_RECORD` at offset 156, whose extent LBA is
  bytes 2..6 and size bytes 10..14).
- **Directory records**: `IsoFs::lookup` / `list_boot_bins` walk a directory
  extent record by record. Each record's length is byte 0 (a zero length skips
  to the next logical-sector boundary); the file-flags byte 25 carries
  `FILE_FLAG_DIR` (`0x02`); the file-identifier length is byte 32 and the
  identifier starts at byte 33; the extent LBA/size are bytes 2..6 / 10..14. The
  `.`/`..` self/parent records (identifier `0x00`/`0x01`) are skipped, and
  identifiers are matched case-insensitively after stripping the `;version`
  suffix and trailing dots (`name_matches` / `normalize_ident`).
- **Path resolution**: `IsoFs::lookup_path` descends from the root through each
  component; `boot_bins_dir` resolves `/boot/bins/` and `open_file` resolves a
  named file beneath it, each returning a validated `(lba, size)` extent.

## 3. capOS mapping

- **Binding (boot-only, kernel-owned)**: this is not a DDF device. It is **not**
  enumerated through PCI and does **not** bind through the
  `DeviceMmio`/`Interrupt`/`DMAPool` provider grants the cloud-NIC/storage
  drivers use; it owns fixed legacy I/O ports directly in kernel mode and runs
  only during boot. There is no userspace driver and no `*_grant_source` for the
  reader itself.
  - Under `boot_iso_read` the kernel runs `iso::boot_read_proof` /
    `iso::boot_fs_proof` (called from `kernel/src/main.rs`) to exercise the
    device-read primitive and the ISO 9660 walk.
  - Under `boot_iso` the reader is the live boot-binary source:
    `iso::boot_source::init` (in `kernel/src/main.rs` `run_init`) builds a
    registry resolving each declared manifest binary name to its `(lba, size)`
    extent via `open_file` (name mapping through `iso_dname`, which applies the
    ISO 9660 d-character substitution `xorriso` records), and
    `iso::boot_source::read_binary` reads each ELF on demand. The device is owned
    by the registry and serialized behind a `Mutex` so concurrent spawns on
    multiple CPUs do not interleave PIO transfers on the shared IDE channel.
- **`Directory`/`File` cap fixture**: the read path has no caps of its own, but
  the `installable_image` cap (`kernel/src/cap/installable_image.rs`) layers a
  **read-only** `Directory`/`File` `CapObject` over this reader for the focused
  QEMU install-source proof. It exposes the packaged `/boot/bins/` tree to the
  installer smoke only; it is not a general post-bootstrap ISO filesystem
  service. It is granted via the qemu-gated `installable_image_source`
  (`KernelCapSource::InstallableImageSource`); `Directory.list`/
  `Directory.open` + `File.read`/`File.stat` are served and every mutating method
  fails closed (read-only is structural, not a rights flag). It reuses the
  driver's in-bounds checks (`IsoFs::validate_extent` at mount/open,
  `AtapiDevice::read_sectors` range validation per read) and is physically
  scoped to the ATAPI medium, so it cannot reach the writable virtio-blk target
  disk.
- **MMIO / Interrupt / DMA**: none. Access is legacy port I/O (`in`/`out` via the
  module's `inb`/`outb`/`inw`/`outw` helpers), not memory-mapped BARs. Interrupts
  are disabled (`CTRL_NIEN`) and the path is polled PIO, so there is no MSI/MSI-X
  vector binding. Transfers move through the data register word by word, so there
  is no DMA buffer and no IOMMU/bounce-buffer involvement.
- **Fail-closed / validation rules**: every derived extent is validated against
  the volume size (`IsoFs::validate_extent`) before it is read, so a malformed or
  hostile volume cannot drive an out-of-bounds device read; directory extents are
  capped at `MAX_DIR_BYTES` and records are length/identifier-bounded before
  trusting them; capacity and buffer-length checks gate `read_sectors`; block
  size is floored/ceiled to `MIN_BLOCK_SIZE`/`MAX_BLOCK_SIZE`; and every status
  wait is `SPIN_LIMIT`-bounded. All failure modes funnel through `IsoError`
  (`NoDevice`/`Timeout`/`DeviceError`/`Protocol`/`InvalidRequest`/`OutOfRange`/
  `BufferTooSmall`/`ShortRead`/`BadVolume`/`NotFound`/`NotDirectory`).
- **QEMU-emulable vs hardware-only**: fully QEMU-emulable. QEMU's `-cdrom`
  attaches an ATAPI CD-ROM on the secondary legacy IDE channel. `make
  run-boot-iso-read` proves the bounded ATAPI PIO read primitive and the ISO 9660
  walk; `make run-boot-iso` and the default `make run-smoke` prove the live
  on-demand boot-binary load path; and `make run-installable-image-source`
  proves the read-only `Directory`/`File` install-source fixture layered over
  the reader. No hardware-only path.

## Related

- `kernel/src/iso/mod.rs` — the ATAPI PIO reader, the ISO 9660 `IsoFs` driver,
  the `boot_iso` `boot_source` registry, and the boot-time proofs.
- `kernel/src/cap/installable_image.rs` — the read-only `Directory`/`File` cap
  surface layered over this reader.
- `kernel/src/main.rs` — `run_init` ISO boot-binary registry build and on-demand
  ELF load under `boot_iso`.
