Операционная система QNX 4.Архитектура системы

         

Адаптивное планирование


При адаптивном планировании процесс ведет себя следующим образом:

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

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

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

Методы планирования

Процесс А продолжает выполняться до истечения кванта времени, после чего в зависимости от алгоритма планирования определяется, что произойдет дальше.

Рис. 11



Администратор файловой системы DOS


В системе QNX работа с пространством имен ввода/вывода организована посредством префиксов, которые адресуют запросы на доступ к файлам к соответствующему процессу-администратору. Это использует Администратор файловой системы DOS (Dosfsys). Dosfsys работает с префиксом /dos и представляет набор файлов DOS в пространстве имен системы QNX как "гостевую" файловую систему.

Dosfsys обеспечивает прозрачный доступ к дискам DOS таким образом, что с файловыми системами DOS можно работать также, как с файловыми системами QNX. Эта прозрачность позволяет процессам работать с файлами DOS непосредственно.

Стандартные библиотечные функции ввода/вывода, такие, как open(), close(), read() и write() работают идентично как с файлами раздела DOS, так и с файлами раздела QNX.

Например, для того, чтобы скопировать файл из раздела QNX в раздел DOS, достаточно ввести команду

cp /usr/luc/file.dat /dos/c/file.dat ----- | составное имя диска DOS С:, | работающего под QNX |

Команда cp не содержит никаких специальных признаков, позволяющих определить, находится ли копируемый файл в разделе DOS. Другие команды также работают в прозрачной среде (например: cd, ls, mkdir).

В том случае, если не существует эквивалента функции QNX в среде DOS, например, mkfifo() или link(), то Dosfsys возвращает соответствующий код ошибки (errno).

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

Для выполнения программ DOS в среде QNX существует специальный пакет Rundos.





Альтернативные префиксы


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

префикс = строка-замена

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

/=//10/

В этом случае ведущий символ (/) будет заменяться префиксом //10/. Например, имя

/usr/dtdodge/test

будет заменено на

//10/usr/dtdodge/test.

Это новое имя будет сопоставляться с деревом префиксов узла 10, т.к. оно начинается с символов "//10". В результате запрос open() будет направлен Администратору файловой системы узла 10. Таким образом, альтернативное имя позволит обеспечить доступ к удаленной файловой системе, как к своей собственной.

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

/dev = 5,а:/=//10/

В этом случае имена, начинающиеся с "/dev", будут адресованы своему Администратору устройств, а запросы с другими именами - к администраторам удаленной файловой системы.



Архитектура ядра системы QNX


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

Микроядро системы QNX координирует работу системных администраторов.

Рис. 1



Балансировка нагрузки


Пропускная способность сети определяется как бысродействием используемых в ней компьютеров, так и скоростью передачи данных, которую может обеспечить сетевое оборудование. Если компьютер выдает данные в сеть быстрее, чем сеть может принять их, то в этом случае общую пропускную способность сети ограничивает используемое сетевое оборудование. Например, два 486-х компьютера, соединенные по сети Arcnet будут ограничены предельной для этой сети скоростью передачи 2,5 Мбит/сек. Если поставить по две сетевые карты Arcnet в каждый компьютер и соединить их отдельными кабелями, то Сетевой администратор сможет передавать данные по двум сетям одновременно. При высокой нагрузке это позволит обеспечить производительность в два раза большую, чем производительность одной сети.

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



Битовая карта


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



Блок загрузчика


Блок загрузчика_-_это первый физический блок раздела диска. Этот блок содержит программный код, который загружается и затем выполняется базовой системой ввода/вывода (BIOS) компьютера, при загрузке операционной системы из раздела.

Если диск не разбит на разделы (например, в случае гибкого диска), то этот блок является первым физическим блоком диска.



Блокировка сигналов


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

Во время работы обработчика сигналов QNX автоматически блокирует обрабатываемый сигнал. Это означает, что не требуется организовывать вложенные вызовы обработчика сигналов. Каждый вызов обработчика сигналов непрерываем остальными сигналами данного типа. При нормальном возврате управления от обработчика, сигнал автоматически разблокируется.

