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

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

и не должно использоваться ни в каких других идентификаторах, не являющихся именами типов.

Таблица 2.2. Размер некоторых типов на 16- и 32-разрядных системах (размер указан в битах)

16-разрядная MINIX

32-разрядная MINIX

QidJ

dev t

pidj

inoj

Множество различных макросов для действий по управлению устройствами имеется в файле sys/ioctl.h, хотя он используется не настолько часто, чтобы включать его в главный заголовочный файл для каждой секции. Кроме того, здесь же описывается прототип системного вызова ioctl. Правда, сейчас, когда функции POSIX, прототипы которых находятся в файле include/termios.h, во многом заменили старую библиотечную функцию ioctl, этот вызов не так часто делается про-фаммистами напрямую. Но тем не менее он все еще необходим. Фактически функции POSIX для управления терминалами транслируются библиотекой в соответствующие вызовы ioctl. Вдобавок, все возрастает количество прочих интерфейсных устройств, подлежащих контролю. Так, в конце этого файла определено несколько кодов операций, начинающихся с DSPIO, предназначенных для управления числовыми сигнальными процессорами. Конечно, в этой книге мы описываем систему только с основными периферийными устройствами. Но ничто не мещает добавить и многие другие типы устройств: сетевые адаптеры, приводы компакт-дисков, звуковые карты. Управляющие коды для всех этих устройств представлены в файле sys/ioctl.h в виде макросов.

Широко используются в системе еще несколько файлов из рассматриваемого каталога. В sys/sigcontext.h задаются различные структуры, служащие для сохранения и последующего восстановления состояния системы перед вызовом обработчика прерывания. Этот файл необходим как для ядра, так и для менеджера памяти. В MINIX предусмотрена поддержка отладки программ и просмотра памяти при помощи системного вызова ptrace, все возможные действия с которым описаны в файле sys/ptrace.h. Файл sys/stat.h определяет структуры, которые упоминались в листинге 1.1, для системных вызовов stat и fstat. Также в этом файле находятся прототипы функций для работы со свойствами файлов. К нему по мере необходимости обращаются некоторые части файловой системы и менеджера памяти.

Последние два файла, которые мы рассмотрим в текущем разделе, востребованы не так широко, как описанные выше. В файле sys/dir.h описан формат каталога в MINIX. Значение этого файла, помимо прочего, в том, что он задает максимальную длину имени файла. Напрямую он используется только один раз, но опосредовано - достаточно часто, через подключение в другой заголовочный файл. Наконец, в файле sys/wait.h представлены макросы, нужные для работы с системными вызовами wait и waitpid, реализуемыми менеджером памяти.



2.6.3. Заголовочные файлы MINIX

Файлы, специфичные только для MINIX, расположены в каталогах include/minix/ и include/ibm/. Первый из каталогов содержит файлы, общие для реализаций MINIX на всех платформах (хотя в некоторых из файлов есть альтернативные определения, зависящие от платформы), а второй - специфичные для платформы IBM.

Мы начнем изучение с каталога minix/. Ранее был упомянут файл config.h, включаемый во все главные заголовочные файлы основных компонентов системы, и фактически являющийся первым файлом, обрабатываемым компилятором. Во многих случаях, когда в системе меняется оборудование или же нужно изменить способ работы MINIX, все, что нужно сделать, - отредактировать этот файл и пересобрать систему. Начальная часть файла представляет собой список настраиваемых пользователем параметров, первый из которых - MACHINE, может принимать такие значения, как 1ВМ РС, SUN 4, MACINTOSH или другие, в зависимости от того, для какой мащины компилируется MINIX. Это не оказывает влияния на больщую часть кода, но у такой профаммы, как операционная система, всегда есть платформно-зависимый код. В тех немногих частях нащей книги, где мы будем обсуждать подобный код, мы будем ориентироваться на IBM-совместимые компьютеры в 32-разрядном режиме (то есть 80386, 80486, Pentium, Pentium Pro и т. д.); такие процессоры будут называться 32-разрядными Intel-совместимыми. Кроме того, MINIX можно скомпилировать и для более старых процессоров Intel, если использовать 16-разрядные слова. Для таких мащин некоторые части системы должны кодироваться иначе. На PC компилятор самостоятельно определяет тип аппаратного обеспечения, для которого компилируется система.

Стандартным инструментом для MINIX на PC является компилятор из пакета разработчика АСК (Amsterdam Compiler Kit). Он идентифицируется предустановленными макросами STDC и АСК . Также он самостоятельно определяет макрос, хранящий величину мащинного слова целевой мащины (в байтах), его имя EM WSIZE. В исходных кодах системы создается новый макрос, WORD SIZE, которому присваивается значение EM WSIZE. Затем этот макрос можно использовать в дальнейшем коде, чтобы определить тип системы. Например, директива препроцессора #if (MACHINE == IBM PS && WORD SIZE - 4)

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

Другое назначение config.li - дополнительная настройка конкретной системы. Например, имеется секция настроек, в которой можно указать различные типы драйверов устройств, включаемых в ядро при компиляции. Эта секция начинается строками:

#define ENABLEJETWORKING О #define ENABLE AT WINI 1 #define ENABLE BIOS WINI 0



Изменив значение О в первой строке на 1, можно включить поддержку сети в ядре MINIX. Если же определить ENABLE AT WINI как О, а ENABLE BIOS WINI как 1, можно отключить код драйвера IDE-дисков и тем самым обращаться к жесткому диску через BIOS.

Следующий файл, const.h, демонстрирует другое типичное применение заголовочных файлов. В нем перечислены различные константы, которые, скорее всего, не должны меняться при компиляции ядра, но которые используются в различных частях системы. Поместив подобные определения в отдельный файл, вы оградите себя от ошибок, вызванных несоответствием значений в различных местах программы. В дереве исходных кодов MINIX имеется еще несколько файлов с именем const.h, но у них более офаниченное применение. Например, константы, востребуемые только кодом ядра, помещены в src/kernel/const.h. Константы для файловой системы хранятся в src/fs/const.h. У менеджера памяти тоже собственный файл для своих констант - src/mm/const.h. В основной файл, include/ minix/consth, помещены только те определения, которые используются в различных частях системы.

Имеет смысл особо упомянуть некоторые макроопределения из const.h. Макрос EXTERN транслируется в ключевое слово extern. При помощи этого макроса определяются глобальные переменные, продекларированные в заголовочном файле и включаемые в два или более файлов с кодом. Например:

EXTERN int who:

Если же просто объявить переменную как

int who:

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

Чтобы избежать подобных проблем, переменные следует декларировать так:

extern int who:

причем это нужно делать во всех местах, кроме одного. Здесь и помогает макроопределение EXTERN, разворачивающееся в extern, если включен файл const.h, или в пустую строку, если явно переопределить EXTERN. В каждой из частей MINIX это делается путем помещения глобальных переменных в отдельный файл, называемый glo.h, косвенно включаемый в каждый процесс компиляции. Например, для ядра таким будет файл src/kernel/glo.h. В каждом из glo.h имеются подобные строки:

#ifdef JABLE #undef EXTERN #define EXTERN #endif

В файле table.c для каждой из составных частей системы перед секцией #include имеется такая директива:

#define TABLE



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