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

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

чае make break делает возврат прямо из оператора switch, тем самым обходя операторы в конце функции, записывающие в переменную esc нулевое значение. В результате esc действует только на один символ, который будет получен следующим. Если вы знакомы с особенностями обычного программирования ввода от клавиатур PC, то это также будет вам понятно, хотя и немного странно, так как BIOS PC не позволяет считывать код опроса для клавиши ALT и возвращает другое значение для расширенного кода.

Функция set leds управляет светодиодами на клавиатуре, индицирующими состояние клавиш Num Lock, Caps Lock и Scroll Lock. Чтобы указать клавиатуре, что следующий записанный в порт байт управляет индикаторами, в порт записывается управляющий байт, LED CODE. Состояние всех трех светодиодов кодируется тремя битами этого байта. Две следующие функции необходимы для поддержки данной операции. Функция kb wait вызывается тогда, когда необходимо определить момент готовности клавиатуры к получению управляющей последовательности, а кЬ аск проверяет, что команда была подтверждена. Обе эти команды используют активное ожидание, непрерывно считывая состояние до тех пор, пока не будет получено нужное значение. Такая методика не рекомендуется для операций ввода/вывода, но переключение индикаторов не должно происходить часто, поэтому временные издержки не так велики. Заметьте, что и kb wait, и кЬ аск могут завершиться неудачей, что видно из кода возврата функций. Правда, переключение индикаторов на клавиатуре - не самая важная задача, поэтому возвращаемое значение не проверяется, и set leds выполняется вслепую .

Так как клавиатура является составной частью консоли, ее подпрограмма инициализации, kbjnit, вызывается из scrjnit в файле console.c, а не напрямую из ttyjnit в tty.c. Если включены виртуальные консоли (то есть константа NR CONS в include/minix/config.h больше 1), kbjnit вызывается для каждой логической консоли. Хотя после того, как kbjnit будет запущена для первой консоли, а для других необходимо только записать адрес процедуры kb read в поле tp->tty devread, нет никакого вреда в том, чтобы лишний раз повторить и остальные команды инициализации. В оставшейся части kbjnit устанавливаются значения некоторых переменных, задается состояние индикаторов на клавиатуре, а клавиатура сканируется, чтобы удостовериться, что не будет прочитано никаких остаточных нажатий на клавиши. Когда все готово, функция инициализации вызывает putjrq handler, а затем enablejrq, чтобы при следующем нажатии или отпускании клавиши сработал обработчик kbd hwjnt.

Следующие три функции довольно просты. Подпрограмма kbd loadmap почти тривиальна. Она вызывается из dojoctl с целью скопировать карту клавиатуры из пользовательского адресного пространства. При этом новая раскладка записывается поверх раскладки по умолчанию, сгенерированной благодаря тому, что исходный файл раскладки включен в начало keyboard.c.

Функция func key вызывается из kb read и проверяет, не нажата ли специальная клавиша, которая должна быть обработана локально. Эти клавиши и производимый ими эффект перечислены в табл. 3.18. Вызываемые функцией подпрограммы расположены в различных файлах. Коды F1 и F2 активизируют функции из файла dmp.c, который мы рассмотрим в следующем разделе. Код F3 приводит



к вызову функции toggle scroll из состава console.c, которая также будет рассмотрена в следующем разделе. Коды CF7, CF8 и CF9 обслуживаются вызовами функции sigchar из tty.c. Когда MINIX скомпилирована с поддержкой сети, обрабатывается еще один код, F5, распечатывающий статистику Ethernet. Кроме этого, доступно еще большое число различных кодов, которые можно использовать для передачи на консоль различных отладочных сообщений и прочих специальных событий.

Функция scan keyboard взаимодействует с аппаратным интерфейсом клавиатуры, считывая и записывая байты из портов ввода/вывода. Контроллер клавиатуры информируется о том, что символ был считан последовательностью трех команд, начинающейся со второго вызова in byte. Эти команды считывают байт, затем записывают его обратно с установленным старшим битом, а затем перезаписывают его еще раз, со сброшенным битом. В результате те же самые данные не встретятся заново при следующем чтении. В этой функции не делается никаких проверок, что не есть проблема, так как scan keyboard вызывается только из обработчика прерываний (из kbjnit, как единственное исключение, чтобы удалить любой мусор).

