Symbian developer community

 
wiki

Symbian OS Internals/1. Introducing EKA2/ru

From Symbian Developer Community

Jump to: navigation, search

Авторы главы: Джейн Салес (Jane Sales) и Мартин Таскер (Martin Tasker)

"Способность цитировать - это весьма полезная замена остроумия."
Уильям Сомерсет Моэм (W. Somerset Maugham)


Contents

История EKA2

Создание ядра операционной системы является одной из самых восхитительных тем в программной инженерии. EKA2 представляет собой второе поколение 32-битной архитектуры ядер от Symbian, в данном случае EKA2 следует за ядрами 8- и 16-битных архитектур, примененных когда-то в органайзерах и PDA от фирмы Psion.

Organiser от фирмы Psion, увидевший свет в 1984 году, имел 8-битный процессор, и поддерживал только встроенные в память программы. Для такого устройства ядро должно было иметь лишь загрузчик операционной системы (bootstrap loader), и небольшой набор системных сервисов. Такой системе не требовалось отделять 8-битное ядро от системных модулей или пользовательских приложений.

В 1986 году фирма Psion создала Organiser II - 8-битное устройство, позволяющее расширять свою функциональность при помощи языка программирования OPL. Требования к операционной системе были уже несколько выше, в частности - значительно лучшее управление памятью для поддержки интерпретируемого языка программирования.

Главная фаза эволюции операционных систем Psion пришлась на начало 90-х годов, когда фирма выпустила целый ряд устройств, включающий портативный компьютер, складной и промышленный органайзеры, каждый из которых использовал одну и ту же операционную систему. 16-битное ядро операционной системы EPOC было привязано к процессорной архитектуре Intel 8086, и поддерживало функциональные расширения не только при помощи языка программирования OPL, но так же при помощи различных API на языке С, доступных из операционной системы. Таким образом, расширение операционной системы EPOC стало возможным любому числу разработчиков программ.

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

Поэтому 16-битное ядро EPOC должно было реализовывать множество всех тех требований, которые и сейчас реализуются ядром EKA2. И все из-за позиции операционной системы от Symbian между встроенными операционными системами реального времени (RTOS), и такими классическими операционными системами настольных компьютеров, как Windows. И хотя операционная система от Symbian была похожа на системы RTOS (она запускалась из памяти ROM), она все же поддерживала бóльшую функциональность и была открыта для сторонних приложений. В то же время, будучи похожей на операционные системы настольных компьютеров (так как система была открытой и использовала архитектуру Intel 8086), она была значительно меньше своих собратьев по причине значительно меньших объемов доступной памяти и ресурсов питания.

В EKA2 было необходимо реализовать два эволюционных улучшения. Операционная система EPOC32, начавшая свою жизнь в 1994 году, была выпущен в 1997 году фиромй Psion вместе с устройствами PDA Series 5. Ее ядро, называемое EKA1, взяло все лучшее от 16-битной архитектуры EPOC, и разрешило несколько серьезных ограничений. Во-первых, ядро EKA1 было полностью 32-битным, безо всяких ограничений со стороны сегментной модели памяти архитектуры Intel 8086. Во-вторых, ядро EKA1 с самого начала разрабатывалось под множество различных машинных архитектур, с возможностью последующей эволюции системы. (16-битное ядро EPOC было жестко привязано к единственному чипсету с процессором Intel 80186.) Так же в связи с озвученными фундаментальными характеристиками были заново переписаны многие элементы системы, однако в то же самое время EKA1 было удивительным образом реализовано в том же духе, что и 16-битное ядро системы EPOC.

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

Однако истории не суждено было закончиться на EKA1. Symbian OS была в целом достаточно эффективна для программирования на основе событий в системе, однако она не давала никаких гарантий реального времени. Само ядро было весьма устойчивым, то есть обладало особенностью, остро необходимой для PDA-устройств, хранящих персональные данные пользователей. Однако как только Symbian OS стала использоваться в мобильных телефонах, стало ясно, что нужна операционная система, предоставляющая приложениям гарантии реального времени.

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

