Общее описание структуры системы

Архитектура ОС Windows (в данном разделе она излагается, следуя главным образом [3] и [6]), претерпела ряд изменений в процессе эволюции. Первые версии системы имели микроядерный дизайн, основанный на микроядре Mach, которое было разработано в университете Карнеги-Меллона. Архитектура более поздних версий системы микроядерной уже не является.

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

Высокая модульность и гибкость первых версий Windows NT позволила успешно перенести систему на такие отличные от Intel платформы, как Alpha (корпорация DEC), Power PC (IBM) и MIPS (Silicon Graphic). Более поздние версии ограничиваются поддержкой архитектуры Intel x86.

Упрощенная схема архитектуры, ориентированная на выполнение Win32-приложений, показана на рис. 1.4.

Общее описание структуры системы - student2.ru

Рис. 1.4. Упрощенная архитектурная схема ОС Windows

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

Задача уровня абстрагирования от оборудования (hardware abstraction layer, HAL) - скрыть аппаратные различия аппаратных архитектур для потенциального переноса системы с одной платформы на другую. HAL предоставляет выше лежащим уровням аппаратные устройства в абстрактном виде, свободном от индивидуальных особенностей. Это позволяет изолировать ядро, драйверы и исполнительную систему ОС Windows от специфики оборудования (например, от различий между материнскими платами).

Ядром обычно называют все компоненты ОС, работающие в привилегированном режиме работы процессора или в режиме ядра. Корпорация Microsoft называет ядром (kernel) компонент, находящийся в невыгружаемой памяти и содержащий низкоуровневые функции операционной системы, такие, как диспетчеризация прерываний и исключений, планирование потоков и др. Оно также предоставляет набор процедур и базовых объектов, применяемых компонентами высших уровней.

Ядро и HAL являются аппаратно-зависимыми и написаны на языках Си и ассемблера. Верхние уровни написаны на языке Си и являются машинно-независимыми.

Исполнительная система (executive) обеспечивает управление памятью, процессами и потоками, защиту, ввод-вывод и взаимодействие между процессами. Драйверы устройств содержат аппаратно-зависимый код и обеспечивают трансляцию пользовательских вызовов в запросы, специфичные для конкретных устройств. Подсистема поддержки окон и графики реализует функции графического пользовательского интерфейса (GUI), более известные как Win-32-функции модулей USER и GDI

В пространстве пользователя работают разнообразные сервисы (аналоги демонов в Unix), управляемые диспетчером сервисов и решающие системные задачи. Некоторые системные процессы (например, обработка входа в систему) диспетчером сервисов не управляются и называются фиксированными процессами поддержки системы. Пользовательские приложения (user applications) бывают пяти типов: Win32, Windows 3.1, MS-DOS, POSIX и OS/2 1.2. Среду для выполнения пользовательских процессов предоставляют три подсистемы окружения: Win32, POSIX и OS/2. Таким образом, пользовательские приложения не могут вызывать системные вызовы ОС Windows напрямую, а вынуждены обращаться к DLL подсистем (краткое определение dll имеется в приложении).

Основные компоненты ОС Windows реализованы в следующих системных файлах, находящихся в каталоге system32:

· ntoskrnl.exe - исполнительная система и ядро;

· ntdll.dll - внутренние функции поддержки и интерфейсы диспетчера системных сервисов с функциями исполнительной системы;

· hal.dll - уровень абстрагирования от оборудования;

· win32k.sys - часть подсистемы Win32, работающая в режиме ядра;

· kernel32.dll, advapi32.dll, user32.dll, gdi32.dll - основные dll подсистемы Win32.

Подсистема Win32

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

Win32 API (Application Programming Interface) - основной интерфейс программирования в семействе операционных систем Microsoft Windows. Функции Win32 API , например, CreateProcess или CreateFile, - документированные, вызываемые подпрограммы, реализуемые Win32 подсистемой.

В состав Win32 подсистемы (см. рис. 1.4) входят: cерверный процесс подсистемы окружения csrss.exe, драйвер режима ядра Win32k.sys, dll - модули подсистем (kernel32.dll, advapi32.dll, user32.dll и gdi32.dll), экспортирующие Win32-функции и драйверы графических устройств. В процессе эволюции структура подсистемы претерпела изменения. Например, функции окон и рисования с целью повышения производительности были перенесены из серверного процесса, работающего в режиме пользователя, в драйвер режима ядра Win32k.sys. Однако это и подобные изменения никак не отразились на работоспособности приложений, поскольку существующие вызовы Win32 API не изменяются с новыми выпусками системы Windows, хотя их состав постоянно пополняется.