В некоторых версиях системы UNIX работа с обработчиком сигналов организована некорректно, так как в них не предусмотрена блокировка сигналов. В результате в некоторых приложениях, работающих под управлением UNIX, используется функция signal() внутри обработчика прерываний с целью "перевзвода" обработчика. В этом случае может возникнуть одна из двух аварийных ситуаций. Во-первых, если другой сигнал поступает, во время работы обработчика, но вызова функции signal() еще не было, то программа будет снята с обработки. Во-вторых, если сигнал поступает сразу же после вызова обработчиком функции signal(), то обработчик будет запускаться рекурсивно. В QNX выполняется блокировка сигналов, поэтому указанные выше проблемы не могут возникнуть. Нет необходимости вызывать signal() из обработчика. Если требуется выйти из любой точки обработчика, то следует воспользоваться функцией siglongjmp().



Более сложные средства таймирования


Процесс может также создавать таймеры, задавать им временной интервал и удалять таймеры. Эти более сложные средства таймирования соответствуют стандарту POSIX 1003.4/Draft 9.



Чтение или запись части сообщения


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

Например, администратор ввода/вывода может принимать для записи сообщения, состоящие из заголовка фиксированной длины и переменного количества данных. Заголовок содержит значение количества байт данных (от 0 до 64 Кбайт). Администратор ввода/вывода может принимать сначала только заголовок, а затем, используя функцию Readmsg(), считывать данные переменной длины в соответствующий буфер. Если количество посылаемых данных превышает размер буфера, администратор ввода/вывода может вызывать функцию Readmsg() несколько раз, передавая данные по мере освобождения буфера. Аналогично, функцию Writemsg() можно использовать для сбора и копирования данных в буфер отправителя по мере его освобождения, снижая таким образом требования к размеру внутреннего буфера администратора ввода/вывода.



Чтение элементов каталога


Для чтения элементов каталога используется набор POSIX-функций языка Си, которые обеспечивают к ним мобильный доступ:

opendir() readdir() rewinddir() closedir()

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



Что наследует процесс


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

Что наследуется fork() exec() spawn()
Идентификатор процесса Нет Да Нет
Открытые файлы Да На выбор* На выбор
Блокировка файлов Нет Да Нет
Задержанные сигналы Нет Да Нет
Маска сигнала Да На выбор На выбор
Игнорируемые сигналы Да На выбор На выбор
Обработчик сигналов Да Нет Нет
Переменные среды Да На выбор На выбор
Идентификатор сеанса Да Да На выбор
Группа процесса Да Да На выбор
Реальные идентификаторы Да Да Да
Группы и пользователя ( UID, GID )
Эффективные UID, GID
Да На выбор На выбор
Текущий рабочий каталог Да На выбор На выбор
Маска создания файлов Да Да Да
Приоритет Да На выбор На выбор
Метод планирования Да На выбор На выбор
Виртуальные каналы Нет Нет Нет
Символические имена Нет Нет Нет
Таймеры реального времени Нет Нет Нет
Примечание.

* - вызывающий процесс может по необходимости выбрать - да или нет.



Что такое файл


В системе QNX под файлом понимается объект, над которым может быть выполнена либо операция записи, либо операция чтения, либо обе эти операции. В QNX имеется шесть типов файлов, пять из которых поддерживает администратор Fsys:

регулярные файлы - содержат последовательность байтов, доступ к которым произволен, и которые не имеют заранее определенной внутренней структуры;
каталоги - содержат информацию, необходимую для определения местонахождения регулярных файлов; кроме того, содержат информацию о статусе и атрибутах каждого регулярного файла;
символические связи - содержат составное имя файла или каталога, к которым требуется обеспечить доступ, вместо файла символической связи. Эти файлы часто используются для обеспечения доступа разными путями к одному и тому же файлу;
программные каналы (pipe) и простые очереди (FIFO) - служат каналами ввода/вывода между взаимодействующими процессами;
блок-ориентированные - описывают устройства, такие как накопители на дисках,
специальные файлы - накопители на магнитной ленте, и разделы диска. Доступ к этим файлам организован таким образом, что технические характеристики устройств "скрыты" от использующих их приложений.

Все эти типы файлов подробно рассматриваются в этом разделе. Шестой тип файла - (символьный специальный файл), относится к сфере управления Администратора устройств.



Что такое QNX


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

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

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

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

Уникальная эффективность, модульность и простота системы QNX определяется:

архитектурой ядра; взаимодействием между процессами посредством сообщений.



Демонтирование файловой системы


Для демонтирования файловой системы используется утилита umount. Например, следующая команда демонтирует файловую систему вашего исходного раздела QNX

umount /dev/hd0t77

После демонтирования файловой системы доступ к файлам ее раздела становится невозможным.



Диски и дисковые подсистемы


В системе QNX каждый физический диск компьютера представлен блок-ориентированным специальным файлом.

