Поскольку Менеджер сети и Микроядро отделены друг от друга,
Микроядро может достичь независимости от сетевого оборудования, а
компьютеры, не подключенные к сети, могут выиграть за счет меньшего
объема кода.



Интерфейс Микроядро/Менеджер сети


Микроядро и Менеджер процессов взаимодействуют с Менеджером сети
через специальную неблокирующую очередь в памяти. Эта очередь представляет
собой список передач, которые должен выполнить Менеджер сети. Элементы
очереди содержат всю информацию о конкретной операции (например,
Send(), Reply(), создание виртуального канала (VC), передача
удаленного сигнала и т.д.).

Другим ресурсом операционной системы, используемым для обеспечения
прозрачной передачи сообщений, является буфер виртуального канала.
Выделяемый при создании VC процессом, буфер виртуального канала хранит
данные до завершения операции передачи сообщения на другой узел.

Ниже приведены диаграммы, иллюстрирующие процесс посылки и
приема удаленных сообщений.


Посылка сообщения на удаленный узел



fig: i/sendrmot.gif




Процесс вызывает Send() или Reply() к удаленному узлу.





В случае вызова Send() или Reply() к удаленному узлу,
имеют место следующие события:



  1. Процесс вызывает Send() или Reply(), и Микроядро
    копирует данные из области данных процесса в буфер виртуального
    канала.
  2. Микроядро добавляет в очередь Менеджера сети элемент,
    содержащий идентификаторы отправителя, удаленного получателя и
    указатель на данные в буфере виртуального канала. Если перед этим
    очередь была пуста, то Менеджер сети получает прокси, извещающее о
    том, что появилась новая работа.
  3. Менеджер сети извлекает элемент из очереди.
  4. Менеджер сети посылает элемент соответствующему сетевому
    драйверу.
  5. Менеджер сети начинает передачу данных по сети и отвечает за
    доставку.


В случае распространения сигнала или создания VC, Менеджер
процессов, а не Микроядро, добавляет управляющий пакет в очередь .
Как и в предыдущем случае, Менеджер сети передаст пакет по
назначению.

Получение сообщения с удаленного узла



fig: i/recvrmot.gif




Процесс получает удаленный Send() или Reply().





Допустим, что удаленный узел послал сообщение, как описано выше.
В этом случае на принимающем узле имеют место следующие события:



  1. Сетевой драйвер помещает поступившие по сети данные в
    соответствующий буфер виртуального канала.
  2. Сетевой драйвер информирует Менеджер сети о том, что прием
    завершен.
  3. Менеджер сети использует частный вызов Ядра, извещая его о
    том, что прием завершен.
  4. Микроядро копирует данные из буфера виртуального канала в
    буфер процесса (при условии, что он RECEIVE- или REPLY-блокирован на
    этом виртуальном канале).


Любые управляющие пакеты, которые получает Менеджер сети,
немедленно переправляются Менеджеру процессов через стандартный
примитив Send(). Эти управляющие пакеты используются для
распространения сигналов и создания виртуальных каналов.


Сетевые драйверы


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

Интерфейс между Менеджером сети и драйверами реализован через
очереди в разделяемой памяти. Этот интерфейс разработан таким
образом, чтобы достичь максимально возможной производительности.
Драйвер определяет протокол, подходящий для данного сетевого
носителя.

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



Идентификаторы узла и сети


Каждый узел в локальной сети идентифицируется
двумя числами:

  • физическим идентификатором (ID) узла (или идентификаторами,
    если узел имеет более одной сетевой платы);
  • комбинацией логического ID узла и логического ID сети.


Физический ID узла

Физический ID узла определяется оборудованием. Сетевые платы
обмениваются данными друг с другом, указывая физический ID удаленного
узла, с которым должна быть установлена связь. В случае сети Ethernet
или Token Ring - это большое число, которым неудобно оперировать
людям и утилитам. Например, каждая плата Ethernet или Token Ring
имеет уникальный 48-битный физический ID узла в соответствии со
стандартом IEEE 802. Платы Arcnet, напротив, имеют всего лишь
8-битный ID.