Поэтому было разработано новое ядро. А для отличия нового ядра от его 32-битного оригинала, ему было дано имя EKA2 (или EPOC Kernel Architecture 2).

EKA2 был задуман в 1998 году, и мало по малу вышел на рынок. В 2003 году главные лицензиаты Symbian и партнеры по электронике договорились об использовании ядра EKA2 в своих будущих продуктах.

Данная книга была написана для детального представления нового ядра реального времени, со всеми тонкостями от инженеров, разработавших и реализовавших это ядро.

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

Основные понятия операционной системы

Я хотел бы начать с обычного определение операционной системы (ОС):

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

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

Symbian OS обладает более модульной архитектурой, чем многие другие операционные системы. Например, операции с диском в основном выполняются файловым сервером (file server), в то время как операции с экраном устройства и осуществление пользователем ввода данных реализуется оконным сервером (window server). Однако существует элемент системы, который можно считать ее "сердцем". Элемент, отвечающий за управлением памятью, управлением и планированием задач. Таким элементом, конечно же, является ядро EKA2.

В мире существует множество различных видов операционных систем, поэтому следует дать некоторые характеристики системе Symbian OS, и в частности, ее ядру EKA2:

Symbian OS и EKA2 являются модульными. Как я уже говорил, функциональность операционной системы Symbian OS представлена в виде отдельных блоков, а не в виде одного монолита. Ядро EKA2 в этом смысле так же модульно, в чем вы можете убедиться взглянув на рисунок 1.1.

Ядро EKA2 является однопользовательским. То есть в смартфон с системой Symbian OS нельзя залогиниться нескольким пользователям, как например в системах Windows, Mac OS X, UNIX или любых других операционных системах для мэйнфреймов.

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

File:Internals1-1.jpeg

Рис. 1.1 Архитектура Symbian OS

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

EKA2 использует приоритетную многозадачность с наследованием приоритетов.

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

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

EKA2 может быть встроенной операционной системой, работающей целиком из ROM-памяти.

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

Архитектура Symbian OS

Задачи архитектуры

При создании ядра EKA2 мы поставили перед собой ряд архитектурных задач. Сначала мы определили то, что не хотели бы потерять из архитектуры ядра EKA1. В итоге мы пришли к выводу, что ядро по-прежнему должно быть:

  1. Пригодным для использования в качестве встроенной операционной системы
  2. Пригодным для работы в средах, ограниченных по ресурсам
  3. Модульным: состоять из микроядра, и пользовательских серверов
  4. Портируемым на ряд чипсетов
  5. Устойчивым к плохо написанному пользовательскому коду
  6. Стабильным в отношении сохранности пользовательских данных

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

  1. Время ожидания = 1 ms от прерывания к передачи сигнала пользовательскому потоку
  2. Время ожидания = 500 µs от прерывания к передачи сигнала потоку ядра
  3. Быстрые операции над мьютексом
  4. Где это возможно, ограниченные во времени вызовы функций операционной системы
  5. Вытесняющие вызовы функций операционной системы
  6. Приоритетное ожидание на семафорах и мьютексах
  7. Таймеры с отличным разрешением

Затем мы стали думать как мы еще бы могли улучшить операционную систему, и мы составили следующий список:

  1. Легкость портирования. Хотя ядро EKA1 было создано для облегчения портирования, мы все еще могли бы значительно улучшить жизнь тем, кто портирует нашу операционную систему на новые машинные архитектуры
  2. Устойчивость к вредоносному (а не просто плохо написанному) пользовательскому коду
  3. Создание одноядерного решения, в котором встроенный и пользовательский код мог бы исполняться на одном-единственном процессоре
  4. Создание более качественного эмулятора для разработки и отладки кода, который по своим характеристикам был бы гораздо ближе к реальным устройствам
  5. Упрощение жизни разработчикам драйверов

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

Библиотека EUSER является интерфейсом к ядру операционной системы для всех приложений, созданных под Symbian OS, а на данный момент их уже ой как много!