Таблица 3.18. Функциональные клавиши, обнаруживаемые func key()

Клавиша Действие

F1 Отображается таблица процессов

F2 Показывает информацию о занятой процессом памяти

F3 Переключает между программной и аппаратной прокруткой

F5 Показывает статистику Ethernet (если есть поддержка сети)

CF7 Отправляет сигнал SIGQUIT, тот же эффект, что и CTRL+\

CF8 Отправляет сигнал SIGINT, тот же эффект, что и DEL

ста Отправляет сигнал SIGKILL, тот же эффект, что и CTRL+U

Завершает файл keyboard.c функция wreboot. Вызываемая в результате краха системы, она дает пользователю возможность просмотреть отладочную информацию при помощи функциональных клавиш. Цикл в этой ветви кода функции - еще один пример активного ожидания. Клавиатура непрерывно опрашивается до тех пор, пока не будет нажата ESC. Безусловно, никто не может заявить, что после сбоя, когда ожидается команда на перезагрузку, имеет смысл применять более эффективные методики. Внутри цикла вызывается func keys, это позволяет обрабатывать функциональные клавиши с целью сбора информации, которая поможет понять причины сбоя. Дальнейшие детали возврата в монитор начальной загрузки мы обсуждать не будем, так как они сильно завязаны на аппаратное обеспечение и не имеют особого отношения к операционным системам.

3.9.6. Реализация драйвера экрана

Если имеется достаточное количество видеопамяти, экран IBM PC можно сконфигурировать как несколько виртуальных терминалов. В этом разделе мы будем



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

Специфичный для отображаемого в память экрана PC код расположен в файле console.c. Здесь объявляется структура console, которая по своему смыслу является расширением структуры tty из файла tty.c. При инициализации в поле tp->tty priv структуры tty для консоли записывается указатель на принадлежащую этой консоли структуру console. Первое поле структуры является указателем, содержащим обратную ссылку на структуру tty. Остальные компоненты структуры содержат вполне ожидаемую для видеоустройства информацию: переменные, хранящие текущие координаты курсора, адрес начала области памяти, отведенной для дисплея, и ее размер, адрес, на который ссылается регистр базы чипа контроллера, и текущий адрес курсора. Другие переменные используются для работы с ESC-последовательностями. Так как символы принимаются в виде 8-битных байтов и перед выводом в видеопамять должны быть скомбинированы с байтом атрибутов, блок данных подготавливается к передаче в c ramqueue, массиве, объема которого достаточно для хранения 80 16-битных пар символ-атрибут . Каждой виртуальной консоли требуется собственная структура console, для хранения которой выделяется область памяти в cons table. Как мы уже делали в случае структур tty и kb s, мы обычно будем ссылаться на поля console через указатель, например: cons->c tty.

Для каждой консоли в поле tp->tty devwrite хранится адрес функции cons write. Она вызывается только из одного места, обработчика handle events в файле tty.c. Большая часть остальных функций в console.c существуют для того, чтобы обеспечивать работу cons write. Когда она вызывается впервые после того, как процесс-клиент сделал вызов write, выводимые данные расположены в буфере в адресном пространстве этого процесса. Определить положение этого буфера можно при помощи полей tp->tty outproc и tp->out vir структуры tty. Поле tp->tty outleft говорит о том, сколько символов должно быть передано, а поле tp->tty outcum изначально равно нулю, сообщая о том, что ни одного символа еще не выведено. Это обычная ситуация для cons write, так как эта функция обычно выводит все данные, указанные в вызове. Но если пользователь хочет замедлить процесс вывода, он может ввести с клавиатуры символ STOP (CTRL+S), который приводит к тому, что устанавливается флаг tp->ttyjnhibited. Когда этот флаг установлен, cons write немедленно возвращает управление, даже если вызов write еще не выполнен полностью. Причем handle events продолжит вызывать cons write, и, когда флаг tp->ttyjnhibited будет сброшен (для этого необходимо ввести символ START (CTRL4-Q), прерванная передача данных будет возобновлена.

Единственным аргументом cons write является указатель на структуры tty для данной консоли, поэтому первым действием инициализируется указатель cons, содержащий адрес структуры console. Затем необходимо проверить, действительно ли есть какая-либо работа, так как handle events вызывает cons write неоднократно.



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