Обращение к портам ввода/вывода
Команды ассемблера in, out, ins и outs дают доступ к портам ввода/вывода. Для упрощения такого доступа в ядро включены следующие служебные функции:
- inb , inw , ini — прочитать, соответственно, один, два или четыре последовательных байта из порта ввода/вывода. Суффиксы "b", "w" и ”1” обозначают байт (8 битов), слово (16 битов) и длинное слово (32 бита) соответственно;
- inb p , inw p , ini p — прочитать, соответственно, один, два или четыре последовательных байта из порта ввода/вывода, а затем выполнить "пустую” команду, чтобы создать паузу;
- outb , outw , outi — записать, соответственно, один, два или четыре последовательных байта в порт ввода/вывода;
- outb po, outw po, outi po — записать, соответственно, один, два или четыре последовательных байта в порт ввода/вывода, а затем выполнить "пустую” команду, чтобы создать паузу;
- insb, insw, insi — прочитать из порта ввода/вывода последовательность групп, состоящих соответственно из одного, двух или четырех байтов. Длина последовательности передается функции в качестве параметра;
- outsb , outsw , outsi — записать в порт ввода/вывода последовательность групп, состоящих соответственно из одного, двух или четырех байтов.
В то время как доступ к портам ввода/вывода довольно прост, определить, какие порты ввода/вывода назначены устройствам, не так легко, особенно для систем с шиной ISA. Нередко драйверу устройства приходится вслепую писать данные в какой-нибудь порт ввода/вывода, чтобы прозондировать аппаратное устройство. Однако если этот порт уже используется другим устройством, может произойти крах системы. Для предотвращения подобных ситуаций ядро отслеживает порты ввода/вывода для каждого аппаратного устройства, пользуясь механизмом ресурсов”.
Ресурс — это часть некой сущности, которая может быть эксклюзивно назначена драйверу устройства. В нашем случае ресурс представляет собой диапазон адресов портов ввода/вывода. Информация, относящаяся к каждому ресурсу, хранится в структуре resourc Все ресурсы одного типа заносятся в древовидную структуру. Например, ресурсы, представляющие диапазоны адресов портов ввода/вывода, ВКЛЮЧеНЫ В Дерево, Корнем КОТОРОГО ЯВЛЯетСЯ ioport_resourse.
Потомки узла собраны в список, на первый элемент которого указывает поле child. Поле sibling указывает на следующий узел в списке.
Почему используется дерево? Рассмотрим, например, адреса порта ввода/вывода в интерфейсе жесткого диска IDE. Предположим, они лежат в диапазоне от Oxfооо до OxfOOf. Ресурс, у которого поле start имеет значение Oxfооо, а поле end — значение OxfOOf, включается в древовидную структуру, а условное имя контроллера записывается в поле паше. Однако драйвер IDE должен помнить дополнительную информацию, а именно тот факт, что поддиапазон от Oxf о оо до Oxf о 07 используется для master-диска в цепочке IDE, а поддиапазон от 0xf008 до OxfOOf— для slave-диска. С этой целью драйвер вставляет два узла-потомка ниже ресурса, соответствующего всему диапазону от Oxf о оо до OxfOOf (по одному потомку для каждого поддиапазона портов ввода/вывода). В качестве общего правила можно сказать, что каждый узел дерева должен соответствовать поддиапазону диапазона, ассоциированного с родительским узлом. Корень дерева ресурсов портов ввода/вывода (ioport resourse) охватывает все адресное пространство (от 0 до 65 535).
Каждый драйвер устройства может вызывать следующие три функции, передавая им корневой узел дерева ресурсов и адрес интересующей его структуры данных:
- request resourse — присваивает данный диапазон устройству ввода/вывода;
- aiiocate_resourse — ищет в дереве ресурсов доступный диапазон, имеющий указанный размер и тип выравнивания. Если такой диапазон существует, функция присваивает его устройству ввода/вывода. Преимущественно используется драйверами PCI-устройств, которые могут быть настроены на произвольные номера портов и отображаемые адреса памяти;
- reiease_resourse — освобождает указанный диапазон, ранее присвоенный устройству ввода/вывода.
Кроме того, в ядре определены псевдонимы для этих функций, относящиеся к портам ввода/вывода: request region присваивает указанный диапазон портов, a reiease region о освобождает ранее присвоенный диапазон портов ввода/вывода. Дерево адресов ввода/вывода, присвоенных устройствам на данный момент, хранится в файле /proc/ioports.
Предыдущая страница | 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 | Следующая страница