Задачи, стоящие перед программным обеспечением ввода-вывода
Ключевая концепция разработки программного обеспечения ввода-вывода известна как независимость от конкретных устройств. Ее смысл заключается в предоставлении возможности создания программ, способных получить доступ к любому устройству ввода-вывода без необходимости предварительного определения устройства- К примеру, программа, считывающая входной файл, должна иметь возможность читать его с жесткого диска, компакт-диска, DVD или флэш-накопителя USB без изменения программы под каждое конкретное устройство. То есть любой пользователь должен получить возможность набрать команду типа
sort <input >output
и убедиться, что она работает с входными данными, поступающими с диска любого типа или с клавиатуры, и с выходными данными, отправляемыми на диск любого типа или на экран. Решение всех проблем, связанных с разнородностью этих устройств и с тем, что для них требуются существенно отличающиеся друг от друга последовательности команд для чтения или записи, возлагается на операционную систему.
С независимостью от конкретного устройства тесно связана и задача однообразного именования. Имя файла или устройства должно быть просто строкой или целым числом и никоим образом не зависеть от устройства. В UNIX все диски могут быть произвольным образом сгруппированы в иерархию файловой системы, поэтому пользователь не должен знать, какое имя какому устройству соответствует. Например, флэш-накопитель USB может быть подключен (смонтирован) к каталогу /usr/ast/backup, чтобы при копировании файла в каталог /usr/ast/backup/ monday происходило его копирование в каталог monday на этом флэш-накопителе. Таким образом, все файлы и устройства адресуются одинаково: по полному имени, включающему путь в файловой системе.
Другим важным аспектом программного обеспечения ввода-вывода является обработка ошибок. В общем-то, обработка ошибок должна осуществляться как можно ближе к аппаратуре. Если контроллер обнаружил ошибку чтения, он должен попытаться, если это возможно, исправить ее самостоятельно. Если он не в состоянии с ней справиться, то ее должен обработать драйвер устройства, возможно, путем повторной попытки чтения блока. Многие ошибки носят случайный характер, как, например, ошибки чтения, вызванные пылинками на головке чтения, и зачастую исчезают при повторе операции. Верхние уровни должны осведомляться о возникшей проблеме только в том случае, если с ней не удалось справиться на нижних уровнях. Во многих случаях устранение ошибки может быть произведено незаметно, на нижних уровнях, так, чтобы верхние уровни даже не знали о ее существовании.
Еще один ключевой вопрос — какой способ применить для передачи данных: синхронный (блокирующий) или асинхронный (управляемый с помощью прерываний). Большинство физических операций ввода-вывода осуществляется в асинхронном режиме: центральный процессор инициирует передачу данных и устраняется от нее для выполнения каких-нибудь других задач, до тех пор пока не поступит прерывание. А вот прикладные программы значительно легче писать, если операции ввода-вывода осуществляются в блокирующем режиме: после системного вызова read программа автоматически приостанавливается до тех пор, пока данные не поступят в буфер. На операционную систему возлагается задача, чтобы фактически управляемые с помощью прерываний операции выглядели для пользовательской программы как блокирующие.

