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

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

мы, это может оказаться полезным. Записывая данные в /dev/mem, можно изменить векторы прерываний. Не стоит и говорить, что делать это должен только опытный пользователь, твердо знающий, что он делает.

Файл /dev/kmem полностью подобен файлу /dev/mem, за тем исключением, что нулевой адрес в файле соответствует нулевому адресу в пространстве ядра, положение последнего зависит от размера кода MINIX. Этот файл также привлекается по большей части для целей отладки рядом специальных программ. Обратите внимание на то, что области памяти, соответствующие этим двум устройствам, перекрываются. Если вы точно знаете, где в памяти находится ядро, то, если прочитать из /dev/mem данные по означенному адресу, можно увидеть точно те же данные, которые находятся в начале файла /dev/kmem. При перекомпиляции системы размер и положение ядра в памяти могут измениться, но /dev/kmem все равно будет содержать область памяти ядра.

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

а out >/dev/null

запустит программу a.out, но все, что она выводит, будет игнорироваться. Драйвер RAM-диска считает, что размер этого устройства равен О, поэтому никаких данных на него не записывается и не считывается с него.

Код, обслуживающий устройства /dev/ram, /dev/mem и /dev/kmem, идентичен. Единственное различие между этими тремя устройствами в том, что они работают с разными областями памяти, задаваемыми массивами ram origin и ram limit, индексируемыми младшим номером устройства.

3.6.3. Реализация драйвера RAM-диска в MINIX

Как и у других драйверов, главный цикл драйвера RAM-диска находится в файле driver.c. Поддержка специальных функций RAM-диска обеспечивается файлом memory.c. В массиве m geom хранятся базовые адреса и размеры всех четырех специальных устройств. Адреса подпрограмм, обеспечивающих работу устройств, записываются в переменную m dtab, имеющую тип driver. Эта структура будет использоваться в главном цикле для организации соответствующих устройству вызовов. Четыре вызова являются либо пустыми, либо очень простыми, их код помещен в driver.c, что является еще одним подтверждением того, что код драйвера не слишком сложен. Головная процедура mem task выполняет локальную инициализацию, вызывая одну функцию. После этого она передает управление в главный цикл, который получает сообщения, вызывает для их обслуживания необходимые подпрограммы и отправляет ответные сообщения. Главный цикл не возвращает управление обратно в mem task.

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



правильное младшее устройство, и возвращает адрес структуры, содержащей базовый адрес и размер запрошенной области памяти. Второй вызов обслуживает функция m schedule, которая и выполняет всю работу. Имя этой функции не соответствует тому, что она делает. По определению, она должна запланировать операцию ввода/вывода, но для RAM-диска в планировании нет необходимости, так как никакого диска нет.

Работа RAM-диска настолько проста и выполняется так быстро, что никогда не возникает потребности отложить запрос, поэтому сначала функция сбрасывает бит, который при разрозненном вводе/выводе обозначает необязательное выполнение запроса. В сообщении, которое передается задаче, адрес буфера назначения указывается в адресном пространстве пользовательского процесса. Поэтому далее в коде функции этот адрес преобразуется в абсолютный и делается проверка его правильности. За сам обмен данными ответственны завершающие команды функции, обрамленные условным оператором. Передача данных сводится к простому копированию блока из одного места в другое.

Третий, завершающий шаг RAM-диску не нужен, поэтому в соответствующее поле переменной m dtab записывается адрес пустой функции nop finish.