Архитектура ядра Symbian OS

Со всеми представленными задачами архитектуры, мы создали систему, чье устройство на высшем уровне выглядит так же, как и на рисунке 1.1. На рисунке представлены главные строительные блоки ядра. Я так же добавил к рисунку две других ключевых системных компоненты, которые чаще всего рассматриваются частью операционной системы, и будут рассмотрены в данной книге: это файловый сервер (file server) и сервер окон (window server). Далее я рассмотрю каждый из представленных модулей системы, и расскажу об их основной функциональности.

Наноядро

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

Наноядро является начальным обработчиком всех прерываний. Именно наноядро передает затем большинство прерываний на вариантный уровень (variant layer) для их дальнейшей обработки. Так же наноядро предоставляет простые функции таймера и отсчета времени. Например, при помощи таймера наноядра (NTimer API), можно осуществить запуск функции обратного вызова спустя заданное количество времени. Или при помощи методов NKern::Sleep API отправить исполняемый поток в режим ожидания на заданное количество времени.

Простые объекты синхронизации, о которых я говорил, представлены здесь мьютекском наноядра (NFastMutex), а так же семафором наноядра (NFastSemaphore). Оба эти объекта способны обслужить множество потоков, подключенных к ним.

Так же наноядро поддерживает вызовы отложенных функций (deferred function calls), или DFC. А так же имеющих несколько странное имя, немедленные вызовы отложенных функий (immediate deferred function calls), или IDFC. Если вы хотите больше узнать об этих понятиях, вам следует обратиться к Symbian OS Internals/6. Interrupts and Exceptions.

Важным отличием ядра EKA2 от EKA1 является то, что ни наноядро, ни ядро Symbian OS не ссылаются в своей работе на пользовательскую библиотеку EUSER. Напротив, наноядро использует свою собственную библиотеку утилит, и позволяет пользоваться ей всем остальным модулям ядра, включая и драйверам устройства.

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

Большинство своего времени наноядро работает в преимущественном режиме (preemptible). Наноядро, обрабатывающее прерывания, обычно работает асинхронно, однако в некоторых местах кода мы все же были вынуждены останавливать исполняемые потоки, как например во время смены состояния какого-нибудь из текущих потоков, а так же во время доступа к списку готовых к исполнению потоков. Мы спроектировали эти части кода как можно более краткими и ограниченными во времени, чтобы вся система в реальном времени имела строго детерменистический характер. Критические части наноядра были защищены отсутствием в них кода преимущественного исполнения. Возможно просто из-за того, что эти части были очень маленькими по объему. Чаще всего мы использовали мьютекс, известный как системный блокиратор (system lock) для защиты критичного кода в ядре Symbian OS, а так же в модели памяти (memory model). Однако единственное место, где наноядро использует этот системный блокиратор, находится в защитном механизме адресного пространства планировщика задач во время переключения модели памяти.

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

Ядро Symbian OS

Ядро Symbian OS предоставляет все базовые сервисы, в которых нуждается операционная система. На основе простых потоков и примитивных сервисов наноядра, ядро Symbian OS предоставляет разработчикам более сложные объекты, такие как потоки на стороне пользователей, процессы, объекты и хэндлеры с подсчитанным числом ссылок, динамически загружаемые библиотеки, межпотоковое взаимодействие, и многое другое.

Упомянутые объекты содержат в себе целый ряд других, более сложных объектов для синхронизации: семафоры и мьютексы Symbian OS. Семафоры Symbian OS являются стандартными подсчитывающими семафорами, работающими с несколькими ожидающими потоками в порядке приочередности. Мьютексы Symbian OS являются полностью вкладываемыми, то есть один поток может одновременно удерживать несколько мьютексов, и может открывать и закрывать один и тот же мьютекс несколько раз. Семафоры и мьютексы Symbian OS так же поддерживают наследование приоритетов: поток, удерживающий семафор или мьютекс, наследует наивысший приоритет среди других потоков, ждущих своего времени на том же семафоре или мьютексе.

В отличии от наноядра, ядро Symbian OS умеет выделять и освобождать динамическую память. Ядро имеет свой выделитель памяти - кучу ядра (kernel heap), которая в свою очередь пользуется низкоуровневыми функциями памяти другого модуля, известного под именем "модели памяти" (memory model). Работа Symbian OS совершенно независит от блока управления памятью (MMU), так как всеми деталями, касающихся памяти, заведует отдельный модуль под названием "модель памяти", речь о котором пойдет в последующих главах.

Ядро Symbian OS работает полностью в режиме вытесняющей многозадачности: возникшее прерывание может перепланировать работу ядра в совершенно любом месте, даже во время переключения контекста. В действительности это означает, что ядро Symbian OS не имеет никакого эффекта на время ожидания потоков.

Для защиты наиболее уязвимых частей ядра Symbian OS, используется мьютекс системного блокиратора (system lock mutex), предоставляемый наноядром. Наиболее уязвимыми частями ядра Symbian OS являются:

  1. Состояние объектов типа DThread. Когда Symbian OS взаимодействует с семафорами и мьютексами, они проходят через смену состояний, защищенную системным блокиратором
  2. Состояние большинства синхронизирующих объектов Symbian OS: межпроцессного взаимодействия (IPC) серверов и сессий; семафоров, мьютексов; очередей сообщений, а так же переменных публикации и подписки (Publish & Subscribe)
  3. Массивы хэндлеров, которые доступны для чтения (но не для записи) во время использования системного блокиратора. Все исполнительные функции, использующие хэндлер, удерживают системный блокиратор на время трансляции массива хэндлеров. За более детальной информацией обратитесь к 5-й главе.

Модель памяти

В ядре EKA2 мы ограничиваем наши предположения об архитектуре памяти на специализированной интегральной схеме (ASIC) при помощи одного модуля, называемому "моделью памяти". Модель памяти инкапсулирует все существенные отличия, касающиеся используемого в системе блока управления памятью (MMU), как например виртуальное или физическое индексирование кэша, а так же вообще, наличие в системе блока управления памятью. В ядре EKA1 предположения об устройстве памяти и наличия MMU были разбросаны по всей операционной системе, делая тем самым весьма затруднительной разработку мобильного телефона на интегральной плате без MMU. Подобные разработки стали значительно проще с улучшениями в ядре EKA2, так как модель памяти позволяет вам представить память множеством различных способов, и относительно легко изменить уже выбранную модель памяти.

В данный момент Symbian предоставляет четыре разных модели памяти:

  1. Прямая модель памяти (direct memory model), без использования MMU
  2. Замещающая модель памяти (moving memory model), похожая на модель памяти в EKA1
  3. Многоуровневая модель памяти (multiple memory model), используемая в платах ASIC, снабженных кэшами с физической индексацией, таких как Intel x86, и последних ядрах ARM
  4. Эмуляторная модель памяти (emulator memory model), используемая в эмуляторе Symbian OS под Windows

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

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

Если вы хотите больше узнать о моделе памяти, обратитесь к 7-й главе.

Персональные уровни

Мы спроектировали наноядро таким, чтобы оно имело достаточно функциональностей для запуска сигнального стека GSM. Идея такого решения заключалась в желании предоставить производителям мобильных телефонов возможность запуска сигнального стека GSM и программ управления персональными данными (personal information management, или PIM) на одном-единственном процессоре, экономя таким образом их средства по сравнению с обычными двухпроцессорными решениями.

Большинство производителей мобильных телефонов написали сигнальные стеки GSM для уже существующих операционных систем реального времени, как например Nucleus или µITRON. Созданные сигнальные стеки потребовали значительных денежных вложений и многих часов работы, поэтому для производителей было бы слишком накладным портировать стеки в наноядро (не говоря уже о возможном росте ошибок и дефектов, вызванных такой операцией). Именно поэтому мы и спроектировали наноядро таким образом, чтобы любая третья сторона могла создавать под наноядро персональные уровни.

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

За более детальной информацией о персональных уровнях, и особенностях устройства наноядра, касающихся их, обращайтесь к Symbian OS Internals/17. Real Time.

Расширения ASSP и вариантов

Обычно CPU и большинство электронной периферии мобильных устройств реализуется в виде электронной платы, чаще всего называемой ASSP, или Application-Specific Standard Product (стандартный продукт для конкретного приложения). Для уменьшения стоимости материалов, и цены телефона, становится обычной практикой добавление бóльшего числа компонент на плату ASSP. Такими компонентами могут быть блоки RAM- и флеш-памяти на одном силиконовом чипе, или компоненты, интегрируемые в силиконовую плату, как например DSP (digital signal processor) для обработки аудио и видео; специальные графические процессоры; а так же процессоры, отвечающие за работу с коммуникационными стеками GSM или CDMA.

Любые элементы платы, находящиеся вне ASSP, мы считаем вариантными. Такими компонентами обычно являются чипы флеш- и RAM-памяти, дисплеи, модули для работы с сетью и протоколом Bluetooth. Эти компоненты обычно имеют спциализированные шинные интерфейсы с центральным процессором, а так же специальные соединения с платой, либо коммуникационные линии через такие интерфейсы как USB и серийные UART (universal asynchronous receiver/transmitter, или универсальные асинхронные приемники и передатчики). Платы ASSP так же имеют тенденцию предоставлять конфигурируемые линии GPIO (general purpose I/O, или линии универсального ввода-вывода) для таких специфических функций как поддержка MMC-карточек, и поддержка прерываний от экрана, чувствительного к нажатию.

Таким образом, в Symbian OS расширение ASSP и варианта предоставляет все сервисы, необходимые ядру для работы на разных электронных компонентах и платах, как например поддержку прерываний таймера и компонент часов реального времени. В ядре EKA1 поддержка ASSP была встроена в само ядро, и поэтому отдельный вариационный уровень, описываемый ниже, был просто обязательным. Поэтому ядро EKA1 приходилось излишний раз перекомпилировать при портировании на новую плату ASSP. Поэтому в EKA2 мы полностью отделили поддержку ASSP от самого ядра. В действительности это означает, что при портировании EKA2, вам уже не нужно каждый раз заново компилировать ядро при тех или иных изменениях вашей электронной платы.

Вариант

В EKA2 мы уже не требуем, чтобы вы разделяли програмное обеспечение для ASSP и варианта, как это было в EKA1. Если хотите, вы можете создать одну-единственную DLL для вашего варианта. Тем не менее, если бы вы портировали операционную систему на целый ряд схожих ASIC-плат, то возможно вы решили бы отделить код, общий для семьи ASIC-плат в ASSP-расширении, от кода, пригодного для специализированной ASIC-платы, в виде вариантной DLL. К примеру стоит заметить, что для разработок в компании Symbian, используется плата Intel SA1100 ASSP в двух вариантах: Brutus и Assabet.

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

В Symbian OS вы используете драйверы устройств для контролирования периферии: драйверы являются промежуточным слоем между периферией и операционной системой. Если пожелаете, то драйвер устройства так же может быть логически разделен, как ASSP и вариант, на две части: драйвер логического устройства (logical device driver), или LDD, и, зависящий от реализации, драйвер физический устройства (physical device driver), или PDD.

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

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

Драйверы устройств претерпели значительные изменения от EKA1 к EKA2. За детальными подробностями обратитесь к 12-й главе.

Расширения ядра

Расширениями ядра являются обычные драйверы устройств, которые ядро автоматически подгружает во время своего старта. Поэтому они могут быть представлены как расширения функциональности ядра. Например, аварийный отладчик (crash debugger) является расширением ядра, и по вашему желанию может быть как включен, так и исключен из ROM-образа операционной системы, безо всякой надобности перекомпиляции ядра.

Вариант и ASSP, о которых мы говорили ранее, являются важными расширениями, которые ядро загружает очень рано во время своего запуска. После их подключения ядро продолжает процесс загрузки до тех пор, пока оно не запустит планировщик задач, и не начнет работать в контрольном потоке (supervisor thread), который в свою очередь инициализирует все остальные расширения ядра. Расширения, подгружаемые на этой поздней стадии, не являются критическими для работы самого ядра, а обычно используются для начальной инициализации электронных устройств, и для предоставления устройствам таких перманентных сервисов, как LCD, DMA, I2C, и контроллеров периферийной шины (peripheral bus controllers).

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

EUSER

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

  1. Методы, расширяющие функциональность пользовательской стороны операционной системы, как например большинство методов, касающихся массивов и дескрипторов (дескрипторы - это классы, отвечающие за хранение строк в Symbian OS).
  2. Доступ к функциям ядра, требующих от пользовательского потока привилегий со стороны ядра, как например, проверка времени или локальных установок.
  3. Доступ к функциям ядра, требующих от ядра манипуляций с собственной памятью, как например, создание процесса или загрузка библиотеки.

Каждый поток Symbian OS получает доступ к сервисам ядра через библиотеку EUSER. Пользовательская библиотека EUSER является единственным интерфейсом, который мы почти в том же виде перенесли из EKA1 в EKA2, благодаря чему у разработчики приложений практически не возникает никаких проблем.

Файловый сервер

Файловый сервер является пользовательским сервером, позволяющим пользовательским потокам управлять драйверами, директориями и файлами. За более детальной информацией вас следует обратиться к 9-й главе.

Сервер окон

Сервер окон (window server) является пользовательским сервером, распределяющим информацию о текущем состоянии экрана, нажатиях клавиш и указателя между всеми приложениями Symbian OS. За более детальной информацией вам следует обратиться к 11-й главе.

Уровни програмного обеспечения

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

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

Четыре самых верхних уровня мы называемя уровнем ядра ("the kernel layer"), а два нижних уровня - уровнем периферии ("the peripheral layer"). Два последних уровня формируют ключевой пакет, отвечающий за работу операционной системы на конкретной электронной плате при портировании Symbian OS на новые устройства, а так же заключают в себе код загрузчика, драйверы устройств и расширения ядра.

File:Internals1-2.jpeg

Рис 1.2 Уровни ядра

Независимый уровень (independent layer), составляет примерно 60% исходного кода ядра. Этот уровень предоставляет наноядру и ядру Symbian OS такие ключевые компоненты, как нанопотоки, потоки, процессы, блоки памяти (chunks), клиенты-серверы, и т.д. Перечисленные базовые классы основываются в своей работе на объектах более низкого уровня, работающих уже на конкретном электронном устройстве, на котором и будет работать Symbian OS.

Платформенный уровень (platform layer) имеет отношение к работе с исполняемыми образами (executable images), отвечающими за ту или иную среду, в которой будет работать сама Symbian OS: будь то эмулятор, или электронное устройство. На данном уровне реализуется лишь код модели памяти, имеющей две версии: EPOC - для электронных устройств, и WIN32 - для эмулятора.

Уровень модели (model layer) полностью отвечает за организацию памяти отдельно взятого процесса. Опять же, на данном уровне реализуется лишь код модели памяти. На данном уровне модель памяти имеет четыре разных реализации: замещающую (moving), многоуровневую (multiple), прямую (direct), и эмуляторную (emulator). О деталях реализациях каждой из моделей памяти речь пойдет в 7-й главе.

Процессорный уровень (CPU layer) отвечает за отличия в коде, касающиеся всех процессоров, на которых может работать Symbian OS. Именно к данному уровню относится весь ассемблерный код системы. Наноядро, модель памяти и ядро Symbian OS также хранят свой ассемблерный код на данном уровне. Во время написания этой книги, Symbian OS имела три варианта процессорного уровня: x86 (для портирования на PC-устройства), ARM (мобильные телефоны), и Win32 (для эмулятора).

Процессорный уровень содержит весь код, специфичный как по отношению к конкретному процессору и блоку управления памятью (MMU), так и используемой модели памяти. Процессорный уровень наноядра содержит всю информацию об архитектуре используемого процессора: способы обработки исключений и прерываний; сохранение содержимого определенных регистров при смене контекста, и т.д. Значительный объем процессорного уровня, относящийся к ядру Symbian OS, имеет уровне-независимую функциональность, которая однако была реализована здесь в виде ассемблерного кода по причинам улучшения общей производительности ядра.

Вариантный уровень (variant layer) реализует платформенно-зависимые управляющие функции, используемые наноядром и ядром Symbian OS. Как уже было заявлено ранее, при портировании операционной системы Symbian OS, производитель мобильных телефонов может разделить этот уровень на вариантный и ASSP уровни.

Так же вариантный уровень может реализовывать специальные функции уровня аппаратной абстракции (hardware abstraction layer, или HAL), однако данные функции могут быть в то же самое время реализованы внутри самого ядра или его расширениях.

В 5-й главе будет рассказано о сервисах, которые каждый из уровней предоставляет другим.

Решения, касающиеся дизайна

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

Многопоточное, вытесняющее ядро

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

EKA2 имеет следующие пять потоков:

  1. null-поток (null thread) - загружает центральный процессор и дефрагментирует RAM-память. null-поток так жи известен под именем "холостого потока" (idle thread)
  2. Главный поток (supervisor thread) - очищает память и ресурсы после закончивших работу потоков и процессов, а так же предоставляет функции асинхронного удаления объекта
  3. 0-й DFC-поток (DFC thread 0), или 0-й поток вызовов отложенных функций - отвечает за осуществление вызовов отложенных функций в общедоступных драйверах устройств, таких как коммуникационные устройства, клавиатура и цифровой преобразователь
  4. 1-й DFC-поток (DFC thread 1) - отвечает за работоспособность очереди таймера в наноядре
  5. Поток таймера (timer thread) - отвечает за работу относительного и абсолютного таймеров в Symbian OS (методы After() и At() соответственно)

Более детально о предназначении этих пяти потоков рассказано в Symbian OS Internals/3. Threads, Processes and Libraries.

Мультипоточная природа ядра помогла нам достичь еще одной нашей цели: сделать более легкой жизнь разработчика драйверов. Чаще всего разработчики хотели портировать драйверы устройств из другой операционной системы, однако одно-поточная модель драйвера в EKA1 означала сложности на пути такого портирования. В итоге разработчикам приходилось заново разрабатывать драйвер. В ядре EKA2, драйвера устройств могут воспользоваться 0-м DFC-потоком, или сами запускать потоки, если они того пожелают. Таким образом, драйверы устройств для других операционных систем могут быть намного легче использованы заново при портировании в Symbian OS.

Наноядро

Для наличия отдельного наноядра имелось несколько преимуществ:

  1. Очень краткие и предсказуемые времена ожидания потоков и прерываний. Краткость и предсказуемость времени ожидания возможны благодаря способу работы наноядра, существующему только в нем: ядро выключает либо обработку прерываний, либо перепланировку задач. (В этом способе работы существует несколько исключений, но они здесь не важны.) Остальная львиная доля ядра Symbian OS и модели памяти работают с одновременно включенными обработчиками прерываний и вытесняющей многозадачностью. Так как наноядро работает лишь с небольшим числом примитивных объектов, ему легко определять самый длительный промежуток времени для отключения либо прерываний, либо перепланировки задач
  2. Более простая лучшая эмуляция. Эмулятор Symbian OS, работающий под Windows, имеет гораздо больше кода, общего с реальным электронным устройством. На деле же это означает, что эмуляция будет более точной, чем это было раньше в эмуляторе EKA1
  3. Поддержка однопроцессорных телефонов. Наноядро позволяет вам запускать RTOS и сигнальный стек GSM параллельно с Symbian OS и ее программами, отвечающими за персональные данные пользователя (PIM software). За более детальными разъяснениями обратитесь к главе, касающейся персонального уровня.

Модульность

Повышенная модульность нового ядра намного облегчает портирование операционной системы на новые платы ASSP. Львиная часть процессорно-зависимого кода расположена в наноядре, а отличия в устройстве памяти и блока управления памятью (MMU) заключены в модели памяти.

Модель памяти позволяет вам легко воспользоваться прямой моделью памяти (direct memory model) на ранних стадиях портирования на архитектуру нового процессора, с ее последующей заменой на замещающую (moving) или многоуровневую (multiple) модели памяти, когда ваш код будет больше отлажен. Таким образом вы сможете провести портирование операционной системы меньшими, и более простыми шагами.

Ограничения дизайна

Проектирование ядра EKA2, имеющего производительность реального времени, привело к двум ограничениям:

1. Для гарантирования строго определенного времени ожидания при обработке исключений, мы не могли разрешить неограниченному числу обработчиков прерывания (interrupt service routines, или ISR) быть привязанными к одному и тому же источнику прерываний, как это было возможно в ядре EKA1. Теперь только один обработчик прерываний, или ISR, может быть привязан к источнику прерывания

2. Для гарантирования строго определенного времени переключения контекстов, мы должны были ограничить максимальное число блоков памяти (chunks), доступных из процесса, числом 16. В ядре EKA1 это число могло быть бесконечным. (В Symbian OS блок памяти (chunk) представляет собой объект, являющийся фундаментальным для выделяемой памяти. За более детальной информацией касательно блоков памяти, обратитесь к 7-й главе.)

Важно отметить, что не все сервисы EKA2 строго ограничены по времени. Например, выделение и освобождение памяти потенциально являются неограниченными во времени. Об этом будет более детально рассказано в Symbian OS Internals/17. Real Time.

Эмулятор Symbian OS

Решения, стоящие за дизайном

Эмулятор используется для двух главных целей: разработка программ под Symbian OS, и демонстрация этих программ.

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

  1. Эмулятор должен поддерживать разработку и отладку кода при помощи стандартных инструментов эмулирующей платформы
  2. Эмулятор должен производить эмуляцию как можно более точно по сравнению с работой Symbian OS на настоящем устройстве

Два этих требования на самом деле противоречат друг другу, так как первое требует использования возможностей эмулирующей платформы (до сего момента, этой платформой всегда была Windows), которых на самом деле нет в реальной Symbian OS, как например:

  1. Отладка на уровне кода требует, чтобы объектный код сохранялся в стандартных исполняемых файлах Windows, которые затем можно будет передать отладчику Windows через стандартный загрузчик
  2. Отладка многопоточных программ требует, чтобы отладчик Windows мог понимать используемые нами потоки. В действительности это означало, что мы должны были реализовывать эмулируемые потоки как потоки операционной системы Windows.

В конце-концов, мы решили создать эмулятор EKA2 как часть ядра EKA2, а не как эмуляцию API ядра Symbian OS силами Win32 API. Поэтому мы использовали Windows как можно меньше для того, чтобы бóльшая часть кода Symbian OS (а потому, и поведение кода), были одинаковыми как на эмуляторе, так и в настоящих мобильных телефонах.

Если вы посмотрите на рис. 1.3, и сравните код, работающий на настоящем устройстве с кодом, работающим на эмуляторе Win32, то обнаружите массу общего. Обе системы содержат одну и ту же основную часть ядра: как от ядра Symbian OS, так и от наноядра. На низких, архитектурно-зависимых уровнях наноядра, мы сэмулировали поддержку центрального процессора Win32, вместо уже имеющихся там процессоров ARM и х86. Поэтому в действительности оказывается, что эмулятор - всего лишь код, портированный на новый процессор, и поэтому процессы и планировка задач эмулятора практически идентична тем, что имеются в настоящих устройствах.

File:Internals1-3.jpeg

Рис. 1.3 Повторное использование кода эмулятора

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

Comments

Sign in to comment…