Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [ 68 ] 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

единственная причина, по которой он может не выполниться, - неправильно указанное в операции OPEN устройство. Далее заполняется стандартная структура iorequest s, описание которой находится в файле include/minix/type.h. Затем делается следующий косвенный вызов, *dr schedule. В разделе ниже будет показано, что обработка запросов к оборудованию в том порядке, в каком они поступают, не обязательно эффективна. Эта подпрограмма служит для того, чтобы запросы к каждому конкретному устройству могли обрабатываться в оптимальном порядке. Например, для RAM-диска dr schedule ссылается на функцию, которая непосредственно вызывает передачу данных, а следующий косвенный вызов, *dr finish, представляет собой пустую функцию. У реальных дисков *dr finish выполняет все задержанные запросы на считывание, поступивщие с предшествующими вызовами *dr schedule. Как мы увидим, иногда *dr finish может вообще не передавать всех запрошенных данных.

Какой бы вызов ни занимался реальным обменом информацией, изменяется значение поля io nbytes в структуре iorequest s. При этом отрицательное число индицирует ошибку при передаче данных, а положительное означает разницу между запрошенным количеством байтов и количеством, которое было реально передано. Причем нулевое значение не обязательно свидетельствует об ошибке. Например, это может значить, что достигнут конец устройства. После возврата в главный цикл отрицательное значение (код ошибки) помещается в поле REP STATUS, если ошибка произошла. Если ошибки не было, полученное значение вычитается из запрошенного количества байтов (поле COUNT исходного сообщения) и результата (равный реально переданному объему информации) и записывается в поле ответного сообщения REP STATUS.

Следующая функция, do vrdwt, обрабатывает разрозненные запросы ввода/ вывода. В сообщении драйверу, содержащем подобный запрос, в поле ADDRESS помещается адрес массива структур типа iorequest s. Каждая из этих структур хранит информацию для выполнения одного запроса: адрес буфера, величину смещения для устройства, количество байтов, а также признак, нужно ли чтение или запись. Все операции в одном запросе должны быть либо на чтение, либо на запись, и перед выполнением они сортируются в порядке следования блоков на устройстве. Функция do vrdwt сложнее функции для чтения или записи, так как массив запросов должен быть предварительно скопирован в память ядра Но, после того как массив скопирован, запросы выполняются при помощи тех же самых косвенных вызовов *dr prepare, *dr schedule и *dr finish. Различие только в том, что второй вызов, *dr schedule, делается несколько раз в цикле, по одному разу для каждого запроса, или пока не случится ошибка. После завершения цикла однократно вызывается *dr finish, и затем массив запросов копируется обратно на то место, откуда он взят. При этом в каждом из элементов массива меняется поле io nbytes, отражая количество реально переданных байтов. Суммарное количество для всех запросов не подсчитывается, хотя вызывающая программа сама может рассчитать это значение по полям массива.

Как уже было сказано выше, при выполнении разрозненного запроса не все переданные в вызов *dr schedule гарантированно выполняются, когда делается завершающий вызов *dr f1nish. Поле io request в структуре iorequest s содер-



жит фланговый бит, который позволяет пометить данный запрос как необязательный.

Следующие несколько функций из файла driver.c обеспечивают выполнение описанных выше операций. Вызов *dr name возвращает имя устройства. Если у устройства нет фиксированного имени, функция no name извлекает имя устройства из таблицы задач. Некоторым устройствам не нужен ряд функций. Например, RAM-диск не должен ничего делать по запросу DEV CLOSE. В качестве пустой функции используется do nop, возвращаемое ею значение зависит от типа запроса. Функции nop finish и nap cleanup - пустые функции для устройств, которым не требуется обрабатывать вызовы *dr finish или *dr cleanup.

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

Наконец, функция do diocntl осуществляет для блочных устройств запросы DEV IOCTL. Она сообщает об ошибке, если затребована любая другая операция помимо считывания (DIOGETP) информации о разделе или записи (DIOSETP). Чтобы удостовериться, что устройство задано корректно, и получить указатель на структуру device с информацией о базовом адресе и размере раздела, do dioctl вызывает *dr prepare. При обработке запроса на чтение вызывается специфичная для устройства функция *dr geometry, с целью получить информацию о цилиндрах, головках и секторах, относящихся к разделу диска.

3.5.3. Библиотека поддержки драйверов

Файлы drvlib.h и drvlib.c содержат системно-зависимый код, поддерживающий работу с разделами дисков на IBM PC-совместимых компьютерах.

Разбиение диска на разделы позволяет получить на одном накопителе несколько логических. Обычно на разделы дробятся жесткие диски, хотя MINIX поддерживает и разбиение дискет. Вот несколько причин в пользу разбиения на разделы.

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

2. У операционной системы могут иметься офаничения на максимальный размер устройства. Обсуждаемая здесь версия MINIX поддерживает максимальный размер файловой системы 1 Гбайт, а у более старых версий было офаничение до 256 Мбайт. В результате оставшееся дисковое пространство расходовалось впустую.



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

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

Поддержка разделов зависит от платформы, причем эта зависимость не относится к аппаратному обеспечению. К накопителям поддержка разделов не привязана. Но если на одном и том же наборе устройств должно работать несколько операционных систем, они должны иметь одинаковое представление о формате таблицы разделов. Для IBM PC стандарт задает команда MS-DOS fdisk, и другие операционные системы, такие как MINIX, OS/2 и Linux, поддерживают этот формат и могут сосуществовать с MS-DOS. Когда MINIX переносится на другую платформу, имеет смысл использовать формат таблицы разделов, совместимый с другими операционными системами, работающими на данной платформе. Чтобы упростить перенос системы, код для поддержки таблицы разделов на IBM PC-совместимых системах помещен в отдельный файл drvlib.c, а не включен в driver.c.

Основные структуры данных описываются в файле include/minix/partition.h. Формат этих структур определяется разработчиками программно-аппаратных средств платформы. Этот заголовочный файл при помощи директивы препроцессора #include включается в файл drvlib.h. Сюда входит информация о геометрии всех разделов (цилиндры-головки-секторы), а также информация о типе файловой системы на каждом из разделов и метка, обозначающая активный раздел, который будет загрузочным. После проверки файловых систем большая часть этой информации MINIX не нужна.

Функция partition в файле drvlib.h вызывается, когда в первый раз открывается блочное устройство. В аргументы этой функции входит структура driver, поэтому первая в состоянии вызывать специфичные для данного устройства функции. Также в функцию передается младший номер устройства и параметр, задающий тип разбиения на разделы (существуют различные способы разбиения для гибкого диска, основного раздела и подраздела). Чтобы проверить правильность устройства и поместить в структуру device базовый адрес и размер раздела, вызывается функция *dr prepare. Затем, чтобы детектировать наличие таблицы разделов и считать ее, вызывается get part table. Если таблицы разделов не оказалось, работа завершена. В противном случае вычисляется младший номер устройства для первого раздела (правила нумерации устройств определяются упомянутым ранее типом разбиения на разделы). Для случая основных разделов таблица сортируется так, чтобы порядок разделов соответствовал очередности, используемой другими операционными системами.

В этом месте делается другой вызов *dr prepare, на этот раз ему в качестве параметров передается только что вычисленный для первого раздела номер устройства. Если устройство корректно, проверяются все записи в таблице на этом устройстве, с целью удостовериться, что хранящиеся в таблице ссылки не выходят за пределы, отведенные устройству. Если все данные корректны, таблица



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [ 68 ] 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.