Linux Kernel (Ядро линукса) (часть 2)


Присваивание номеров устройств

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

Каждый элемент списка является структурой char_device_struct, поля которой представлены в табл. 13.10.
Существует два метода для присваивания диапазона номеров устройств драйверу символьного устройства. Первый, который следует использовать ДЛЯ всех НОВЫХ драйверов, основан на функциях register_chrdev_region И aiioc_chrdev_region. Он заключается в присваивании драйверу произвольного диапазона номеров устройств. Например, чтобы получить интервал номеров, начинающийся СО значения dev типа dev_t И имеющий ширину size, нужно написать:
register_chrdev_region(dev, size, "foo") ;
Эти функции не вызывают функцию cdev add , так что драйвер устройства должен вызвать ее сам после успешного получения запрошенного интервала.
Второй метод основан на функции register chrdev и состоит в присваивании фиксированного интервала номеров устройств, включающего в себя один старший номер и младшие номера от 0 до 255. В этом случае драйвер не должен вызывать cdev add .

Функции register_chrdev_region и alloc_chrdev_region

Функция register_chrdev_region принимает три параметра: исходный номер устройства (старший и младший номера), размер запрошенного диапазона номеров (то есть количество требуемых младших номеров) и имя драйвера устройства, который запросил диапазон номеров. Функция проверяет, захватывает ли запрошенный диапазон несколько старших номеров, и, если это так,
определяет старшие номера и соответствующие интервалы, покрывающие
весь диапазон. Затем функция вызывает функцию register_chrdev_region
(описанную далее) для каждого из этих интервалов.

Функция aiioc_chrdev_region аналогична предыдущей, но служит для динамического выделения старших номеров. В качестве параметров она принимает исходный младший номер из интервала, размер интервала и имя драйвера устройства. Эта функция тоже вызывает register chrdev region .
Функция register chrdev region ВЫПОЛНЯет следующие деЙСТВИЯ!
1. Выделяет новую структуру char device struct и заполняет ее нулями.
2. Если старший номер из интервала равен нулю, значит, драйвер запросил динамическое выделение старшего номера. Начиная с последней записи в хеш-таблице и следуя в обратном направлении, функция ищет пустой список коллизий (указатель null), который соответствует еще не задействованному старшему номеру. Если пустая запись не найдена, функция возвращает код ошибки6.
3. Инициализирует соответствующие ПОЛЯ структуры char device struct первым номером устройства из интервала, размером интервала и именем драйвера.
4. Вызывает хеш-функцию для вычисления индекса в хеш-таблице по старшему номеру.
5. Проходит по списку коллизий в поисках корректной позиции для новой структуры char device struct. Если по ходу дела обнаруживается интервал, перекрывающийся запрошенным, функция возвращает код ошибки.
6. Вставляет НОВЫЙ дескриптор char device struct в список коллизий.
7. Возвращает адрес нового дескриптора char device struct.

Предыдущая страница | 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 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без проблем

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга для вас. А так как к книге прилагается компакт- диск с готовой к работе операционной системой Knoppix Live CD, то лишь достаточно вставить его в привод и перегрузить компьютер,...

Linux Kernel (Ядро линукса) (часть 1)

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

Linux Kernel (Ядро линукса) (часть 2)

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно неуклюже: получив системный вызов fork о, ядро в буквальном смысле дублировало все адресное пространство родителя и присваивало копию процессу-потомку. Такая операция...

Linux Kernel (Ядро линукса) (часть 3)

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