За открытие RAM-диска отвечает функция m do open. Самые главные действия в ней выполняет вызов m prepare, который проверяет, что устройство указано корректно. Если указано одно из устройств /dev/mem или /dev/kmem, то, чтобы получить более высокий уровень привилегий, делается вызов функции enablejop (ее код находится в файле protect.c). Этот вызов нужен не для того, чтобы обратиться к памяти, он служит для решения другой задачи. Вспомните, что у процессоров Pentium есть четыре уровня привилегий. При этом пользовательские профаммы работают на последнем уровне. Кроме того, у процессоров Intel, в отличие от других архитектур, порты ввода/вывода занимают отдельное от основной памяти адресное пространство, и для обращения к ним применяется специальный набор команд. В обычной ситуации попытка пользовательского процесса обратиться к порту ввода/вывода приводит к исключению ограничения доступа. Тем не менее существуют причины, по которым может потребоваться разрешить пользовательским процессам доступ к портам, что в особенности относится к маленьким системам. Это и обеспечивает функция enablejop, которая меняет биты уровня защиты ввода/вывода процессора (I/O Protection Level, lOPL) таким образом, чтобы необходимые действия были разрешены. В результате процесс, открывший устройство /dev/mem или /dev/kmem, в дополнение получает разрешение обращаться к портам ввода/вывода. В тех системах, где порты принадлежат общему адресному пространству, для доступа к ним достаточно установить для файлов памяти биты разрешения доступа rwx. Мы рассказали о таких возможностях потому, что, если их не учитывать, они могли бы стать уязвимостью. Если вы, например, планируете применять MINIX для управления системой безопасности банка, вам лучше перекомпилировать ядро без такой функциональности.

Следующая функция, mjnit, вызывается только один раз, когда в первый раз делается вызов mem task. Эта функция устанавливает базовый адрес и размер устройства /dev/kmem, присваивая размеру значение 1 Мбайт, 16 Мбайт или 4 Гбайт (п - 1), в зависимости от того, в каком режиме работает MINIX: 8088,



80286 или 80386. Величина устройства в данном случае определяется максимальным адресуемым объемом памяти и не имеет ничего общего с количеством оперативной памяти, установленной на машине.

RAM-диск поддерживает несколько операций ioctl, код для которых находится в функции m ioctL Операция MIOCRAMSIZE предоставляет файловой системе удобный способ управлять размером RAM-диска. Операция MIOCSPSINFO используется как файловой системой, так и менеджером памяти, чтобы поместить адреса своих компонентов в таблице процессов в таблицу psinfo. Стандартная утилита UNIX ps получает эти данные при помощи операции MIOGSPSINFO. Программа ps - это стандартная утилита, но микроядерная архитектура MINIX затрудняет ее работу, так как необходимая ей информация о процессах хранится в нескольких различных местах. Системный вызов ioctl предоставляет удобный способ решить эту проблему. Без него пришлось бы при каждой перекомпиляции системы перекомпилировать ps.

Последняя функция в файле memory.c это m geometry. Для RAM-диска понятия цилиндра, дорожки и сектора не имеют смысла, но, если система запросит эту информацию, он должен притвориться, что они есть.

3.7. Диски

Пример RAM-диска познавателен в качестве вступления (так как он прост), но у реальных дисков есть ряд особенностей, которые еще не были рассмотрены. В последующих разделах мы скажем несколько слов об устройстве жестких дисков, а затем перейдем к рассмотрению их драйверов и, в частности, драйверов для MINIX. Гибкие диски мы подробно обсуждать не будем, но выделим некоторые моменты, отличающие их от жестких дисков.

3.7.1. Аппаратная часть дисков

Магнитные диски организованы в цилиндры, каждый из которых содержит столько дорожек, сколько есть у устройства головок, установленных вертикально. Дорожки делятся на секторы, их количество обычно варьируется от 8 до 32 у гибких дисков и до нескольких сотен у жестких дисков. Число головок варьируется от 1 до 16.

У некоторых магнитных дисков мало электроники, они предоставляют на выходе простой поток битов. Контроллер такого диска выполняет совсем немного работы. На других дисках, в частности на IDE-дисках (IDE, Integrated Drive Electronics - встроенный интерфейс накопителей) само устройство содержит микроконтроллер, выполняющий значительный объем работ и позволяющий собственно контроллеру обращаться к нему с набором команд высокого уровня.

IDE-диски обладают одним свойством, несущим важные последствия для драйверов: контроллер способен выполнять одновременно поиск дорожки на двух и более дисках. Это свойство известно под названием поиска с перекрытием. В то время как контроллер и программное обеспечение ожидают окончания операции



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 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.