В отличие от блочных устройств символьные устройства посылают поток данных. Все последовательные устройства являются символьными. Когда мы используем классический пример контроллера клавиатуры или последовательного терминала в качестве символьного устройства, становится интуитивно понятным, что мы не можем (и не хотим) получать данные от устройства не по порядку. Так мы подходим к серой области пакетной передачи данных. Сеть Ethernet на физическом уровне является последовательным устройством, но на уровне шины используется DMA для передачи в память и из памяти больших порций данных.
Как разработчики драйвера устройства мы можем сделать с устройством что угодно, но на практике мы редко будем получать случайный доступ к аудиопотоку или писать поток на IDE-диск. Несмотря на то что оба примера звучат заманчиво, мы должны придерживаться двух простых правил:
• все устройства ввода-вывода в Linux основаны на файлах;
• все устройства ввода-вывода в Linux являются либо символьными, либо блочными.
Драйвер параллельного порта в конце этой главы - символьный драйвер устройства. Символьные и блочные устройства схожи между собой интерфейсом, основанным на файловом вводе-выводе. Извне оба типа используют файловые операций, такие, как open, close, read и write. Внутри самое главное различие между символьными драйверами устройств и блочными драйверами устройств заключается в том, что символьные устройства не обладают системой блокировки для очередей запросов операций на чтение и на запись (как было сказано ранее). Зачастую для не имеющих буфера символьных устройств прерывание выполняется для каждого полученного элемента (символа). Для блочных устройств, наоборот, получается целая порция (порции) данных и затем для этой порции вызывается прерывание.