Когда процесс открывает специальный файл устройства, происходит инициализация соответствующего snode и вызов функции spec_open()
, реализованной в файловой системе specfs, о которой только что говорилось. Эта функция, в свою очередь, вызывает функцию драйвера
, передавая ей в качестве аргумента указатель на номера устройства, сохраненного в поле s_dev
snode. Одной из схем реализации клонов является использование зарезервированного младшего номера. Когда процесс открывает специальный файл устройства с этим номером, функция
выбирает неиспользуемый младший номер и соответственно модифицирует данные snode (с помощью указателя на vnode, передаваемые ей spec_open()
). Поскольку доступ процесса к драйверу осуществляется через vnode файловой системы specfs, все последующие операции будут использовать новый младший номер. Таким образом, процесс получит доступ к новому логическому устройству. Эта схема приведена на рис. 5.6.
Рис. 5.6. Создание клонов с помощью зарезервированного младшего номера
Другой подход заключается в использовании специального драйвера, обеспечивающего создание клонов, —
$ ls -l
...
crw-rw-rw- 1 root sys 11, 44 Oct 31 16:36 arp
crw------- 1 root sys 11, 5 Oct 31 16:36 icmp
crw-rw---- 1 root sys 11, 3 Nov 3 1995 ip
crw------- 1 root sys 11, 40 Nov 3 1995 le
crw-rw-rw- 1 root sys 11, 42 Oct 31 16:36 tcp
crw-rw-rw- 1 root sys 11, 41 Nov 3 1995 udp
...
В данном случае старший номер всех драйверов равен 11 — это драйвер клонов. Если проанализировать информацию файла, скажем, tcp, то станет понятно, что старший номер драйвера этого протокола равен 42, для файла tcp он представлен младшим номером устройства. Когда процесс открывает этот файл, производится вызов функции clopen()
драйвера клонов, которой передаются номера устройства. Функция clopen()
использует младший номер для поиска требуемых точек входа драйвера TCP в коммутаторе устройств cdevswf[]
. После этого clopen()
вызывает процедуру
драйвера, в данном случае tcpopen()
, передавая ей указатель на номера устройства и флаг CLONEOPEN
. В ответ на это tcpopen()
генерирует неиспользуемый младший номер, создает отдельный логический драйвер (т.е. копирует необходимые структуры данных) и соответствующим образом модифицирует поле s_dev
индексного дескриптора файловой системы specfs. Таким образом, для получения уникального TCP-соединения процессу нет необходимости самостоятельно производить поиск неиспользуемого младшего номера.
Встраивание драйверов в ядро
Драйвер устройства является частью кода ядра операционной системы и обеспечивает взаимодействие других подсистем UNIX с физическими или псевдоустройствами. Существует два основных метода встраивания кода и данных драйвера в ядро операционной системы: перекомпиляция ядра, позволяющая статически поместить драйвер, и динамическая загрузка драйвера в ядро в процессе работы системы.
Традиционно для встраивания драйвера в ядро UNIX требуется перекомпиляция ядра и перезапуск системы. Принципиально эта процедура не отличается от компиляции обычной программы, все компоненты ядра являются объектными модулями и редактор связей объединяет их с объектным модулем драйвера для получения исполняемого файла. В этом случае драйвер встраивается в ядро статически, т. е. независимо от фактического наличия устройства и ряда других причин, код и данные драйвера будут присутствовать в ядре UNIX до следующей перекомпиляции.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии