Операционная система QNX Neutrino RTOS
Операционная система QNX Neutrino Realtime Operating System. Основные функции стандартов. Локальная память потока. Поддержка защиты памяти в среде разработки. Разделения встраиваемого программного обеспечения на группу взаимодействующих процессов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 06.06.2014 |
Размер файла | 332,7 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
QNX Neutrino RTOS
Операционная система QNX Neutrino Realtime Operating System (RTOS) корпорации QNX Software Systems является микроядерной операционной системой, которая обеспечивает многозадачный режим с приоритетами. QNX Neutrino RTOS имеет клиент-серверную архитектуру. В среде QNX Neutrino каждый драйвер, приложение, протокол и файловая система выполняются вне ядра, в защищенном адресном пространстве. В случае сбоя любого компонента он может автоматически перезапуститься без влияния на другие компоненты или ядро. Хотя система QNX является конфигурируемой, т.е. отдельные модули можно загружать статически или динамически, нельзя сказать, что она использует подход, основанный на компонентах. Все модули полагаются на базовое ядро и спроектированы таким образом, что не могут использоваться в других средах. операционный память локальный
Микроядро ОС QNX Neutrino реализует основные функции стандартов POSIX, используемые во встраиваемых системах реального времени, а также базовые службы обмена сообщениями. Те POSIX-функции, которые не реализованы в микроядре (например, функции файлового или аппаратного ввода/вывода), выполняются дополнительными процессами или разделяемыми библиотеками.
В каждой новой версии микроядра QNX код, предназначенный для реализации обращений к ядру, становился все более компактным. Определения объектов на самых нижних уровнях в коде ядра становились все более четкими, что позволяло увеличить возможности его повторного использования (например, выполнялось сворачивание различных форм POSIX-сигналов, сигналов реального времени и QNX-импульсов в общие структуры данных и код, предназначенный для управления этими структурами).
На самых нижних уровнях микроядра расположено всего несколько базовых объектов, а также четко отрегулированные процедуры для управления ими. Это и есть та основа, на которой строится ОС QNX Neutrino (рис. 2.1).
Некоторые разработчики считают, что компактность и высокая производительность микроядра ОС QNX Neutrino достигается благодаря его реализации в виде ассемблерного кода. В действительности микроядро ОС QNX Neutrino реализовано преимущественно на С, а компактность и высокая производительность достигаются с помощью четко отлаженных алгоритмов и структур данных, а не посредством оптимизации на уровне ассемблерного кода.
Реализация ОС QNX Neutrino
Исторически складывалось так, что операционные системы QNX испытывали на себе "прикладное давление" одновременно с двух сторон спектра вычислительных моделей. С одной стороны, это встраиваемые системы с ограниченными ресурсами памяти, а с другой -- высокотехнологичные машины симметричной многопроцессорной обработки с гигабайтами физической памяти. Именно поэтому при разработке ОС QNX Neutrino в качестве проектных целей были приняты оба эти на первый взгляд исключающие друг друга подхода. Их выбор связан со стремлением значительно расширить функциональный диапазон операционных систем QNX за пределы возможностей других ОС.
Потоки и функции реального времени в POSIX
Поскольку в ОС QNX Neutrino большинство служб по обеспечению работы в реальном масштабе времени и по планированию потоков реализуется прямо в микроядре, эти службы могут работать даже без дополнительных модулей ОС.
Кроме того, некоторые из стандартов POSIX предполагают, что данные службы должны работать даже при отсутствии модели на основе процессов. Для достижения этого, ОС осуществляет прямую поддержку потоков с помощью администратора процессов, который позволяет управлять в том числе и процессами со множеством потоков.
Нужно отметить, что многие исполнительные модули и ядра, предназначенные для работы в реальном масштабе времени, не обеспечивают изоляции между потоками и не имеют модели на основе процессов. Однако без модели на основе процессов невозможно достичь полного соответствия стандартам POSIX.
Системные службы
В микроядре ОС QNX Neutrino существуют системные вызовы (kernel calls), которые служат для управления следующими объектами:
? потоками (threads);
? сообщениями (message passing);
П сигналами (signals);
? часами (clocks);
? таймерами (timers);
? обработчиками прерываний (interrupt handlers);
? семафорами (seamphores);
? блокировками взаимного исключения, или мутексами (mutexes);
ГЗ условными переменными (condvars);
П барьерами (barriers);
ОС QNX Neutrino целиком построена на основе таких вызовов, причем ядро ОС полностью вытесняемо (preemptable), в том числе и во время обмена сообщениями между процессами (обмен сообщениями продолжается с той точки, на которой был прерван перед вытеснением).
Благодаря простоте архитектуры микроядра, появляется возможность устанавливать ограничение на максимальный объем нереентерабельного кода в адресном пространстве ядра, что облегчает решение сложных задач многопроцессорной обработки. В микроядро были включены те службы, которые порождали наиболее короткую ветвь исполняемого кода. Операции, требующие значительных ресурсов (например, загрузка процесса), были переданы внешним процессам и потокам, в которых работа по переключению на контекст другого потока пренебрежительно мала в сравнении с работой по обработке запроса, выполняемой внутри этого потока.
Строгое применение этого подхода к разграничению функций между ядром и внешними процессами развенчивает миф о том, что микроядерной ОС свойственны более высокие накладные расходы (runtime overhead) при выполнении операций, чем операционной системе с монолитным ядром. Если оценить работу, которая выполняется между переключениями контекстов во время обмена сообщениями, и учесть высокую скорость этих переключений в минимизированном ядре, то становится очевидным, что объем времени, расходуемый на выполнение этих Действий, настолько минимален, что становится пренебрежимо малым в сравнении с работой, производимой для обработки запросов от механизма обмена межзадачными сообщениями.
Запрет прерываний или отсутствие вытеснения происходит только на короткие периоды времени (как правило, эти периоды не превышают порядка сотен наносекунд).
При разработке какого-либо приложения (например, приложение реального времени, встраиваемое приложение, графическое приложение и т. п.) про граммисту может понадобиться сделать так, чтобы в нем одновременно выполнялось несколько алгоритмов. Эта одновременность может быть достигнута с помощью модели многопоточности POSIX, в которой процесс состоит из одного или нескольких потоков управления.
Поток можно рассматривать как минимальную "единицу выполнения", т. е. единицу планирования (scheduling) и выполнения в микроядре. Процесс, в свою очередь, можно рассматривать как объект, который содержит в себе эти потоки и который определяет для их выполнения свое "адресное пространство". Процесс всегда содержит по крайней мере один поток.
В зависимости от приложения, потоки могут выполняться независимо друг от друга и не требовать взаимодействия между разными алгоритмами (что является редким случаем), или же для их выполнения требуется тесная взаимосвязь с возможностью быстрого взаимодействия и строгой синхронизации. Для обеспечения такого взаимодействия и синхронизации в ОС QNX Neutrino предусмотрен целый набор специальных служб и механизмов.
В следующих далее вызовах из библиотек pthread_ * (POSIX Threads) не используются вызовы микроядра по управлению потоками:
ОС QNX Neutrino можно конфигурировать определенным образом для реализации некоторого набора потоков и процессов (в соответствии со стандартами POSIX). Все процессы отделены друг от друга с помощью блока управления памятью (Memory Management Unit, MMU), и каждый процесс может содержать один или несколько потоков, использующих адресное пространство процесса.
От используемой среды зависят не только возможности параллельного выполнения задач приложением, но и механизмы межзадачного взаимодействия и синхронизации, которые могут понадобиться для работы этого приложения. ( Примечание j)
Хотя термин "межзадачное взаимодействие" (Interprocess Communication, IPC) обычно относят к процессам, мы используем его для обозначения взаимодействия между потоками (внутри одного процесса или внутри разных процессов).
Атрибуты потока
Хотя потоки внутри процесса и используют совместно одно общее адресное пространство этого процесса, каждый из этих потоков имеет некоторые "собственные" данные. В некоторых случаях эти данные защищаются внутри ядра (например, идентификатор потока tid), в то время как другие данные остаются незащищенными в адресном пространстве процесса (например, каждый поток имеет свой собственный стек). Перечислим некоторые из наиболее важных ресурсов, относящихся к потоку:
? идентификатор потока (tread identifier, tid) -- каждый поток обозначается своим собственным целочисленным идентификатором, начиная с 1. Внутри процесса потоки имеют уникальные идентификаторы;
? набор регистров (register set) -- каждый поток имеет свой указатель команд (Instruction Pointer, IP), указатель стека (Stack Pointer, SP) и другие регистры, составляющие контекст потока;
? стек (stack) -- каждый поток имеет свой собственный стек, хранимый в адресном пространстве процесса, к которому поток относится;
? маска сигналов (signal mask) -- каждый поток имеет свою собственную маску сигналов;
? локальная память потока (ЛПП) (Thread Local Storage, TLS) -- это системная область данных потока. Локальная память потока используется для хранения информации, относящейся к каждому отдельному потоку (например, tid, pid, базовый адрес стека (stack base), errno, привязка ключей и данных, относящихся к потоку). К локальной памяти потока не нужно обращаться напрямую из пользовательского приложения. Поток может использовать содержимое ЛПП как ключ для привязывания пользовательских данных;
О обработчик завершений (cancellation handler) -- содержит функции обратного вызова, выполняемые при завершении потока.
Данные, относящиеся к потоку, реализуются в библиотеке pthread и хранятся в локальной памяти потока. Они обеспечивают механизм, предназначенный для связывания глобального целочисленного ключа процесса (process global integer key) с уникальным значением данных для каждого потока. Для того чтобы использовать данные потока, сначала создается новый ключ, а затем с этим ключом связывается уникальное значение данных (по каждому потоку). Значение данных может, например, представлять собой целое число или являться указателем на динамическую структуру данных (dynamically allocated data structure). После этого ключ может по каждому потоку возвращать то значение данных, с которым он связан.
Типичным примером использования данных потока является их применение для функции, совместимой с механизмом многопоточности и предназначенной для формирования контекста каждого вызывающего потока.
Потоки создаются и уничтожаются динамически, и их количество внутри процесса может изменяться в значительных пределах. Создание потока {pthreadjcreateQ) включает в себя выделение и инициализацию необходимых ресурсов внутри адресного пространства процесса (например, стека потока), а также запуск выполнения потока с некоторой функции в данном адресном пространстве.
Завершение потока (pthread_exit(), pthreadjcancdQ) включает в себя останов потока и освобождение ресурсов потока. Говоря в целом, когда поток запущен, он может находиться в одном из двух состояний: "готов" (ready) или "блокирован" (blocked). Если же говорить более детально, то поток может иметь одно из следующих состояний:
? CONDVAR -- поток блокирован на условной переменной (например, при вызове функции pthreadjcondvar wait());
? DEAD -- поток завершен и ожидает завершения другого потока;
Планирование потоков. Выполнение операций планирования
При каждом вызове ядра, исключении или аппаратном прерывании, в результате которого управление передается коду ядра, выполнение активного потока временно приостанавливается. Действие планирования совершается в момент изменения состояния любого потока независимо от того, в каком процессе поток расположен. Планирование потоков осуществляется по всем процессам сразу.
Как правило, выполнение приостановленного потока через некоторое время возобновляется. При этом планировщик (scheduler) выполняет переключение контекстов с одного потока на другой всякий раз, когда активный поток:
? блокируется (blocked);
? вытесняется (preempted);
? отдает управление (yields).
Когда поток блокируется
Активный поток блокируется, если он должен ожидать какого-либо события (например, ответа на запрос механизма обмена сообщениями, освобождения мутекса и т. д.). Блокированный поток удаляется из очереди готовности (ready queue), после чего запускается поток с наивысшим приоритетом. Когда блокированный поток разблокируется, он помещается в конец очереди готовности на соответствующий приоритетный уровень.
Когда поток вытесняется
Активный поток вытесняется, когда поток с более высоким приоритетом помещается в очередь готовности (т. е. он переходит в состояние готовности (READY) в результате снятия условия блокировки). Прерванный поток остается на соответствующем приоритетном уровне в начале очереди готовности, а поток с более высоким приоритетом начинает выполняться.
Когда поток отдает управление
Активный поток самостоятельно освобождает процессор (sched_yield()) и помещается в конец очереди готовности на данном уровне приоритета. После этого запускается поток с наивысшим приоритетом (в том числе им может быть поток, который только что отдал управление).
Планирование и приоритеты
Каждому потоку назначается свой приоритет. Планировщик выбирает поток для выполнения в соответствии с приоритетом каждого потока, находящегося в состоянии готовности (READY), т. е. способного использовать процессор. Таким образом выбирается поток с наивысшим приоритетом.
Схематически отображает очередь из шести потоков (A--F), находящихся в состоянии готовности (READY). Все остальные потоки (G--Z) блокированы (BLOCKED). Поток А в настоящий момент является активным. Потоки А, В и С имеют наивысший приоритет, поэтому они совместно используют процессор в соответствии с алгоритмом планирования активного потока.
Всего в ОС QNX Neutrino поддерживается до 256 уровней приоритетов. Приоритет выполнения каждого непривилегированного (nonroot) потока может изменяться в пределах от 1 до 63 (наивысший приоритет), независимо от его дисциплины планирования (scheduling policy). Только привилегированные (root) потоки (т. е. потоки, действующий uid которых равен 0) могут иметь приоритет выше 63. Специальный поток с именем idle в администраторе процессов, имеет приоритет 0 и всегда готов к выполнению. По умолчанию поток наследует приоритет своего родительского потока.
Команда procnto -р позволяет изменить диапазон допустимых приоритетов для непривилегированного процесса:
Следует обратить внимание на то, что для предотвращения инверсии приоритетов (priority inversion) ядро может временно повышать приоритет потока.
Потоки, находящиеся в очереди, упорядочиваются по приоритету. В действительности очередь готовых потоков состоит из 256 отдельных очередей -- по одной на каждый приоритет. Потоки выстраиваются в очереди по порядку поступления (FIFO) и в соответствии с их приоритетом. Для выполнения выбирается первый поток с наивысшим приоритетом.
Управление памятью
Некоторые ядра или исполняемые модули реального времени обеспечивают поддержку защиты памяти в среде разработки. Однако редко когда они имеют поддержку защиты памяти в среде исполнения, что, как правило, объясняется слишком большими накладными расходами памяти и производительности. Тем не менее, зашита памяти все больше применяется во встраиваемых процессорах, так как ее преимущества значительно перевешивают те небольшие потери, которые связаны с ее обеспечением.
Главным преимуществом, которое дает защита памяти во встраиваемых приложениях (особенно системах критического назначения), является повышенная отказоустойчивость.
При наличии защиты памяти, если один из процессов в многозадачной среде пытается получить доступ к области памяти, для которой данный тип доступа не был назначен явным образом, MMU-оборудование может известить об этом ОС, которая в этом случае может снять данный процесс.
Таким образом обеспечивается "защита" адресных пространств процессов друг от друга, что позволяет предотвратить сбои памяти, используемой одним процессом, из-за ошибок в коде, исполняемом в другом процессе или даже ОС. Такая защита полезна как в процессе разработки системы реального времени, так и в процессе работы данной системы, т. к. позволяет выполнять послеаварийный анализ.
Во время разработки ошибки исполнения программного кода (например, недействительные указатели (stray pointers) и индексирование вне границ массива) могут приводить к случайной записи данных одним потоком или процессом в пространство данных другого процесса. Если такая перезапись производится в ячейку памяти, ссылка на которую слишком долго
не обновляется, при отладке вы можете потратить очень много времени на поиски "виновного" посредством внутрисхемных эмуляторов и логических анализаторов.
С помощью блока управления памятью (MMU) операционная система может завершить процесс сразу после возникновения ошибки доступа к памяти. Таким образом, программист может быстро узнать о возникшей ошибке вместо того, чтобы через какое-то время получить загадочный отказ системы. ОС может сообщить о месте ошибочной инструкции в процессе или запустить символьный отладчик прямо на этой инструкции.
Блоки управления памятью
Говоря в общем, блок управления памятью занимается тем, что делит физическую память на страницы размером 4 Кбайта. Процессор использует набор из множества таблиц страниц, хранящихся в системной памяти. Эти таблицы служат для описания того, как виртуальные адреса (т. е. адреса памяти, используемые приложением) отображаются в адреса, выделяемые процессором для доступа к физической памяти.
Во время выполнения потока в таблицы страниц, управляемые операционной системой, заносятся данные о том, как адреса памяти, используемые потоков, отображаются в физической памяти системы.
Линейное пространство
Для большого адресного пространства со множеством процессов и потоков количество записей в таблицах страниц, необходимое для описания отображений, может быть весьма большим -- больше чем может хранить процессор. Для сохранения высокой производительности процессор выполняет кеширование часто используемых сегментов внешних таблиц страниц в буфере быстрого преобразования адреса (Translation Look-aside Buffer, TLB).
Однако обработка "пропавших” записей в TLB-кеше -- одна из причин повышения накладных расходов, связанных с работой блоков управления памятью. Для снижения этих накладных расходов в ОС QNX Neutrino предусмотрено несколько различных механизмов на уровне таблиц страниц.
С таблицами страниц связаны биты, которые определяют атрибуты каждой страницы памяти. Страницы могут иметь различные типы доступа: "только чтение", "чтение/запись" и т. д. Как правило, память выполняемого процесса определяется страницами с доступом "только чтение" для кода и "чтение/запись" для данных и стека.
Когда ОС QNX Neutrino применяет операцию переключения контекстов (т. е. приостанавливает выполнение одного потока и возобновляет выполнение другого потока), она указывает блоку управления памятью применить для возобновленного потока потенциально иной набор таблиц страниц. Если ОС переключает контексты между потоками внутри одного процесса, задействование блока управления памятью не требуется.
Когда возобновляется выполнение нового потока, все адреса, сгенерированные в процессе его выполнения, отображаются в физическую память посредством назначенной для него таблицы страниц. Если поток пытается использовать адрес, который не отображен в таблице страниц, или использовать адрес с нарушением определенных атрибутов (например, с записью в страницу, имеющую доступ только на чтение), процессор получит "ошибку" (аналогичную "делению на ноль"), которая обычно реализуется как особый тип прерывания.
Проверяя значение указателя команд, записываемое в стек при возникновении прерывания, ОС может определить адрес команды, вызвавшей ошибку обращения к памяти, и выполнить необходимые в этом случае операции.
Защита памяти в режиме исполнения
Защита памяти полезна не только в процессе разработки -- она также обеспечивает повышенную степень отказоустойчивости во время работы встраиваемых систем. Во многих встраиваемых системах используются программируемые сторожевые таймеры (watchdog timer), предназначенные для того, чтобы следить за системой и ее программным обеспечением и определять, не "зависла” ли она. Однако такой метод менее точен, чем сигнальные устройства на основе MMU.
Аппаратные сторожевые таймеры обычно реализуются в виде сбрасываемого таймера с одним устойчивым состоянием (retriggerable monostable timer). Этот таймер присоединяется к шине сброса процессора. Если системное программное обеспечение перестает передавать сторожевому таймеру стробирующий сигнал (strobe), то через заданное временное значение таймер истекает и вызывает процедуру перезагрузки процессора. Как правило, в системе предусмотрен специальный программный компонент, который проверяет состояние системы и передает сторожевому таймеру стробирующий сигнал, сообщающий о нормальной работе системы.
Этот метод позволяет восстановить работу системы после ее зависания из-за программного или аппаратного сбоя, однако он приводит к полной перезагрузке системы и, возможно, значительному времени простоя.
Программные сторожевые таймеры
Если в системе с защитой памяти во время работы программного обеспечения происходит случайная ошибка, ОС может перехватить это событие и передать его заданному пользователем потоку вместо создания дампа оперативной памяти. Этот поток может определить оптимальный способ восстановления системы после ошибки, не производя полную перезагрузку системы (как это сделал бы аппаратный сторожевой таймер). Программные сторожевые таймеры имеют следующие функции:
? завершение процесса, в котором произошла ошибка из-за нарушения доступа к памяти, и перезапуск этого процесса без закрытия системы;
? завершение процесса, в котором произошла ошибка, и других, связанных с ним процессов; переключение оборудования в "безопасный*' режим и перезапуск связанных процессов по заданной процедуре;
? при возникновении аварийного останова закрытие всей системы по заданной процедуре и включение аварийного звукового сигнала.
Важной особенностью здесь является то, что мы сохраняем интеллектуальное программируемое управление встраиваемой системы, даже если возник сбой в нескольких процессах и потоках в управляющем программном обеспечении. Аппаратный сторожевой таймер все еще остается полезным для восстановления после зависаний по аппаратным причинам, (latch-ups). Однако для сбоев в программном обеспечении существует более эффективное средство.
Кроме того, для корректировки стратегий восстановления система может собирать подробную информацию о сбоях в программном обеспечении. Например, если встраиваемая система включает в себя запоминающее устройство большой емкости (или имеет доступ к нему как внешнему ресурсу -- например, это может быть накопитель на флеш-памяти или жестких дисках, расположенный на другом компьютере), программный сторожевой аймер может в хронологическом порядке периодически генерировать файлы дампов оперативной памяти. Эти файлы можно использовать для по- слеаварийной диагностики.
Во встраиваемых управляющих системах часто используется такой метод "частичного перезапуска" для восстановления после случайных программных сбоев, что помогает операторам избегать долгих простоев системы, а в некоторых случаях они (операторы) даже могут не заметить, как быстро произошло восстановление системы после сбоя. Благодаря дампам оперативной памяти разработчики могут выявлять и исправлять ошибки в программном обеспечении без необходимости воспроизводить возникшие аварийные условия. Аппаратный сторожевой таймер приводит к продолжительным простоям, поэтому, если сравнить его с программным сторожевым таймером, становится очевидным, какой из них является более эффективным.
Послеаварийный анализ дампов оперативной памяти особенно важен для встраиваемых систем критического назначения. Если критическая система дает сбой в условиях реальной работы, всегда должны быть приложены максимальные усилия для выявления причин аварии, с тем чтобы разработать необходимое исправление и своевременно внедрить его в другие системы до возникновения в них подобных ситуаций.
Дампы оперативной памяти дают программистам информацию, необходимую для решения проблемы. Без этих файлов у программистов не будет ничего, кроме непонятных жалоб клиента на то, что "система сломалась”.
Контроль качества
За счет разделения встраиваемого программного обеспечения на группу взаимодействующих процессов, имеющих защищенную (изолированную) память и состоящих из одного или нескольких потоков, мы можем легко рассматривать эти процессы как "компоненты", которые могут повторно использоваться в разных проектах. Посредством явно определенных интерфейсов, имеющих аппаратную поддержку, эти процессы могут быть интегрированы в приложения без риска нарушения общей надежности системы. Кроме того, поскольку точный двоичный образ процесса (не только его исходный код) может быть повторно использован, мы получаем больше возможностей для контроля тех изменений и нестыковок, которые могли появиться после рекомпиляции исходного кода, перекомпоновки программы, применения новых версий инструментов разработки, заголовочных файлов, библиотечных подпрограмм и т. д.
Поскольку двоичный образ процесса может использоваться повторно (с возможностью модификации его работы с помощью ключей из командной строки), наша уверенность в этом двоичном модуле, основанная на опыте его предыдущего использования, позволяет с большей легкостью применять его в новых приложениях, чем если бы двоичный образ процесса изменялся.
Хотя мы, конечно, стремимся минимизировать ошибки в программном коде создаваемых нами систем, нужно понимать, что после выхода продукта, представляющего собой весьма сложную встраиваемую систему, фактически мы уже не имеем возможности что-либо кардинально в нем изменить. Поэтому, вместо того чтобы укрываться в иллюзии, будто ошибок вовсе нет (до тех пор, пока клиент не заявит о них), нам следует избрать для себя тот самый "критический" (''mission-critical") подход и изначально разрабатывать системы с высокой отказоустойчивостью и автоматическим восстановлением после сбоев. И первым правильным шагом в этом направлении может быть использование защиты памяти с помощью блоков MMU, интегрированных в наши встраиваемые системы.
Модель полной защиты памяти
В соответствии с моделью полной защиты памяти (ШП-protection model), которая используется в ОС QNX Neutrino, весь программный код, находящийся в образе, перемещается в новое виртуальное пространство, при этом включается оборудование, реализующее блок управления памяти, и устанавливаются начальные значения отображения таблиц страниц. Это позволяет запустить модуль procnto корректным образом и в среде со включенным блоком управления памятью. Управление данной средой переключается на администратор процессов, который изменяет таблицы отображения в соответствии с запускаемыми процессами.
Изолированное виртуальное адресное пространство
В модели полной защиты памяти для каждого процесса определяется изолированное виртуальное адресное пространство (private virtual memory), которое может охватывать от 2 до 3,5 Гбайт (в зависимости от типа процессора). Это осуществляется с помощью блока управления памятью. Общие накладные расходы, связанные с переключением процессов и передачей сообщений, возрастают из-за повышения сложности в механизме адресации между двумя абсолютно изолированными адресными пространствами.
(Замечание) На процессорах семейства х86( SH-4, ARM и MIPS изолированное адресное пространство начинается с 0, тогда как на процессорах семейства PowerPC адресное пространство от 0 до 1 Гбайт резервируется для системных процессов.
Расходы памяти на таблицы страниц могут увеличиваться на значение от 4 до 8 Кбайт в расчете на каждый процесс. Следует обратить внимание на то, что в такой модели управления памятью есть поддержка POSIX-вызова fork().
Обработка прерываний
Компьютеры не могут работать с бесконечной скоростью, как бы сильно мы этого ни хотели. Поэтому для системы реального времени крайне важно, чтобы вычислительные циклы процессора не тратились впустую. Также очень важно минимизировать время между возникновением внешнего события и выполнением программного кода внутри потока, предназначенного для обработки этого события. Это время называется задержкой (latency).
Наиболее важными формами задержки являются следующие: задержка обработки прерывания (interrupt latency) и задержка планирования (scheduling latency).
(Замечание) Время задержки может быть очень различным в зависимости от производительности процессора и других факторов. Более подробную информацию можно найти на веб-сайте компании QNX Software Systems (www.qnx.com).
Задержка обработки прерывания
Задержка обработки прерывания (interrupt latency) -- это время, прошедшее от момента возникновения аппаратного прерывания до выполнения первой команды обработчиком прерывания в драйвере устройства. В ОС QNX Neutrino прерывания почти всегда остаются разрешенными, поэтому задержка обработки прерывания обычно незначительная. Однако некоторые критические секции программного кода требуют временного запрета прерываний. Обычно максимальное время такого запрета и определяет наибольшую задержку обработки прерывания, и в QNX Neutrino оно составляет очень небольшое значение.
Задержка обработки прерывания (Та) обозначает миитшлшую задержку, которая возникает при условии, что прерывания были разрешены в тот момент, когда произошло данное прерывание. Максимальной время задержки обработки прерывания будет определяться как сумма минимальной задержки и наибольшего времени, за которое ОС (или активный системный процесс) запрещает аппаратные прерывания.
Задержка планирования
В некоторых случаях низкоуровневый обработчик аппаратных прерываний должен запланировать запуск обработчика прерываний более высокого уровня (потока). При таком сценарии обработчик прерываний возвращается и сообщает о необходимости передачи события. Здесь возникает вторая форма задержек -- задержка планирования.
Задержка планирования -- это время между последней командой обработчика прерываний и выполнением первой команды потока драйвера. Как правило, это означает время, за которое выполняется сохранение контекста текущего потока и загрузка контекста требуемого потока драйвера. Хотя задержка планирования происходит дольше, чем задержка обработки прерывания, в ОС QNX Neutrino этот период времени также имеет довольно небольшое значение. Важно отметить, что большинство прерываний завершается без передачи события. Как правило, обработчик прерываний может самостоятельно решить все вопросы аппаратного уровня. Передача события для пробуждения потока драйвера верхнего уровня осуществляется только в том случае, когда происходит значительное событие. Например, во время взаимодействия с драйвером последовательных портов обработчик прерываний может передавать оборудованию один байт данных при получении каждого прерывания передачи данных и запускать поток более высокого уровня (т. е. поток модуля devc-ser*) только в том случае, когда выходной буфер почти пуст.
Вложенные прерывания
Этот механизм полностью поддерживается в ОС QNX Neutrino. В предыдущих сценариях описывалась самая простая и наиболее распространенная ситуация, когда возникает только одно прерывание. Однако для получения максимального значения задержки в отсутствие немаскированных прерываний следует рассматривать время с учетом сразу всех текущих прерываний, так как немаскированное прерывание с более высоким приоритетом будет вытеснять текущее прерывание.
На рис. 2.25 показан выполняемый Поток А. Прерывание IRQx запускает обработчик прерываний Intx, который вытесняется прерыванием IRQy и обработчиком прерываний lnty. Обработчик прерываний Inty возвращает событие, которое запускает Поток В, а обработчик прерываний Intx возвращает событие, которое запускает Поток С.
Вызовы, связанные с прерываниями
Программный интерфейс обработки прерываний включает в себя следующие вызовы ядра.
Посредством этого программного интерфейса поток с соответствующими пользовательскими привилегиями может вызывать функцию InterruptAttachQ или Interrupt Attach EventQ, передавая номер аппаратного прерывания и адрес функции в адресном пространстве потока, которая должна быть вызвана при возникновении прерывания. ОС QNX Neutrino позволяет с каждым номером аппаратного прерывания связывать множество обработчиков прерываний (ISR). Немаскированные прерывания могут обрабатываться во время выполнения уже запущенных обработчиков прерываний.
Далее приводится пример программного кода, с помощью которого обработчик прерываний (ISR) присоединяется к аппаратному прерыванию таймера (которое ОС также использует в качестве системных часов). Обработчик прерываний таймера, имеющийся в ядре, самостоятельно выполняет очистку источников прерываний, поэтому он только увеличивает значение счетчика в пространстве данных потока и затем передает управление ядру.
В результате пользовательские потоки, имеющие соответствующие привилегии, могут динамически присоединять (и отсоединять) обработчики прерываний к (от) векторам аппаратных прерываний в процессе их выполнения. Эти потоки могут быть отлажены на уровне исходного текста с помощью обычных отладочных средств, а сам обработчик прерываний может быть отлажен посредством вызова этого обработчика на уровне потока и пошагового выполнения на уровне исходного текста или посредством вызова функции InterruptAttachEventQ.
Когда происходит аппаратное прерывание, процессор вызывает модуль первичной обработки прерываний (interrupt redirector) микроядра. Данный модуль записывает на стек регистровый контекст выполняемого потока в соответствующий элемент таблицы потоков и затем устанавливает такой контекст, чтобы у обработчика прерываний был доступ к программному коду и данным потока, в котором содержится этот обработчик прерываний. Таким образом, обработчик прерываний получает возможность использовать буферы и код в пользовательском: потоке для определения источника возникшего прерывания и, в случае если поток требует выполнения работы более высокого уровня, сгенерировать событие для того потока, в который входит данный обработчик прерываний, после чего этот поток может обработать данные, которые обработчик прерываний поместил в принадлежащий ему буфер.
Поскольку обработчик прерываний отображается в контекст содержащего его потока, он может непосредственно оперировать устройствами, отображенными в адресном пространстве потока, или самостоятельно выполнять команды ввода/вывода. В результате это избавляет от необходимости связывать драйверы устройств с ядром.
Модуль первичной обработки прерываний, который содержится в микроядре, вызывает все обработчики, связанные с данным аппаратным прерыванием. Если возвращенное значение указывает на то, что процессу должно быть передано некоторое событие, ядро ставит это событие в очередь. После того как последний обработчик прерываний вызывается для обработки данного вектора прерываний, обработчик прерываний ядра завершает работу с устройством управления прерываниями и "возвращается из прерывания".
Этот возврат из прерывания не обязательно должен приводить в контекст прерванного потока. Если событие, поставленное в очередь, заставило поток с более высоким приоритетом перейти в состояние готовности (READY), то микроядро выполнит возврат из прерывания в контекст потока, который является активным в текущий момент.
Таким образом устанавливается период (т. н. задержка обработки прерывания) между возникновением прерывания и выполнением первой инструкции обработчика прерываний, а также период (т. н. задержка планирования) между последней инструкцией обработчика прерываний и первой инструкцией потока, приведенного обработчиком прерываний в состояние готовности.
Период максимальной задержки обработки прерывания строго определяется благодаря тому, что ОС запрещает прерывания только на время выполнения нескольких инструкций в нескольких критических секциях программного кода. Периоды, в течение которых прерывания запрещены, продолжаются строго определенное время и не имеют зависимости от данных.
Модуль первичной обработки прерываний, имеющийся в микроядре, выполняет несколько инструкций перед тем, как вызвать обработчик прерываний. В результате вытеснение процессов по аппаратным прерываниям или вызовам ядра происходит одинаково быстро и посредством одной и той же цепи инструкций.
Во время своей работы обработчик прерываний имеет полный доступ к оборудованию (поскольку является частью привилегированного потока), но другие вызовы ядра выполнять не может. Обработчик прерываний должен реагировать на аппаратное прерывание с максимально возможной скоростью, выполнять минимальный объем работы для обслуживания прерывания (чтение байта из универсального асинхронного приемопередатчика (UART) и т. д.) и, при необходимости, производить планирование потока с некоторым приоритетом для выполнения дальнейшей работы.
Максимальная задержка обработки прерывания для заданного аппаратного приоритета может быть непосредственно вычислена, исходя из значения задержки обработки прерывания, вносимой ядром, и максимального времени работы обработчика прерываний по каждому прерыванию, имеющему более высокий аппаратный приоритет, чем заданный обработчик. Поскольку приоритеты аппаратных прерываний могут переназначаться, самому важному прерыванию в системе можно присвоить наивысший приоритет.
Следует отметить, что вызов функции InterruptAttachEventQ не приводит к запуску обработчика прерываний. Вместо этого по каждому прерыванию генерируется заданное пользователем событие. Как правило, это событие приводит к планированию ожидающего потока, чтобы он мог выполнить основную работу. Прерывание автоматически маскируется после генерации события и должно в нужный момент явно демаскироваться потоком, обслуживающим устройство.
Таким образом, приоритет работы, осуществляемой по аппаратным прерываниям, может регулироваться самой операционной системой, а не оборудованием. Источник прерывания не генерирует нового прерывания до тех пор, пока не будет обслужено текущее, что позволяет управлять действием прерываний на критические секции программного кода и осуществлять высокоточное управление планированием.
Пользовательские процессы и потоки могут "перехватывать" не только аппаратные прерывания, но и различные "события" внутри микроядра. Когда происходит какое-либо из этих событий, ядро может вызвать указанную внешнюю функцию (upcall) в пользовательском потоке для обработки данного события. Например, при каждом вызове потока idle пользовательский поток может указать ядру сделать внешний вызов для реализации специальных режимов энергосбережения оборудования.
Сетевая архитектура
Как и другие процессы, реализующие различные службы в ОС QNX Neutrino, сетевая служба работает вне ядра. Разработчики имеют единый интерфейс независимо от конфигурации или количества задействованных сетей.
Такая архитектура позволяет:
· динамически запускать и останавливать сетевые драйверы;
· организовывать совместную работу протоколов Qnet, TCP/IP и других в любой комбинации.
Сетевая служба в ОС QNX Neutrino состоит из исполняемого модуля сетевого администратора (io-net) и одного или нескольких модулей разделяемых библиотек (рис.). Эти модули могут включать в себя протоколы (например, npm-qnet. so, npm-tcpip.so), драйверы (devn-ne2000 . so) и фильтры.
Сетевой администратор io-net
Компонент io-net является активным исполняемым модулем сетевой службы. Действуя наподобие обработчика/мультиплексора пакетов, модуль io- net отвечает за загрузку модулей протоколов и драйверов на основе конфигурации, заданной в командной строке (или по команде mount, заданной после запуска модуля io-net).
Благодаря архитектуре, исключающей копирование данных, исполняемый модуль io-net способен "на лету" эффективно загружать множество сетевых протоколов, фильтров или драйверов (например, npm-qnet. so, npm-tcpip.so). Эти модули загружаются как разделяемые объекты, которые устанавливаются внутри модуля io-net.
Модуль фильтрации
Сетевой администратор io-net позволяет устанавливать модули фильтрации, которые могут быть помещены над или под модулем-источником (producer module) (например, драйвером или протоколом).
Модуль фильтрации перехватывает пакеты данных, поступающих от модуля-источника, находящегося в сетевом администраторе io-net. Это позволяет определенным образом модифицировать, пропускать или отслеживать поступающие пакеты данных. Вы также можете направлять пакеты данных на другие интерфейсы (например, посредством коммутации или маршрутизации). Как правило, фильтрующий модуль помещается над модулем сетевого драйвера (например, Ethernet).
Модуль конвертации
Основная задача модуля конвертации заключается в том, чтобы выполнять инкапсуляцию и деинкапсуляцию пакетов данных, перемещаемых с одного сетевого уровня на другой (например, IP и Ethernet). Конверторы используются для соединения модулей-источников между собой (например, стек сетевых протоколов с сетевым драйвером).
Модули конвертации также реализуют протоколы, используемые для разрешения адресации, используемой модулем сетевого протокола для физических сетевых адресов, поддерживаемых данным сетевым драйвером. Например, сетевой протокол ARP (используемый для преобразования адресов из IP в Ethernet) может быть реализован как часть модуля конвертации.
Модуль сетевого протокола
Модуль сетевого протокола отвечает за реализацию того или иного сетевого протокола (например, Qnet, TCP/IP и т. д.). Все компоненты протоколов исполняются как разделяемые объекты (например, npm-qnet.so) и могут работать одновременно.
Драйверный модуль
Модуль сетевого драйвера отвечает за управление сетевым адаптером (например, NE-2000-совместимый контроллер сети Ethernet). Каждый драйвер реализуется как разделяемый объект и устанавливается в компонент io-net.
Комплект разработки сетевых драйверов (DDK)
В комплект ОС QNX Neutrino входит несколько сетевых драйверов. Тем не менее, вы можете самостоятельно написать специальный драйвер для своего сетевого оборудования. Комплект разработки сетевых драйверов (Network Driver Development Kit) позволяет упростить выполнение этой задачи. В состав комплекта входит полный исходный код нескольких драйверов, используемых в качестве примера, а также подробные инструкции для решения вопросов, связанных с аппаратной стороной разработки специализированных драйверов, предназначенных для работы в инфраструктуре модуля io-net.
Сеть Qnet. Распределенная среда ОС QNX Neutrino
В ОС QNX Neutrino механизм межзадачного взаимодействия способен прозрачным образом работать внутри целой сети микроядер.
В основе собственной сети ОС QNX Neutrino лежит протокол Qnet, который реализуется в виде сети сильносвязанных доверяемых (trusted) машин. Протокол Qnet позволяет этим машинам эффективно обмениваться ресурсами с минимальными накладными расходами. В сети Qnet вы можете пользоваться стандартными утилитами (ср, mv и т. д.) для управления файлами в любом месте сети, как если бы эти файлы находились на вашей собственной машине. Кроме того, протокол Qnet не выполняет аутентификацию удаленных запросов, так как файлы защищаются обычными правами доступа, применяемыми для пользователей и пользовательских групп. Вы можете не только иметь доступ к файлам, но и запускать или останавливать процессы (в том числе различные администраторы) на любой машине в сети Qnet.
Возможности распределенных вычислений в сети Qnet позволяют эффективно выполнять следующие задачи:
· использовать удаленную файловую систему;
· масштабировать приложения с невероятной легкостью;
· создавать приложения, в которых используется множество процессов, прозрачным образом взаимодействующих между собой посредством механизма обмена сообщениями;
· с легкостью переносить выполнение приложения с одного процессора или симметричной мультипроцессорной машины на несколько однопроцессорных машин и распределять все процессы между этими процессорами;
· разбивать приложение на несколько процессов, выполняющих разные функции (при этом процессы координируют свою работу с помощью механизма обмена сообщениями);
· использовать собственную службу удаленного вызова процедур сети Qnet.
Поддержка стека протоколов TCP/IP
Поскольку роль Интернета в нашей повседневной жизни становится все более заметной, протокол IP (Internet Protocol), на котором он основан, становится все более важным. IP-протокол и связанные с ним инструменты имеют широкое распространение, что делает его по сути стандартом для многих частных сетей.
IP-протокол способен выполнять множество задач: от простых (например, удаленный доступ) до более сложных (например, передача в реальном времени сводок с фондовых бирж). Многие предприятия начинают использовать в своей работе Всемирную Сеть (которая, как правило, основана на IP- протоколе) для взаимодействия с клиентами, передачи рекламы и других целей. ОС QNX Neutrino отлично подходит для самых разных применений, связанных с глобальной сетью Интернет, начиная от встраиваемых сетевых устройств и заканчивая маршрутизаторами, которые как раз и служат для того, чтобы Интернет мог работать.
С учетом всех этих и многих других требований, для ОС QNX Neutrino был разработан стек протоколов TCP/IP (npm-tcpip), который может работать с минимальными ресурсами и использует обычный программный интерфейс BSD.
Конфигурации стека
Для ОС QNX Neutrino поставляются три различных конфигурации стека:
? Стек Net BSD TCP/IP. Поддерживает новейшие спецификации RFC по протоколам UDP, IP, TCP и SCTP. Также поддерживает перенаправление данных (forwarding), широковещание (broadcast), многоадресную передачу (multicast), функцию аппаратной контрольной суммы, сокеты маршрутизации, сокеты доменов Unix, стандарт multilink РРР, протокол РРРоЕ, протокол C1DR (бесклассовая междоменная маршрутизация), фильтрацию NAT/IP, протокол разрешения адресов ARP, протокол ICMP, протокол IGMP, а также протоколы CIFS, DHCP, AutoIP, DNS, NFS (версию 2 и версию 3 "сервер-клиент"), NTP, RIP, RIPv2 и встраиваемый вебсервер. Для создания приложений для этого стека используется стандартный программный интерфейс BSD Socket. Также включает в себя оптимизированный код для перенаправления пакетов, позволяющий повысить производительность и эффективность маршрутизации пакетов при работе стека в качестве сетевого шлюза.
? Расширенный стек NetBSD, включающий протоколы fPsec и IPv6. Включает в себя все возможности стандартного стека, а также функции, предназначенные для работы с новым поколением мобильных и безопасных каналов передачи. Этот стек обеспечивает полную поддержку протоколов IPv6 и IPsec (для IPv4 и IPv6) посредством расширений КАМЕ. Кроме того, обеспечивается поддержка виртуальных частных сетей (VPN) посредством IPsec-туннелей. Этот двухрежимный стек поддерживает одновременно протоколы IPv4 и IPv6, а также имеет поддержку ав- токонфигурирования в IPv6, что позволяет выполнять конфигурирование устройств в сетевых средах с возможностями plug-and-play. Поддержка IPv6 включает в себя утилиты для этого протокола, а также поддержку протоколов RIP/RIPng для осуществления динамической маршрутизации. Для обеспечения расширенных возможностей протокола IPv6 в дополнение к стандартному программному интерфейсу сокетов предоставляется расширенный программный интерфейс Advanced Socket. Поддержка IPsec обеспечивает безопасное взаимодействие между узлами или сетями посредством сервиса секретности данных на основе мощных криптографических алгоритмов и средств аутентификации данных. Поддержка IPsec также включает в себя протокол управления ключами IKE (ISAKMP/Oakley), который позволяет устанавливать безопасные связи между узлами.
? Встраиваемый стек TCP/IP. Этот компактный стек (80 Кбайт) разработан для применения в системах с ограниченными ресурсами. Обеспечивает полную поддержку протоколов IP, TCP, UDP over Ethernet, РРР и РРРоЕ. Для разработки приложений используется интерфейс BSD Socket. Кроме того, имеется возможность переключения между встраиваемым стеком и стеком NetBSD без необходимости выполнять перекомпиляцию.
Отметим, что стек протоколов QNX TCP/IP является модульным. Например, сетевая файловая система NFS включена в него как отдельный модуль. Благодаря такой модульности, а также компактности модулей, разработчики встраиваемых систем могут легко и быстро создавать небольшие системы с поддержкой протокола TCP/IP.
Для настройки стека протоколов QNX TCP/IP разработчики имеют возможность использовать исходный код некоторых компонентов (например, io-net, npm-tcpip.so). Комплекты с исходным кодом также включают в себя простые примеры модулей io-net, которые помогают разработчикам создавать или переносить исходный код в архитектуру io-net.
Структура администратора протокола TCP/IP
Ценной особенностью модуля npm-tcpip, как, впрочем, и всех администраторов ресурсов в ОС QNX Neutrino, является его компактность и стандартный интерфейс. Благодаря естественному наследованию приоритетов в механизме межзадачного взаимодействия ОС QNX Neutrino, клиенты обслуживаются с учетом приоритета и в определенном временном порядке, что позволяет естественным образом распределять вычислительные ресурсы.
Поддержка канала передачи данных в основном реализуется вне модуля npm-tcpip. Модули реализации протокола РРР существуют отдельно в виде разделяемых объектов. Поскольку эти модули (npm-pppmgr .so, npm- pppoe.so) выполняют передачу РРР-пакетов, копирование пакетов данных в память не требуется. Такой подход позволяет реализовывать по протоколу РРРоЕ высокопроизводительные соединения.
Следует отметить, что стек протоколов npm-tcpip работает как разделяемая библиотека протоколов для администратора сети io-net, который направляет данные на соответствующий драйвер. Сетевые драйверы также являются разделяемыми библиотеками.
Другие компоненты стека протоколов npm-tcpip (например, файловая система NFS, snmpd-демон и т. д.) реализуются вне этого модуля. Это повышает уровень модульности и отказоустойчивости системы.
Программный интерфейс Socket
Программный интерфейс BSD Socket был очевидным выбором для ОС QNX Neutrino. Socket API является стандартным программным интерфейсом по программированию TCP/IP в мире UNIX. Что касается мира Windows, то в нем существует Winsock API, который создан на основе BSD Socket API и имеет много общего с ним, что делает оба эти API совместимыми между собой.
Подобные документы
Операционная система (ОС) как комплекс служебных и программных средств. Базовое программное обеспечение компьютера, BIOS - опора для программного обеспечения, прикладных и служебных приложений. Функции ОС, файловая система, базовые объекты Windows.
контрольная работа [505,3 K], добавлен 24.11.2009Общее понятие и устройство компьютера. Внешние устройства ввода и выводы информации. Клавиатура и ее основные составляющие. Операционная система Windows и понятие программного обеспечения. Назначение и параметры папки и файла, действия над ними.
реферат [1,2 M], добавлен 06.03.2011Понятие и содержание программного обеспечения персонального компьютера, специфика его структуры и элементы, операционная система и ее функциональные особенности. Операционная система Windows 7, ее возможности и преимущества, отличительные признаки.
контрольная работа [3,5 M], добавлен 09.12.2011История разработки многозадачной операционной системы POSIX-стандарта - FreeBSD; описание ее виртуальной памяти, файловой системы, уровня защиты. Описание основных средств синхронизации процессов - сигналов и семафоров. Способы блокировки файлов.
презентация [584,2 K], добавлен 02.06.2011Исследование назначения, основных функций и характеристик операционных систем. Операционная система OS/2: исторический обзор и принципиальные особенности последнего поколения. Управление памятью. Устройства, файловая система и средства взаимодействия.
курсовая работа [1,2 M], добавлен 17.02.2015Операционная система - комплекс взаимосвязанных системных программ, назначение которого - организовать взаимодействие пользователя с компьютером. Роль ОС, предъявляемые требования, которым она должна соответствовать. Перечисление ее основных функций.
презентация [21,3 K], добавлен 05.04.2011Возникновение операционных систем, история их эволюционного развития. Совершенствование прикладного программного интерфейса. Создание и функции резидентного монитора. Основное назначение и роль операционной системы. Программная конфигурация компьютера.
презентация [67,6 K], добавлен 24.10.2012Unix - полноценная, изначально многопользовательская, многозадачная и многотерминальная операционная система. Особенности архитектуры Unix, ее два кита - файлы и процессы. Ядро операционной системы, ее файловая система, работа устройств, драйверы.
реферат [1,0 M], добавлен 22.03.2016Устройство ноутбука, его основные отличия от персонального компьютера. Требования, предъявляемые к переносным компьютерам. Преимущества и недостатки операционной системы Windows. Современная операционная система как сложный комплекс программных средств.
контрольная работа [33,8 K], добавлен 14.11.2013Изучение технических возможностей операционной системы Windows XP – ОС семейства Windows NT корпорации Microsoft. Особенности интегрированного программного обеспечения. Дополнительные аплеты в панели управления Windows. Графический интерфейс пользователя.
презентация [7,4 M], добавлен 23.05.2010