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_CTRL0x1F0/0x3F6,SECONDARY_CMD/SECONDARY_CTRL0x170/0x376). QEMU’s-cdromshorthand attaches the disc on the secondary channel (master), whichAtapiDevice::probescans 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 isATAPI_SIG_MID(0x14) in the LBA-mid register andATAPI_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
IsoFsparser indexes. The relevant structures are the primary volume descriptor (PVD) and the directory record.
- 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
- 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 protocolREG_LBA_MID/REG_LBA_HIGHcarry 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-blockCTRL_NIEN(0x02, interrupts disabled — this path is polled only) andCTRL_SRST(0x04, soft reset insoft_reset). Drive select isDRIVE_MASTER(0xA0) /DRIVE_SLAVE(0xB0). - Probe / detect:
AtapiDevice::probesoft-resets each channel and callsdetect, which selects a drive and matches theATAPI_SIG_MID/ATAPI_SIG_HIGHsignature; a0xFFstatus is treated as a floating (empty) bus. Every status spin is bounded bySPIN_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): writesCMD_PACKET(0xA0) to the command register, programs the per-block byte-count limitBYTE_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 overBYTE_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 inAtapiDevice::read_sectors), andCDB_READ_CAPACITY10(0x25, inAtapiDevice::read_capacity) returning the last addressable LBA and the logical block size. A reported block size is range-checked againstMIN_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 thancount * 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::mountreadsPVD_LBA(sector 16, after the reserved system area) throughread_sectorsand validates the descriptor type (pvd[0] == 1), theCD001standard 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 withle_u16/le_u32. It indexes the logical block size (both-endianu16at offset 128, which must equal the device block size), the volume space size (both-endianu32at offset 80), and the embedded root directory record (34-byteMIN_DIR_RECORDat offset 156, whose extent LBA is bytes 2..6 and size bytes 10..14). - Directory records:
IsoFs::lookup/list_boot_binswalk 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 carriesFILE_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 (identifier0x00/0x01) are skipped, and identifiers are matched case-insensitively after stripping the;versionsuffix and trailing dots (name_matches/normalize_ident). - Path resolution:
IsoFs::lookup_pathdescends from the root through each component;boot_bins_dirresolves/boot/bins/andopen_fileresolves 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/DMAPoolprovider 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_sourcefor the reader itself.- Under
boot_iso_readthe kernel runsiso::boot_read_proof/iso::boot_fs_proof(called fromkernel/src/main.rs) to exercise the device-read primitive and the ISO 9660 walk. - Under
boot_isothe reader is the live boot-binary source:iso::boot_source::init(inkernel/src/main.rsrun_init) builds a registry resolving each declared manifest binary name to its(lba, size)extent viaopen_file(name mapping throughiso_dname, which applies the ISO 9660 d-character substitutionxorrisorecords), andiso::boot_source::read_binaryreads each ELF on demand. The device is owned by the registry and serialized behind aMutexso concurrent spawns on multiple CPUs do not interleave PIO transfers on the shared IDE channel.
- Under
Directory/Filecap fixture: the read path has no caps of its own, but theinstallable_imagecap (kernel/src/cap/installable_image.rs) layers a read-onlyDirectory/FileCapObjectover 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-gatedinstallable_image_source(KernelCapSource::InstallableImageSource);Directory.list/Directory.open+File.read/File.statare 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_extentat mount/open,AtapiDevice::read_sectorsrange 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/outvia the module’sinb/outb/inw/outwhelpers), 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 atMAX_DIR_BYTESand records are length/identifier-bounded before trusting them; capacity and buffer-length checks gateread_sectors; block size is floored/ceiled toMIN_BLOCK_SIZE/MAX_BLOCK_SIZE; and every status wait isSPIN_LIMIT-bounded. All failure modes funnel throughIsoError(NoDevice/Timeout/DeviceError/Protocol/InvalidRequest/OutOfRange/BufferTooSmall/ShortRead/BadVolume/NotFound/NotDirectory). - QEMU-emulable vs hardware-only: fully QEMU-emulable. QEMU’s
-cdromattaches an ATAPI CD-ROM on the secondary legacy IDE channel.make run-boot-iso-readproves the bounded ATAPI PIO read primitive and the ISO 9660 walk;make run-boot-isoand the defaultmake run-smokeprove the live on-demand boot-binary load path; andmake run-installable-image-sourceproves the read-onlyDirectory/Fileinstall-source fixture layered over the reader. No hardware-only path.
Related
kernel/src/iso/mod.rs— the ATAPI PIO reader, the ISO 9660IsoFsdriver, theboot_isoboot_sourceregistry, and the boot-time proofs.kernel/src/cap/installable_image.rs— the read-onlyDirectory/Filecap surface layered over this reader.kernel/src/main.rs—run_initISO boot-binary registry build and on-demand ELF load underboot_iso.