Использование физического ID узла имеет существенный недостаток:
при соединении некоторых сетей может возникнуть конфликт адресов
(особенно в случае Arcnet), или формат адресов может радикально
отличаться.


Логический ID узла

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

Использование логических ID узлов упрощает лицензирование. Также
они позволяют утилитам, которые опрашивают сеть, использовать простой
цикл, в котором логический ID узла изменяется от 1 до количества
узлов.

Соответствие между логическими и физическими ID узлов
устанавливается Менеджером сети. Менеджер сети, когда поручает
драйверу передать данные на другой узел, передает ему физический ID
этого узла.

Логические ID узлов обычно присваиваются по порядку,
начиная с 1. Например, узел, имеющий плату Ethernet, может получить
логический ID 2, который будет соответствовать физическому ID
узла 00:00:c0:46:93:30.

Логические ID узлов должны быть уникальны для всех узлов во всех
соединенных QNX-сетях, чтобы сделать возможным функционирование мостов.


Логический ID сети

ID сети идентифицирует конкретную логическую сеть. Логическая
сеть - это любое оборудование, которое позволяет сетевому драйверу
непосредственно взаимодействовать с сетевым драйвером на другом узле.
Это может быть как просто последовательный порт, так и сложная сеть
Ethernet с аппаратными мостами.

На следующей диаграмме узел 7 имеет две сетевые платы, которые
позволяют ему иметь доступ к узлам в логических сетях 1 и 2. Узлы 8 и
9 имеют по три платы, подключающие их к сетям 1, 2 и 3.

Заметьте, что все логические ID узлов уникальны для всех трех
логических узлов.







Note: Логические ID узлов сети назначаются системным администратором. Более
подробно см. в главе "Установка сети" в книге Руководстве
пользователя
.






fig: i/multinet.gif




Несколько физических сетей сосуществуют посредством логических сетей.






Выбор сети


В случае, когда узлы соединены более чем одной логической сетью,
Менеджер сети может выбирать, какую из сетей использовать для
передачи к удаленному узлу. Например, на приведенном выше рисунке
узел 7 может передавать данному узлу 8, используя либо сеть 1, либо
сеть 2.


Распределение нагрузки

Пропускная способность сети определяется совокупностью скорости
компьютера и скорости сети. Если компьютер может выдавать данные
быстрее, чем сеть может их передавать, то сеть будет ограничивать
пропускную способность.

Например, два компьютера Pentium, соединенные сетью 10BASE-T
Ethernet, будут ограничены 1.1 миллионом байт в секунду, то есть
скоростью передачи данных, обеспечиваемой сетевым оборудованием.
Однако если поместить по две платы Ethernet в каждый из компьютеров
и соединить их отдельными кабелями, то Менеджер сети сможет
передавать данные по обеим сетям одновременно. При большой нагрузке
это обеспечит увеличение пропускной способности в два раза по
сравнению с одной сетью.

Менеджер сети будет пытаться сбалансировать нагрузку, выбирая
сетевой драйвер. В рассмотренном выше примере, если производится
передача с узла 7 на узел 8 по сети 1 и другая передача на узел 8
инициируется на узле 7, то сеть 2 будет автоматически выбрана для
передачи данных.

Отказоустойчивость

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

Вы также можете проектировать системы-"тандемы", в которых две
машины соединены высокоскоростной сетью для нормальной работы и
другой, более дешевой и медленной сетью (например, по
последовательному каналу), которая служит резервом. В случае отказа
первой сети соединение не оборвется, хотя пропускная способность,
конечно же, снизится.


Мосты между сетями QNX

Менеджер сети позволяет любому узлу играть роль моста между
двумя отдельными сетями QNX, базирующимися на стандарте IEEE 802.







Note: Так как QNX использует одинаковый формат пакетов и протокол на всех
IEEE 802 сетях, можно создавать мосты между сетями Ethernet, Token
Ring и FDDI.

Для сетей Arcnet нельзя создавать мосты.





Рассмотрим следующую диаграмму, где одной сети принадлежат узлы
17 и 18, а другой - узлы 18 и 19:





fig: i/relay.gif




Мост между двумя IEEE 802 QNX сетями.