Приложение, ориентированное на использование Win32 API, может работать практически на всех версиях Windows, несмотря на то, что сами системные вызовы в различных системах различны (см. рис. 1.5). Таким путем корпорация Microsoft обеспечивает преемственность своих операционных систем.

Общее описание структуры системы - student2.ru

Рис. 1.5. Поддержка единого программного интерфейса для различных версий Windows

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

Общее описание структуры системы - student2.ru


Рис. 1.6. Различные маршруты выполнения вызовов Win32 API.

При вызове приложением одной из Win32-функций dll-подсистем может возникнуть одна из трех ситуаций (см. рис. 1.6).

· Функция полностью выполняется внутри данной dll (шаг 1).

· Для выполнения функции привлекается сервер csrss, для чего ему посылается сообщение (шаг 2a, за которым обычно следуют шаги 2b и 2c).

· Данный вызов транслируется в системный сервис (системный вызов), который обычно обрабатывается в модуле ntdll.dll (шаги 3a и 3b). Например, Win32-функция ReadFile выполняется с помощью недокументированного сервиса NtReadFile.

Некоторые функции (например, CreateProcess ) требуют выполнения обоих последних пунктов.

В первых версиях ОС Windows практически все вызовы Win32 API выполнялись, следуя маршруту 2 (2a, 2b, 2c). После того, как существенная часть кода системы для увеличения производительности была перенесена в ядро (начиная с Windows NT 4.0), вызовы Win32 API, как правило, идут напрямую по 3-му (3a, 3b) пути, минуя подсистему окружения Win32. В настоящее время лишь небольшое число вызовов выполняется по длинному 2-му маршруту.

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

Заключение

В настоящей лекции изложена краткая история создания ОС Windows и ее миграция от микроядерной архитектуры в сторону монолитного дизайна. Описаны возможности и основные структурные компоненты системы. Рассмотрена подсистема Win32, которая объединяет ряд модулей режима ядра и режима пользователя и является базой для разработки приложений.

Приложение. Некоторые понятия и термины

DLL (динамически подключаемая библиотека)

Набор вызываемых подпрограмм, включенных в один двоичный файл, который приложения, использующие эти подпрограммы, могут динамически загружать в процессе своего выполнения. В качестве примера можно привести модули Msvcrt.dll (библиотека исполняющей Си подсистемы) и Kernel32.dll (одна из библиотек подсистемы Win32). DLL активно используются компонентами и приложениями ОС Windows пользовательского режима. Преимущество DLL перед статическими библиотеками состоит в том, что приложения могут разделять DLL-модули, при этом ОС Windows гарантирует, что в памяти будет находиться лишь по одному экземпляру используемых DLL.

Процессы и потоки

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

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

Более подробно процессы и потоки описаны в части II.

Компилятор Visual C++ и среда программирования для Windows

Компилятор Windows Visual C++ удобно объединять со справочной системой MSDN Library, которая при этом вызывается через пункт меню "Справка" ("Help") в интегрированной среде Microsoft Visual C++, а также может использоваться автономно. Запуск установленной графической оболочки Microsoft Visual C++ осуществляется стандартными средствами системы.

Прежде, чем начинать работать с Windows Visual C++ рекомендуется сформировать на рабочем столе иконку запуска компилятора. Для этого зайдите в меню <все программы>, найдите там пункт <Microsoft Visual > и создайте копию иконки <Microsoft Visual С++> , затем перенесите ее на рабочий стол.

Чтобы из текста программы на языке высокого уровня (файл с расширением "c" или "cpp") получить исполняемую программу в машинных кодах (файл с расширением "exe"), необходимо запустить графическую оболочку Microsoft Visual Studio C++ создать рабочий проект, который представляет собой совокупность служебных файлов, необходимых для дальнейшей работы.

Программные примеры, иллюстрирующие данный курс, представляют собой Windows-приложения с текстовым интерфейсом (консольные). Разработка приложений с дружественным графическим интерфейсом сама по себе достаточно сложна и должна изучаться в рамках специальных учебных курсов. Поэтому, формируя проект, далее в графической оболочке Visual Studio в диалоговом окне "New project" нужно выбрать Win32 Console Application в качестве типа приложения, а также дать проекту имя, указать каталог расположения файлов проекта и нажать кнопку "OK".

Имена файлам будем давать по номеру практической работы prN_Фамилия где N-номер практической работы, Фамилия-фамилия студента. Каталог используем по умолчанию.

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

Откомпилировать программу можно нажатием клавиши F7

Запустить программу на отладку можно клавишами Ctrl+F5

Прогон программы "Hello, world"

В качестве самостоятельного упражнения рекомендуется реализовать простейшую программу в интегрированной среде компилятора Visual C++, например, хрестоматийную программу "Hello, world", и ознакомиться со средствами разработки, отладки и контекстной помощи.

Наши рекомендации