С точки зрения файловой системы QNX диск рассматривается как последовательный набор блоков, длиною по 512 байт каждый, независимо от объема диска. Блоки нумеруются, начиная с первого блока диска (блок1).

Поскольку каждый диск - это блок-ориентированный специальный файл, то он может быть открыт для доступа на физическом уровне, с использованием функций Си стандарта POSIX, таких, как open(), close(), read() и write(). На уровне блок-ориентированного специального файла, который определяет весь диск, система QNX не накладывает никаких ограничений на структуры данных, которые могут существовать на диске.

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



Дополнительная информация


Ниже приведена дополнительная информация о передаче сообщений, которую полезно знать.

Данные, передаваемые в сообщении, находятся в процессе-отправителе до тех пор, пока получатель не будет готов к обработке сообщения. Сообщение не копируется в ядро. Это обеспечивает сохранность данных, так как процесс-отправитель остается SEND-блокированным и не может случайным образом модифицировать данные сообщения. При выдаче запроса Reply() данные, содержащиеся в ответном сообщении, передаются от отвечающего процесса REPLY-блокированному процессу за одну операцию. Функция Reply() не блокирует отвечающий процесс, так как REPLY-блокированный процесс разблокировывается сразу после того, как данные скопируются в его адресное пространство. Процессу-отправителю нет никакой необходимости "знать" что-либо о состоянии процесса-получателя, которому он посылает сообщение. В том случае, если процесс-получатель будет не готов к приему сообщения, то процесс-отправитель после отправления сообщения просто перейдет в SEND-блокированное состояние. При необходимости любой процесс может посылать сообщение нулевой длины, ответ нулевой длины, либо то и другое. С точки зрения разработчика выдача запроса Send() обслуживающему процессу - это практически то же самое, что и обращение к библиотеке подпрограмм. В обоих случаях разработчик формирует некоторые наборы данных, а затем выдает Send() или обращается к библиотечной функции. После этого, между двумя определенными точками программы Receive() и Reply() - в одном случае, либо между входом функции и оператором return - в другом, управление передается сервисным программам, при этом ваша программа ожидает завершения их выполнения. После того как сервисные программы отработали, ваша программа "знает", где находятся результаты их работы, и может затем анализировать коды ошибок, обрабатывать результаты и т.д.
Несмотря на это кажущееся сходство, процесс передачи сообщения намного сложнее обычного вызова библиотечной функции. Например, Send() может по сети обратиться к другой машине, где действительно будет выполняться сервисная программа. Кроме того, может быть организована параллельная обработка данных без создания нового процесса. Обслуживающий процесс выдает Reply(), позволяя вызывающему процессу продолжать выполняться, и затем продолжает свою работу. Несколько процессов могут посылать сообщения одному процессу. Обычно процесс-получатель принимает сообщения в порядке их поступления, однако, может быть установлен режим приема сообщений в порядке приоритетов процессов-отправителей, представленный на рис.5.

Обслуживающий процесс принял сообщения от обслуживаемых процессов А и В, но не ответил на них. Сообщения от процессов C, D, E еще не приняты.

Риc. 5



Дополнительные возможности передачи сообщений


В системе QNX имеются функции, предоставляющие дополнительные возможности передачи сообщений, а именно:

условный прием сообщений; чтение и запись части сообщения; передача составных сообщений.



Доступ к файлу


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

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

только пользователю; только группе; другим пользователям.

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



Драйверы устройств


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

Поскольку драйверы выполняются как стандартные процессы, то добавление нового драйвера в систему QNX не влияет на работу других компонентов операционной системы. Единственное изменение, которое происходит в среде QNX - это запуск нового драйвера.

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



Драйверы устройств


На рис. 25 представлена типичная подсистема устройств QNX.

Рис. 25

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

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

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

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

Каноническая очередь полностью управляется Администратором Dev и используется при обработке входных данных в режиме редактируемого ввода. Размер этой очереди определяется максимальным размером входной редактируемой строки для каждого конкретного устройства.

Размер всех этих очередей устанавливается системным администратором; при этом единственным ограничением является то, что суммарный размер всех трех очередей не может превысить 64 Кбайта. Значения, используемые по умолчанию, обычно больше требуемых для реальных устройств, но их можно настроить для того, чтобы уменьшить размер выделяемой системной памяти или иметь возможность работать в нештатных режимах.



Exec()


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



FIFO-файлы


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