Узлы 17 и 18 находятся в одной сети, поэтому они могут общаться
друг с другом напрямую. То же справедливо для узлов 18 и 19. Но как
могут общаться узлы 17 и 19?

Так как обе локальные сети базируются на IEEE 802, узел 18
автоматически перенаправляет пакеты, позволяя узлам 17 и 18 создать
виртуальный канал. Хотя они и не подключены к одной и той же
локальной сети, узлы 17 и 19, тем не менее, могут общаться друг с
другом.



Сеть TCP/IP


Присущая QNX поддержка сети реализует локальную сеть на основе
собственного частного протокола и оптимизирована для организации
интерфейса между QNX компьютерами. Но для связи с не-QNX системами,
QNX использует ставший промышленным стандартом набор протоколов,
называемый TCP/IP.

По мере того как Интернет стал занимать все большее место в
нашей повсеместной жизни, протокол, на котором он основан - IP
(Internet Protocol) - приобретает все большее значение. Даже если вы
не подключаетесь непосредственно к Интернет как к таковому, IP
протокол и связанный с ним инструментарий поистине вездесущи, делая
IP стандартом "де-факто" для многих частных сетей.

IP используется везде, начиная от простых задач (например,
удаленный вход в систему (login)) и до более сложных (например,
отслеживание биржевых котировок в реальном времени). Все больше и
больше компаний используют World Wide Web ("всемирную паутину"),
основанную на IP, для переписки с клиентами, рекламы и другой деловой
активности.


Менеджер TCP/IP

Менеджер TCP/IP в QNX происходит из Berkley BSD 4.3, который
является наиболее распространенным стеком TCP/IP в Интернет и
использован как основа для многих систем.


Сокет API

Библиотека BSD сокета API была очевидным выбором для QNX 4.
Сокет API является стандартным API для программирования TCP/IP в
среде Unix. В среде Windows, Winsock API базируется на BSD сокете
API. Это облегчает переход между ними.

Имеются все процедуры, которые могут понадобиться прикладным
программистам:


accept()

bind()

bindresvport()

connect()

dn_comp()

dn_expand()

endprotoent()

endservent()

gethostbyaddr()

gethostbyname()

getpeername()

getprotobyname()

getprotobynumber()

getprotoent()

getservbyname()

getservent()

getsockname()

getsockopt()

herror()

hstrerror()

htonl()

htons()

h_errlist()

h_errno()

h_nerr()

inet_addr()

inet_aton()

inet_lnaof()

inet_makeaddr()

inet_netof()

inet_network()

inet_ntoa()

ioctl()

listen()

ntohl()

ntohs()

recv()

recvfrom()

res_init()

res_mkquery()

res_query()

res_querydomain()

res_search()

res_send()

select()

send()

sendto()

setprotoent()

setservent()

setsockopt()

shutdown()

socket()

Распространенные утилиты и демоны из Интернет могут быть легко
перенесены или просто перекомпилированы в такой среде. Это облегчает
использование имеющихся готовых наработок.


Возможность взаимодействия сетей

При разработке Менеджера TCP/IP в QNX в первую очередь
принималась во внимание возможность взаимодействия сетей. Учитывались
как требования RFC, так и реальные условия. Менеджер TCP/IP
охватывает всю функциональность, предлагаемую RFC 1122. Также
поддерживаются протоколы ARP, IP, ICMP, UDP и TCP.

NFS


Network File System (NFS) является приложением TCP/IP,
реализованным на большинстве DOS и Unix систем. NFS позволяет
отображать удаленные файловые системы - или их части - в локальное
пространстве имен. Файлы на удаленной системе показываются как часть
локальной файловой системы QNX.








Note: В QNX 4 для поддержки NFS требуется менеджер Socket. Учтите,
что "облегченная" версия менеджера, Socklet, может быть
использована, если нет необходимости в NFS.




SMB


Server Message Block (SMB), который используется многими различными
серверами, такими как Windows NT, Windows 95, Windows for Workgroups,
LAN Manager и Samba. SMBfsys позволяет клиенту QNX прозрачный
доступ к удаленным дискам на таких серверах.



<!-- 7 -->


<!-- 8 -->

Оконная система Photon microGUI




Эта глава охватывает следующие темы:



Графическое микроядро


Многие встроенные системы нуждаются в пользовательском
интерфейсе. Для сложных приложений или для максимальной простоты
использования, естественным выбором является графическая оконная
система. Однако оконные системы настольных ПК требуют слишком много
системных ресурсов для практического применения во встроенных
системах, где память и стоимость ограничены.

При создании оконной системы Photon microGUI была применена
архитектура микроядра, успешно воплощенная в QNX для создания POSIX
ОС для встроенных систем.


Для успешной реализации ОС на основе микроядра в первую очередь
было необходимо добиться максимальной эффективности IPC (так как от
IPC зависит производительность всей ОС). Благодаря воплощенному в QNX
механизму IPC с низкими издержками, стало возможным создание
структуры GUI как графического "микроядра", окруженного командой
взаимодействующих процессов, общающихся через IPC.


Хотя на первый взгляд это может показаться похожим на построение
графической системы по классической схеме клиент/сервер, используемой
в X Window System, архитектура Photon отличается за счет ограничения
функциональности, реализуемой внутри самого графического микроядра
(или сервера), и распределения большей части функций GUI между
взаимодействующими процессами.


Микроядро Photon выполняется как маленький процесс (размер кода
45K), реализуя только несколько фундаментальных примитивов, которые
внешние опциональные процессы используют для построения более
высокого уровня функциональности оконной системы. По иронии, для
самого микроядра Photon "окна" не существуют. Микроядро Photon не
может также "рисовать" что-либо или управлять мышью либо клавиатурой.


Для управления средой GUI, Photon создает 3-мерное "пространство
событий" и ограничивается только оперированием регионами и
выполнением отсечения и направления различных событий по мере их
прохождения сквозь регионы в этом пространстве событий.


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

В основе "абстракции" микроядра Photon лежит воображаемое
графическое пространство событий, в которое другие процессы могут
помещать регионы. Используя QNX IPC для связи с микроядром
Photon, эти процессы управляют своими регионами для предоставления
графических сервисных функций высокого уровня или для выполнения функций
пользовательских приложений. Для систем с ограниченными ресурсами Photon
может масштабироваться "вниз" за счет удаления процессов,
предоставляющих сервисные функции, а за счет добавления
процессов, предоставляющих сервисные функции, Photon может
масштабироваться "вверх" до полнофункциональной настольной системы.



Пространство событий Photon


"Пространство событий" можно представить как пустое трехмерное
пространство с "корневым регионом" на заднем плане. Пользователи
как будто "смотрят внутрь" этого пространства событий. Приложения
помещают регионы в трехмерное пространство между корневым регионом и
пользователем; они используют эти регионы для генерации и приема
различных типов событий в этом пространстве.

Процессы, которые выполняющие обслуживание драйверов устройств,
помещают регионы на передний план пространства событий. В дополнение
к управлению пространством событий и корневым регионом, микроядро
Photon поддерживает экранный указатель (курсор), проецируемый
как события рисования по направлению к пользователю.




fig: i/regions.gif




Photon использует последовательность регионов, начиная от
корневого региона на заднем плане пространства событий до
графического региона спереди. События рисования двигаются от регионов
приложений к графическому региону. События ввода возникают в регионе
курсора/клавиатуры и двигаются по направлению к корневому региону.





Двигающиеся в пространстве событий события можно представить
себе как "фотоны" (что и дало название оконной системе). Сами
события состоят из набора прямоугольных областей и прикрепленных к
ним данных. По мере движения событий в пространстве событий их
прямоугольники пересекают регионы, принадлежащие различным процессам
(приложениям).

Про события, которые двигаются от корневого региона, говорят,
что они перемещаются наружу (по направлению к пользователю), в то
время как про события от пользователя говорят, что они двигаются
внутрь, по направлению к корневому региону.

Взаимодействие между событиями и регионами лежит в основе ввода
и вывода в Photon. События мыши, клавиатуры и светового пера
двигаются от пользователя к корневому региону, с "прикрепленным" к
ним положением курсора. События рисования возникают в регионах и
двигаются по направлению к региону устройства и пользователю.

Регионы

