Типы устройств ввода-вывода Unix




Традиционно в ОС UNIX выделяются три типа организации ввода/вывода и, соответственно, три типа драйверов: блочный, символьный, потоковый.

Блочный ввод/вывод главным образом предназначен для работы с каталогами и обычными файлами файловой системы, которые на базовом уровне имеют блочную структуру. На пользовательском уровне возможно работать с файлами, прямо отображая их в сегменты виртуальной памяти. Эта возможность рассматривается как верхний уровень блочного ввода/вывода. На нижнем уровне блочный ввод/вывод поддерживается блочными драйверами. Блочный ввод/вывод, кроме того, поддерживается системной буферизацией*.

Символьный ввод/вывод служит для прямого (без буферизации) выполнения обменов между адресным пространством пользователя и соответствующим устройством. Общей для всех символьных драйверов поддержкой ядра является обеспечение функций пересылки данных между пользовательскими и ядерным адресными пространствами.

Наконец, потоковый ввод/вывод похож на символьный ввод/вывод, но по причине наличия возможности включения в поток промежуточных обрабатывающих модулей обладает существенно большей гибкостью.

Традиционным способом снижения накладных расходов при выполнении обменов с устройствами внешней памяти, имеющими блочную структуру, является буферизация блочного ввода/вывода. Это означает, что любой блок устройства внешней памяти считывается прежде всего в некоторый буфер области основной памяти, называемой в ОС UNIX системным кэшем, и уже оттуда полностью или частично (в зависимости от вида обмена) копируется в соответствующее пользовательское пространство.