Если вы хотите Используйте
Создать FIFO-файл из интерпретатора Shell Утилиту mkfifo
Создать FIFO-файл из программы Функцию Си mkfifo()
Удалить FIFO-файл из интерпретатора Shell Утилиту rm
Удалить FIFO-файл из программы Функции Си remove() или unlink()



Физические идентификаторы узлов


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



Fork()


Примитив fork() порождает процесс, являющийся его точной копией. Новый процесс выполняется в том же адресном пространстве и наследует все данные порождающего процесса.



Функции Администратора процессов


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

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



Где хранятся экстенты


Файлы, имеющие только один экстент, хранят информацию об экстенте в элементе каталога. Если же для файла требуется более одного экстента, то информация о местонахождении экстента хранится в одном или нескольких блоках связанных экстентов. Каждый блок экстентов может содержать информацию о нахождении 60 экстентов. На рис._20 представлен файл, состоящий из нескольких последовательных областей на диске (экстентов).

Рис. 20



Генерация сигналов


Сигнал выдается процессу при наступлении некоторого заранее определенного для данного сигнала события. Процесс может выдать сигнал самому себе.

Если вы хотите Используйте
Сгенерировать сигнал из интерпретатора Shell Утилиты kill или slay

Сгенерировать сигнал из процесса Функции kill() или raise()



Гибкая сетевая обработка


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

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

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

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

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

Давайте теперь познакомимся ближе со структурой и функциями системы QNX.



Идентификаторы логических сетей


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

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

Обратите внимание на то, что каждый логический ID узла не один и тот же для всех трех логических сетей.

Идентификаторы логических сетей и узлов присваиваются администратором системы. Более подробно об этом см. "Network Installation" в User's Guide.

Несколько физических сетей успешно работают вместе как логические сети.

Рис. 28



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


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



Интерфейс Микроядро/Сетевой администратор


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

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

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

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

Рис. 26

В случае выдачи Send() или Reply() на удаленный узел, происходят следующие действия:

Процесс вызывает функции Send() или Reply(), после чего ядро копирует данные из адресного пространства процесса в буфер соответствующего виртуального канала (ВК), определенного функцией Send() или Reply(); Ядро ставит заявку в очередь к Сетевому администратору в порядке времени ее поступления, указывая в ней отправителя, удаленного получателя и указатели на данные в буфере виртуального канала. Если до этого очередь была пуста, то запускается proxy Cетевого администратора, оповещая его о том, что появилась работа; Сетевой администратор принимает заявку из очереди; Сетевой администратор начинает передачу по сети. Он отвечает за доставку.

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

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

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

Рис. 27

Если удаленный узел послал сообщение так, как это было описано выше, то на узле, принимающем сообщение, будет происходить следующее:

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

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



Исходные тома


Администратор файловой системы управляет блок-ориентированными специальными файлами. Эти файлы определяют диски и разделы дисков.



Использование функции Receive()


Процесс В может принять запрос Send(), выданный процессом А, с помощью функции Receive()

pid = Receive (0, msg, msg_len);

Функция Receive() имеет следующие аргументы:

pid идентификатор процесса, пославшего сообщение (т.е. процесса А);
0 (ноль) указывает на то, что процесс В готов принять сообщение от любого процесса;
msg буфер, в который будет принято сообщение;
msg_len максимальное количество байт данных, которое может поместиться в приемном буфере.

В том случае, если значения smsg_len в функции Send() и msg_len в функции Receive() различаются, то количество передаваемых данных будет определяться наименьшим из них.



Использование функции Reply()


После успешного приема сообщения от процесса А процесс В должен ответить ему, используя функцию Reply()

Reply (pid, reply, reply_len)

Функция Reply имеет следующие аргументы:

pid идентификатор процесса, которому направляется ответ (т.е. процесса А);
reply буфер ответа;
reply_len длина сообщения, передаваемого в ответе.

Если значения reply_len в функции Reply() и rmsg_len в функции Send() различаются, то количество передаваемых данных определяется наименьшим из них.



Использование функции Send()


Предположим, что процесс А выдает запрос на передачу сообщения процессу В. Запрос оформляется вызовом функции Send()

Send (pid, smsg, rmsg, smsg_bn, rmsg_len);

Функция Send() имеет следующие аргументы:

pid идентификатор процесса-получателя сообщения (т.е. процесса В); pid - это идентификатор, посредством которого процесс опознается операционной системой и другими процессами;
smsg буфер сообщения (т.е. посылаемого сообщения);
rmsg буфер ответа (в который помещается ответ процесса В);
smsg_len длина посылаемого сообщения;
rmsg_len максимальная длина ответа, который должен получить процесс А.

Обратите внимание на то, что в сообщении будет передано не более, чем smsg_len байт и принято в ответе не более, чем rmsg_len байт, - это служит гарантией того, что буферы никогда не будут переполнены.



Использование функций Send(), Receive() и Reply()


Давайте теперь рассмотрим функции Send(), Receive() и Reply() более подробно. По-прежнему будем пользоваться нашим примером взаимодействия процессов А и В.



Ядро системы QNX


Ядро является "сердцем" любой операционной системы. В некоторых системах на ядро возложено такое количество функций, что, по сути дела, оно само является полной операционной системой.

В системе QNX ядро является действительно ядром. Прежде всего, как и подобает ядру операционной системы реального времени, оно имеет небольшой размер_-_менее 8 Кбайт. На ядро системы QNX возложено выполнение только двух основных функций:

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

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



Экстенты


В системе QNX регулярные файлы и файлы каталогов хранятся как последовательность экстентов. Экстент - это непрерывная последовательность блоков на диске.



Электронные диски


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

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

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



Элеваторный доступ


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

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



Каталоги


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

На рис. 19 показано, как осуществляется поиск файла /usr/bill/file2 в структуре каталога.

Путь по структуре каталогов QNX к файлу usr/bill/file2

Рис. 19



Кэш-буфер


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

Операции чтения синхронны. Наоборот, операции записи обычно асинхронны. При поступлении данных в кэш-буфер Администратор файловой системы оповещает обслуживаемый процесс о том, что данные записаны. Затем выполняется запись данных на диск, обычно с запаздыванием менее двух секунд.

Программа управления кэш-буфером обычно дает приоритет операциям чтения относительно операций записи. Это правило нарушается только в двух случаях:

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

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



Ключевые компоненты раздела QNX


Несколько ключевых компонентов, находящихся в начале каждого раздела QNX, составляют основу файловой системы:

блок загрузчика; корневой блок; битовая карта; корневой каталог.

Эти компоненты создаются при инициализации файловой системы по команде dinit.

На рис. 24 представлена структура файловой системы QNX в разделе диска.

Рис. 24



Когда выполняется планирование


Планировщик ядра запускается в следующих случаях:

после разблокировки процесса; по истечении временного кванта для выполняющегося процесса; после выгрузки выполняющегося процесса.



Консоль QNX


Системными консолями управляет процесс Dev.con. Консоль - это совокупность видеоадаптера, монитора и системной клавиатуры.

В системе QNX имеется возможность организации параллельной работы посредством виртуальных консолей. Драйвер консоли Dev.con обычно выполняет обработку нескольких наборов очередей ввода/вывода к Администратору Dev, что позволяет процессам пользователя иметь набор периферийных устройств с именами /dev/con1, /dev/con2 и т.д. С точки зрения приложения одновременно используется несколько консолей.

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



Корневой блок


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

корневой каталог файловой системы (/); /.inodes /.boot /.altboot

Файлы /.boot и /.altboot содержат образы операционных систем, которые могут быть загружены программой начальной загрузки QNX.

Обычно программа начальной загрузки QNX загружает образ ОС, хранящийся в файле /.boot. Но в случае непустого файла /.altboot имеется возможность загрузить образ ОС, хранящийся в файле /.altboot.



Корневой каталог


Корневой каталог раздела представляет собой обычный каталог, за исключением следующего:

как "точка", так и "точка точка" являются связями к одной и той же служебной информации, а именно - к служебной информации корневого каталога корневого блока; корневой каталог всегда имеет элементы для файлов /.bitmap, /.inodes, /.boot и /.altboot. Программы, информирующие об использовании файловой системы, воспринимают эти элементы, как обычные файлы.



Круговой метод планирования


При круговом методе планирования процесс, выбранный для выполнения, продолжает работать до тех пор, пока он:

не передаст управления сам; не будет снят с выполнения (выгружен из памяти) процессом с более высоким приоритетом; не истечет его квант времени (timeslice).

Квант времени - это единица временного интервала, закрепляемая за каждым процессом. По истечении кванта времени, процесс выгружается, и управление передается процессу, находящемуся на том же уровне приоритета в состоянии ГОТОВ. Квант времени равен 100 миллисекундам.

За исключением квантования времени круговой метод планирования идентичен планированию по принципу простой очереди.



Логические идентификаторы узлов


Для разрешения указанной выше проблемы с физическими 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.