Каждому региону соответствует прямоугольная область,
определяющая его положение в 3-мерном пространстве событий. Регион
также имеет атрибуты, определяющие, как он взаимодействует с
различными классами событий при пересечении ими региона.
Взаимодействие региона с событиями определяется двумя битовыми
масками:


  • маска чувствительности;
  • маска непрозрачности.

Маска чувствительности определяет, должен ли процесс-владелец
региона оповещаться о пересечении региона тем или иным событием.
Каждый бит маски чувствительности определяет, чувствителен ли регион
к определенному типу событий. Когда событие пересекает регион, для
которого установлен бит (равен 1), копия этого события помещается в
очередь процесса-владельца региона, извещая приложение о прохождении
события через регион. Такое извещение никак не изменяет само событие.

Маска непрозрачности определяет прозрачность региона для тех или
иных событий. Каждый бит этой маски определяет, является ли регион
прозрачным для определенного типа события. При прохождении события
сквозь "непрозрачный" регион, оно модифицируется.

Эти две битовые маски могут быть совместно использованы для
достижения различных результатов. Возможны следующие четыре сочетания
для региона:


Сочетание битовых масок:
Описание:
Нечувствительный, прозрачный.
При прохождении события через регион, оно не модифицируется, и
владелец региона не извещается. Процесс-владелец региона просто не
интересуется событием.
Нечувствительный, непрозрачный.
При прохождении события через регион, оно отсекается; владелец
региона не извещается. Большинство приложений используют такую
комбинацию атрибутов для отсечения событий рисования, чтобы избежать
перерисовки окна событиями рисования, исходящими от лежащих под ним
окон.
Чувствительный, прозрачный.
Копия события направляется владельцу региона; событие продолжит
движение в пространстве событий, не изменяясь. Процесс, желающий
регистрировать прохождение всех событий, может использовать такую
комбинацию.
Чувствительный, непрозрачный.
Копия события направляется владельцу региона; событие отсекается
регионом. Установив такую комбинацию масок, событие может играть
роль фильтра или преобразователя. Приложение может обработать любое
полученное событие, регенерировать его и при необходимости
преобразовать его каким-либо образом при этом, возможно, изменив
направление движения или координаты. Например, регион может поглощать
события светового пера, выполнять распознавание почерка, а затем
генерировать эквивалентные события нажатия клавиш.


События

Подобно регионам, события могут относиться к различным классам и
иметь различные атрибуты, как, например:

  • регион происхождения;
  • тип;
  • направление;
  • прикрепленный список прямоугольников;
  • специфические для данного события данные.

В отличие от большинства оконных систем, Photon
классифицирует не только ввод (перо, мышь, клавиатура т.д.),
но и вывод (запросы рисования) как события. События могут
генерироваться как регионами, которые процессы поместили в
пространство событий, так и самим микроядром Photon. Определены
следующие типы событий:


  • нажатия клавиш;
  • нажатия пера и кнопок мыши;
  • перемещения пера и мыши;
  • пересечение границ региона;
  • события экспозиции и перекрытия;
  • события рисования;
  • события перетаскивания (drag).

Приложения могут либо ждать наступления событий, и при этом
блокироваться, либо получать асинхронные извещения о приходе события.

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



При пересечении событием непрозрачного региона, прямоугольник
региона "вырезается" из списка прямоугольников события так, что
список описывает теперь только видимую часть события.

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

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

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



fig: i/clipping.gif




Непрозрачные для события рисования регионы вырезаются, в
результате чего получается область, состоящая из прямоугольных
"плиток".





В том случае, если событие рисования целиком отсекается при
пересечении с регионом, оно прекращает существование. Этот механизм
"непрозрачных" окон, изменяющих список прямоугольников события
рисования, обеспечивает правильное отсечение событий рисования по
мере их продвижения от исходного региона (и связанного с ним
процесса) к пользователю.


Графические драйверы


Графические драйверы реализованы как процессы, которые помещают
регион на переднем плане пространства событий. Регион графического
драйвера чувствителен к событиям рисования, исходящим из
пространства событий. Графический драйвер получает события рисования,
когда они пересекают его регион. Можно представить себе, что регион
покрыт "фосфором", который светится при попадании "фотонов".



Так как API рисования Photon накапливает запросы рисования в