Принципами организации традиционного механизма буферизации является, во-первых, то, что копия содержимого блока удерживается в системном буфере до тех пор, пока не возникнет необходимость ее замещения по причине нехватки буферов (для организации политики замещения используется разновидность алгоритма LRU. Во-вторых, при выполнении записи любого блока устройства внешней памяти реально выполняется лишь обновление (или образование и наполнение) буфера кэша. Действительный обмен с устройством выполняется либо при выталкивании буфера вследствие замещения его содержимого, либо при выполнении специального системного вызова sync (или fsync), поддерживаемого специально для насильственного выталкивания во внешнюю память обновленных буферов кэша.

Для доступа (т.е. для получения возможности последующего выполнения операций ввода/вывода) к файлу любого вида (включая специальные файлы) пользовательский процесс должен выполнить предварительное подключение к файлу с помощью одного из системных вызовов open, creat, dup или pipe.

Последовательность действий системного вызова open (pathname, mode) следующая:

- анализируется непротиворечивость входных параметров (главным образом, относящихся к флагам режима доступа к файлу);

- выделяется или находится пространство для описателя файла в системной области данных процесса (u-области);

- в общесистемной области выделяется или находится существующее пространство для размещения системного описателя файла (структуры file);

- производится поиск в архиве файловой системы объекта с именем " pathname" и образуется или обнаруживается описатель файла уровня файловой системы (vnode в терминах UNIX V System 4);

- выполняется связывание vnode с ранее образованной структурой file.

Системные вызовы open и creat (почти) функционально эквивалентны. Любой существующий файл можно открыть с помощью системного вызова creat, и любой новый файл можно создать с помощью системного вызова open. Однако, применительно к системному вызову creat мы должны подчеркнуть, что в случае своего естественного применения (для создания файла) этот системный вызов создает новый элемент соответствующего каталога (в соответствии с заданным значением p athname), а также создает и соответствующим образом инициализирует новый i-узел.

Наконец, системный вызов dup (duplicate - скопировать) приводит к образованию нового дескриптора уже открытого файла. Этот специфический для ОС UNIX системный вызов служит исключительно для целей перенаправления ввода/вывода. Его выполнение состоит в том, что в u-области системного пространства пользовательского процесса образуется новый описатель открытого файла, содержащий вновь образованный дескриптор файла (целое число), но ссылающийся на уже существующую общесистемную структуру file и содержащий те же самые признаки и флаги, которые соответствуют открытому файлу-образцу.

Другими важными системными вызовами являются системные вызовы read и write. Системный вызов read выполняется следующим образом:

- в общесистемной таблице файлов находится дескриптор указанного файла, и определяется, законно ли обращение от данного процесса к данному файлу в указанном режиме;

- на некоторое (короткое) время устанавливается синхронизационная блокировка на vnode данного файла (содержимое описателя не должно изменяться в критические моменты операции чтения);

- выполняется собственно чтение с использованием старого или нового механизма буферизации, после чего данные копируются, чтобы стать доступными в пользовательском адресном пространстве.

- операция записи выполняется аналогичным образом, но меняет содержимое буфера буферного пула.

- системный вызов close приводит к тому, что драйвер обрывает связь с соответствующим пользовательским процессом и (в случае последнего по времени закрытия устройства) устанавливает общесистемный флаг "драйвер свободен".

Наконец, для специальных файлов поддерживается еще один "специальный" системный вызов ioctl. Это единственный системный вызов, который обеспечивается для специальных файлов и не обеспечивается для остальных разновидностей файлов. Фактически, системный вызов ioctl позволяет произвольным образом расширить интерфейс любого драйвера. Параметры ioctl включают код операции и указатель на некоторую область памяти пользовательского процесса. Всю интерпретацию кода операции и соответствующих специфических параметров проводит драйвер.

Естественно, что поскольку драйверы главным образом предназначены для управления внешними устройствами, программный код драйвера должен содержать соответствующие средства для обработки прерываний от устройства. Вызов индивидуальной программы обработки прерываний в драйвере происходит из ядра операционной системы. Подобным же образом в драйвере может быть объявлен вход " timeout ", к которому обращается ядро при истечении ранее заказанного драйвером времени (такой временной контроль является необходимым при управлении не слишком интеллектуальными устройствами).


 

Блочные драйверы

Блочные драйверы предназначаются для обслуживания внешних устройств с блочной структурой (магнитных дисков, лент и т.д.) и отличаются от прочих тем, что они разрабатываются и выполняются с использованием системной буферизации. Другими словами, такие драйверы всегда работают через системный буферный пул. Любое обращение к блочному драйверу для чтения или записи всегда проходит через предварительную обработку, которая заключается в попытке найти копию нужного блока в буферном пуле

В случае, если копия требуемого блока не находится в буферном пуле или если по какой-либо причине требуется заменить содержимое некоторого обновленного буфера, ядро ОС UNIX обращается к процедуре strategy соответствующего блочного драйвера. Strategy обеспечивает стандартный интерфейс между ядром и драйвером. С использованием библиотечных подпрограмм, предназначенных для написания драйверов, процедура strategy может организовывать очереди обменов с устройством, например, с целью оптимизации движения магнитных головок на диске. Все обмены, выполняемые блочным драйвером, выполняются с буферной памятью. Перепись нужной информации в память соответствующего пользовательского процесса производится программами ядра, заведующими управлением буферами.

 

Символьные драйверы

Символьные драйверы главным образом предназначены для обслуживания устройств, обмены с которыми выполняются посимвольно, либо строками символов переменного размера. Типичным примером символьного устройства является простой принтер, принимающий один символ за один обмен.

Символьные драйверы не используют системную буферизацию. Они напрямую копируют данные из памяти пользовательского процесса при выполнении операций записи или в память пользовательского процесса при выполнении операций чтения, используя собственные буфера.

Следует отметить, что имеется возможность обеспечить символьный интерфейс для блочного устройства. В этом случае блочный драйвер использует дополнительные возможности процедуры strategy, позволяющие выполнять обмен без применения системной буферизации. Для драйвера, обладающего одновременно блочным и символьным интерфейсами, в файловой системе заводится два специальных файла, блочный и символьный. При каждом обращении драйвер получает информацию о том, в каком режиме он используется.

 

Потоковые драйверы

Основным назначением механизма потоков (streams) является повышение уровня модульности и гибкости драйверов со сложной внутренней логикой (более всего это относится к драйверам, реализующим развитые сетевые протоколы). Спецификой таких драйверов является то, что большая часть программного кода не зависит от особенностей аппаратного устройства. Более того, часто оказывается выгодно по-разному комбинировать части программного кода.

Все это привело к появлению потоковой архитектуры драйверов, которые представляют собой двунаправленный конвейер обрабатывающих модулей. В начале конвейера (ближе всего к пользовательскому процессу) находится заголовок потока, к которому прежде всего поступают обращения по инициативе пользователя. В конце конвейера (ближе всего к устройству) находится обычный драйвер устройства. В промежутке может располагаться произвольное число обрабатывающих модулей, каждый из которых оформляется в соответствии с обязательным потоковым интерфейсом.

Жесткие диски

Жесткий диск состоит из одной или нескольких круглых пластин, одна или обе стороны которой покрыты магнитным материалом, используемым для хранения информации. Для каждой стороны предусмотрена головка, позволяющая считывать или записывать информацию. Пластины вращаются на одной оси обычно со скоростью 3600 оборотов в минуту, хотя в более быстрых пpиводах используются более высокие скорости. Головки перемещаются вдоль радиуса поверхности пластин, что позволяет получить доступ к любой точке поверхности.

Центральный процессор (CPU) и жесткий диск обмениваются информацией через дисковый контроллер. Это упрощает схему обращения и работы с диском, так как контроллеры для разных типов дисков могут быть построены с использованием одного интерфейса для связи с компьютером. Поэтому, например, для считывания сектора можно воспользоваться всего лишь одной командой вместо сложных последовательностей электрических сигналов для того, чтобы переместить головки к нужной позиции, синхронизировать вращение диска и считывание или запись данных и др. (на самом деле, интерфейс между компьютером и контроллером тоже достаточно сложен, но не на столько, на сколько он был бы без использования контроллера). Котроллер также выполняет и некоторые другие функции, такие как буферизация информации или автоматическая замена плохих секторов.

Существуют еще некоторые понятия, знание которых необходимо для понимания работы жесткого диска. Обычно поверхности делятся на концентрические кольца, называемые дорожками или трэками, которые, в свою очередь, делятся на сектора. Такое разделение нужно для указания нужных позиций на диске и для распределения дискового пространства на файлы. Для нахождения нужной информации на диске достаточно примерно следующих данных: "поверхность 3, дорожка 5, сектор 7". Обычно количество секторов на дорожке одинаково для всех дорожек на диске, хотя в некоторых устройствах на внешних трэках размещается большее количество секторов (все сектора имеют один и тот же физический размер, поэтому на более длинных дорожках помещается больше секторов). Стандартный размер сектора равен 512 байт. Диск не может оперировать данными, объем которых менее одного сектора.

Каждая поверхность разделена на дорожки (и сектора) таким образом, что при перемещении головки одной поверхности к какой-либо дорожке, головки остальных поверхностей будут установлены на этой же дорожке. Совокупность всех таких дорожек называется цилиндром. Для перемещения головок от одной дорожки (цилиндра) к другой требуется какое-то количество времени. Таким образом, если разместить данные, доступ к которым чаще всего производится сразу (например, файл), в одном цилиндре, то необходимость в перемещении головок отпадает. Это повышает производительность работы диска. Не всегда представляется возможным разместить файл подобным образом. Файлы, которые хранятся в разных местах на диске, называются фрагментированными.

Количество поверхностей (или головок, что в принципе одно и то же), цилиндров и секторов сильно различается у разных устройств. Совокупность таких параметров называется структурой диска, которая хранится в специальной памяти, для питания которой используются аккумуляторы. Эта память называется CMOSRAM, откуда операционная система может считывать информацию во время ее загрузки или во время установки драйвера.

К сожалению, BIOS построен так, что не представляется возможным указать дорожку, номер которой превышает 1024, для записи в CMOSRAM, что является серьезным ограничением для дисков больших объемов. Для решения этой проблемы контроллер жесткого диска передает заведомо неправильную информацию о структуре диска и преобразует данные, представляемые компьютером, в нечто, соответствующее реальности. Например, жесткий диск может состоять из 8 головок, 2048 дорожек с 35 секторами в каждой. В то время как контроллер может утверждать, что диск имеет 16 головок и 1024 дорожки с 35 секторами в каждой, не превышая предела на хранение в CMOSRAM числа дорожек и преобразуя адресацию уменьшая номер головки вдвое и удваивая номер дорожки. Преобразование адресов искажает представление операционной системы о структуре диска, что усложняет размещение требуемой информации на одном цилиндре для увеличения производительности.

Преобразование используется только для IDE дисков. В SCSI дисках используется доступ с применением последовательного номера сектора (который контроллер преобразует в номер головки, цилиндра и сектора диска) и другой метод обмена информацией с процессором. Однако, процессор может не иметь представления о реальной структуре диска.

Так как системе Linux часто не известна информация о структуре диска, то в файловых системах не используется размещение отдельных файлов в пределах одного цилиндра. Вместо этого применяется размещение файлов в цепочках последовательно расположенных секторов, что дает приблизительно одинаковую производительность. Хотя проблема усложняется за счет использования специальных возможностей контроллера, таких как внутреннее кэширование и других автоматических функций.

Каждый жесткий диск представлен отдельным файлом. Для IDE дисков обычно существует только два таких файла. Они известны как /dev/hda и /dev/hdb соответственно. Для SCSI дисков используются файлы / dev / sda и / dev / sdb и т.д. Подобные обозначения применяются и для других типов дисков. Файлы устройств для жестких дисков предоставляют доступ к целому диску, не рассматривая разделы (которые будут описаны ниже) и поэтому не составляет труда перепутать разделы диска или информацию в них, если не быть достаточно осторожным. Файлы жестких дисков обычно используются для доступа к информации в MBR (которые также рассмотрены ниже).

 

Гибкие диски

Гибкий диск состоит из мягкой пластины, покрытой с одной или обоих сторон материалом, подобным тому, которым покрыты пластины в жестком диске. У самой дискеты нет никаких головок, они установлены в приводе. Дискету можно сравнить с одной пластиной, установленной в жестком диске, только дискета является съемной и привод может использоваться для работы с различными дисками, в то время как жесткий диск является одним неделимым устройством.

Также как жесткий диск, дискета делится на дорожки и сектора (а две соответствующие дорожки на разных сторонах составляют цилиндр), но их намного меньше, чем на жестком диске.

Дисковод может работать с несколькими типами дискет. Например, привод на 3.5 дюйма может работать с дисками на 720 Кб и 1.44 Мб. Так как при использовании разных типов дисков, работа самого привода немного различается, к тому же операционная система должна иметь представление об объеме диска, существует множество файлов устройств для работы с приводами для гибких дисков. Например, файл / dev / fd0H1440 соответствует первому приводу (fd0) формата 3.5 дюйма с дискетой на 3.5 дюйма высокой плотности (H) и объемом 1440 Кб (1440), т.е. позволяет работать с обычными дискетами на 3.5 дюйма.

Имена файлов для приводов гибких дисков довольно сложные, поэтому в системе Linux существует специальный тип устройства, который автоматически определяет тип используемого гибкого диска. Метод определения заключается в последовательном чтении первого сектора вставленной дискеты с применением различных способов чтения, до тех пор, пока он не будет правильно считан. Естественно, диск должен быть сначала отформатирован. Автоматическими устройствами являются /dev/fd0, /dev/fd1 и т.д.

Параметры для автоматических устройств, которые используются для доступа к диску, могут быть установлены с помощью программы setfdprm. Это может быть полезно в некоторых случаях, например, если используются дискеты нестандартного объема (т.е. дискета имеет нестандартное количество секторов в дорожке) или если определение типа диска по какой-либо причине не работает и соответствующий файл устройства отсутствует.


 

Дисковые разделы

 

Весь жесткий диск может быть разбит на несколько разделов, причем каждый раздел представлен так, как если бы это был отдельный диск. Разделение используется, например, при работе с двумя операционными системами на одном диске. При этом каждая операционная система использует для работы отдельный раздел и не взаимодействует с другими. Таким образом, две различные системы могут быть установлены на одном жестком диске. Без использования разделов в данном случае возникла бы необходимость в приобретении второго диска.

Для гибких дисков разделы не предусмотрены. В большинстве случаев для этого нет необходимости, так как их объем достаточно мал.

Информация о разделении жесткого диска находится в первом секторе (т.е. в первом секторе первой дорожки первого диска). Этот сектор называется MBR (сокращение от Master Boot Record) этого диска. При загрузке компьютера BIOS загружает его в память и выполняет. MBR содержит небольшую программу, которая считывает таблицу разделов, находит активный раздел (т.е. раздел, отмеченный как загрузочный) и считывает первый сектор этого раздела, который называется загрузочным сектором (MBR также является загрузочным сектором, но он выполняет специальные функции и поэтому имеет отдельное название). Этот сектор содержит другую небольшую программу, которая, в свою очередь, считывает начальную часть операционной системы, расположенной в этом разделе, а затем выполняет ее.

Схема разделения не встроена в оборудование или даже в BIOS. Это только стандарт, которого придерживается большое количество операционных систем. Не все системы поддерживают его, но они являются исключениями. Некоторые системы поддерживают разделение, но они занимают всего один раздел на диске и используют свою внутреннюю схему разделения в пределах используемого раздела. Такие операционные системы нормально работают с другими системами (включая Linux), которые находятся на том же диске. Но те операционные системы, которые не поддерживают разделы, не могут быть установлены вместе с другими системами на одном диске.

Из мер предосторожности следует записать таблицу разделов. Если эта таблица каким-либо образом повредится, то все файлы останутся в сохранности (испорченная таблица разделов может быть исправлена при помощи программы fdisk).

Расширенные и логические разделы

Изначально, в схеме разделения жесткого диска в PC допускалось использование только четырех разделов. Но вскоре этого оказалось недостаточно, частично по причине того, что многим для работы требуется более четырех операционных систем (например, Linux, MS-DOS, OS/2, Minix, FreeBSD, NetBSD, Windows/NT и т.д.), но в основном из-за того, что одной системой используется несколько разделов.

Для решения этой проблемы была разработана схема, использующая расширенные разделы. Она позволяет разбивать основной раздел на подразделы. Основной раздел, разбитый таким образом, называется расширенным разделом, а подразделы называются логическими разделами. Они функционируют так же, как и основные разделы, различие состоит в схеме их создания.

Таблицы разделов (одна находится в MBR, другие используются для расширенных разделов) содержат один байт для каждого раздела, который указывает тип раздела. Это позволяет определить операционную систему, которая использует раздел или для чего он используется во избежание случайного размещения двух систем на одном разделе. Однако, в действительности, операционные системы игнорируют байт типа раздела. Хуже того, некоторые системы неправильно его интерпретируют (по крайней мере, некоторые версии DR - DOS игнорируют самый важный бит этого байта, в отличие от других).

Не существует никаких стандартов, касающихся значений этих байтов, хотя некоторые общепринятые значения приведены в таблице ниже.

0 пустой раздел 40 Venix 80286 94 Amoeba BBT 1 DOS 12-битная FAT 51 Novell a5 BSD/386 2 XENIX root 52 Microport b7 BSDI fs 3 XENIX usr 63 GNU HURD b8 BSDI swap-область 4 DOS 16-бит (<32Мб) 64 Novell c7 Syrinx 5 расширенный 75 PC/IX db CP/M 6 DOS 16-бит (>=32Мб) 80 old minix e1 dos 7 os/2 hpfs 81 linux/minix e3 dos r/o 8 aix 82 linux swap-область f2 dos дополнительный 9 aix загрузочный 83 linux ff bbt a os/2 загрузочный 93 amoeba

Разделение жесткого диска

Существует много программ, позволяющих создавать и удалять разделы. У большинства операционных систем имеются свои собственные и разумнее всего пользоваться именно такими программами. Чаще всего эта программа называется fdisk (как и в случае Linux). Особенности работы с ней рассмотрены в ее руководстве. Команда cfdisk подобна fdisk, только в первой используется полноэкранный интерфейс.

При работе с IDE дисками, загрузочный раздел (раздел, в котором находятся файлы, используемые при загрузке и само ядро) должен полностью располагаться в пределах первых 1024 цилиндров, потому как во время загрузки работа с диском происходит через BIOS (перед переходом системы в защищенный режим), а BIOS не может оперировать с цилиндрами, номер которых больше, чем 1024. Иногда представляется возможным использование загрузочного раздела, лишь частично расположенного в пределах первых 1024 цилиндров. Данный метод работает до тех пор, пока все файлы, считываемые посредством BIOS, находятся в пределах 1024 цилиндров. Так как это сделать довольно сложно, то применение этого метода не рекомендуется. Сложно предугадать, когда после дефрагментации или сбрасывании содержимого буфера на диск система перестанет загружаться. Поэтому следует удостовериться в том, что загрузочный раздел расположен в пределах первых 1024 цилиндров.

Некоторые последние версии BIOS и недавние модели IDE дисков в действительности позволяют работать с цилиндрами, номер которых превышает 1024.

Каждый раздел должен содержать четное количество секторов. Нечетное количество секторов приведет к тому, что последний из них будет не использован. Это ни на что не влияет, но пpи запуске fdisk будет выдано предупреждение.

При изменении размера раздела обычно требуется сначала сделать резервную копию всей необходимой информации, удалить раздел, создать новый раздел, а затем восстановить всю сохраненную информацию на новый раздел. Хотя существует программа для MS-DOS под названием fips, которая позволяет изменять объем раздела без резервного копирования, но для других файловых систем эту операцию необходимо производить.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-08-20 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: