Лекції "Системне програмування"

1. Лекція 1 Створення ОС Windows. Структура ОС Windows

Створення ОС Windows. Структура ОС Windows

Операційна система є базовою системною програмою. Зазвичай апаратно-програмне забезпечення типової обчислювальної системи представляють у вигляді набору шарів (Мал. 1.1.), при цьому операційній системі відповідає шар між обладнанням комп'ютера і іншим програмним забезпеченням. Таке розташування дозволяє ОС забезпечувати можливість раціонального використання устаткування комп'ютера зручним для користувача чином шляхом створення середовища для функціонування і розробки прикладних програм.

Мал. 1.1. Шари програмного забезпечення комп'ютерної системи

Дружній інтерфейс між користувачем і комп'ютером досягається за рахунок абстрагування, яке є важливим методом спрощення і дозволяє сконцентруватися на взаємодії високорівневих компонентів системи, ігноруючи деталі їх реалізації. У цьому сенсі про ОС кажуть, що операційна система є абстрактною або віртуальною машиною, з якої мати справу набагато зручніше, ніж з низькорівневими елементами комп'ютера

Альтернативний погляд на ОС дає уявлення про ОС як про менеджера ресурсів, який здійснює впорядкований і контрольований розподіл процесорів, пам'яті та інших ресурсів між різними програмами.

Коротка історія створення ОС Windows

Перша версія ряду операційних систем - ОС Windows NT з'явилася в 1993 р Короткий історичний екскурс дозволяє пояснити ряд її особливостей і відмінностей.

Найбільш важливі моменти еволюції операційних систем

Вважається, що операційні системи придбали сучасний вигляд в період розвитку третього покоління обчислювальних машин, тобто з середини 60-х до 1980 року. В цей час істотне підвищення ефективності використання процесора було досягнуто за рахунок реалізації багатозадачності, в тому числі витісняючої (preemptive) багатозадачності. Для підтримки псевдопаралельної роботи декількох програм і асинхронного режиму роботи зовнішніх пристроїв в складі обчислювальних систем були реалізовані наступні програмно-апаратні нововведення і підсистеми:

  • Впровадження захисних механізмів. Захист пам'яті дозволяє ізолювати конкуруючі призначені для користувача програми один від одного, а поява привілейованих і непривілейованих команд - проконтролювати доступ до розподілу ресурсів.
  • Реалізація переривань, оповіщають ОС про що відбулися асинхронних події, наприклад, про завершення операції введення-виведення.
  • Підтримка сукупності системних викликів для організації інтерфейсу між прикладною програмою і ОС.
  • Реалізація дисципліни планування для організації черги з програм в пам'яті і виділення процесора одній з програм.
  • Забезпечення можливості збереження з подальшим відновленням вмісту регістрів і структур даних, необхідних для виконання програми, при перемиканні процесора з однієї програми на іншу.
  • Реалізація стратегії управління пам'яттю - щоб упорядкувати процеси розміщення, заміщення і вибірки інформації з пам'яті.
  • • Організація зберігання інформації на зовнішніх носіях у вигляді файлів і забезпечення доступу до конкретного файлу тільки окремим категоріям користувачів.
  • • Забезпечення програм засобами комунікації та синхронізації.

Архітектурні особливості операційних систем.

В даний час переважна більшість операційних систем має так званий монолітний дизайн.

В цьому випадку компоненти операційної системи є не самостійними модулями, а складовими частинами однієї великої програми. Монолітне ядро являє собою набір процедур, кожна з яких може викликати кожну. Всі процедури працюють в привілейованому режимі.

Таким чином, монолітне ядро - це така схема операційної системи, при якій всі її компоненти є складовими частинами однієї програми, використовують загальні структури даних і взаємодіють один з одним шляхом безпосереднього виклику процедур.

 

Сучасна тенденція в розробці операційних систем полягає в перенесенні значної частини системного коду на рівень користувача і одночасної мінімізації ядра. Йдеться про підхід до побудови ядра, яку називають мікроядерною архітектурою (microkernel architecture) операційної системи, коли більшість її складових є самостійними програмами. У цьому випадку взаємодія між ними забезпечує спеціальний модуль ядра, званий мікроядром. Мікроядро працює в привілейованому режимі і забезпечує взаємодію між програмами, планування використання процесора, первинну обробку переривань, операції введення-виведення і базове управління пам'яттю. Інші компоненти взаємодіють шляхом обміну повідомленнями в рамках архітектури клієнт-сервер 

Створення ОС Windows

Операційні системи корпорації Microsoft можна умовно розділити на три групи:

• MS-DOS і MS-DOS + Windows 3.1,

• так звані споживчі (consumer) версії Windows (Windows 95/98 / Me)

• і лінія ОС, які ведуть свій початок від Windows NT (Windows NT / 2000 / XP / Vista/...).

Однозадачна 16-розрядна ОС MS-DOS була випущена на початку 80-х років і потім широко застосовувалася на комп'ютерах з процесором x86. Спочатку MS-DOS була досить примітивна (деградація ОС), її оболонка займалася, головним чином, обробкою командного рядка, але в наступні версії було внесено багато покращень, запозичених, головним чином, з ОС Unix.

Потім під впливом успіхів дружнього графічного інтерфейсу корпорації Apple для комп'ютерів Macintosh була розроблена система Windows. Особливо широкого поширення набули версії Windows 3.0, 3.1 і 3.11.

Спочатку це була не самостійна ОС, а скоріше багатозадачна (з витісняючою багатозадачностюі) графічна оболонка MS-DOS, яка контролювала комп'ютер і файлову систему.

У 1995 р була випущена 32-розрядна ОС Windows 95, де була реалізована витісняюча багатозадачність. ОС Windows95 включала великий обсяг 16-розрядного коду, головним чином для забезпечення наступності з додатками MS-DOS. 16-розрядний код був присутній і в наступних версіях цієї серії Windows 98 і Windows Me. Іншою проблемою даної версії Windows, багато в чому обумовленої тією ж причиною, була нереентерабельність значної частини коду ядра. Так, якщо один з потоків був зайнятий модифікацією даних в ядрі, інший потік, щоб не отримати ці дані в суперечливому стані, змушений був чекати, тобто не міг скористатися системними сервісами. Це, найчастіше, зводило нанівець переваги багатозадачності.

ОС Windows NT (New Technology) - нова 32-розрядна ОС, сумісна з попередніми версіями Windows по інтерфейсу. Помітна спадкоємність в системі управління великим адресним простором і саморозміщувані безліччю процесу, в системі пріоритетів звичайних процесів і процесів реального часу, в засобах синхронізації і т.д. Разом з тим Windows NT - це абсолютно новий амбітний проект розробки системи з урахуванням новітніх досягнень в галузі архітектури мікроядра. Перша версія, названа Windows NT 3.1 для відповідності популярної Windows 3.1, була випущена в 1993р Комерційного успіху добилася версія Windows NT 4.0, яка мала графічний інтерфейс Windows 95. На початку 1999р була випущена Windows NT 5.0, перейменована в Windows 2000. Наступна версія цієї ОС даної серії - Windows XP з'явилася в 2001 році, а Windows Server 2003 - в 2003р, далі випущена Windows Vista, раніше відома під кодовим ім'ям Longhorn, - нова версія Windows, яка продовжує лінійку Windows NT.

Можливості системи

Перед розробниками системи було поставлено завдання створити операційну систему персонального комп'ютера, призначену для вирішення серйозних завдань, а також для домашнього використання. Перелік можливостей системи досить широкий, ось лише деякі з них. Операційна система Windows:

  • є істинно 32(64)-розрядною, підтримує багатозадачність;
  • працює на різних апаратних архітектурах і має здатність до порівняно легкого переносу на нові апаратні архітектури;
  • підтримує роботу з віртуальною пам'яттю;
  • є повністю реєнтерабельною;
  • добре масштабується в системах із симетричною мультипроцесорної обробкою;
  • є розподіленої обчислювальної платформою, здатною виступати в ролі як клієнта мережі, так і сервера;
  • захищена як від внутрішніх збоїв, так і від зовнішніх деструктивних дій. У додатків немає можливості порушити роботу операційної системи або інших додатків;
  • сумісна, тобто, її призначений для користувача інтерфейс і API сумісні з попередніми версіями Windows і MS-DOS. Вона також вміє взаємодіяти з іншими системами на кшталт UNIX, OS/2 і NetWare;
  • має високу продуктивність незалежно від апаратної платформи;
  • підтримує багатопоточність і об'єктну модель.

Структура ОС Windows

Загальний опис структури

Архітектура ОС, зазнала ряд змін в процесі еволюції. Перші версії системи мали мікроядерний дизайн, заснований на мікроядрі Mach, яке було розроблено в університеті Карнегі-Меллона. Архітектура пізніших версій системи мікроядерною вже не є.

Причина полягає в поступовому подоланні основного недоліку мікроядерних архітектур - додаткових накладних витрат, пов'язаних з передачею повідомлень. На думку фахівців Microsoft, чисто мікроядерний дизайн комерційно невигідний, оскільки неефективний. Тому великий обсяг системного коду, в першу чергу управління системними викликами і екранна графіка, був переміщений з адресного простору користувача в простір ядра і працює в привілейованому режимі. В результаті в ядрі ОС Windows переплетені елементи мікроядерної архітектури та елементи монолітного ядра (комбінована система).

Сьогодні микроядро ОС Windows занадто велике (більше 1 Мб), щоб носити приставку "мікро". Основні компоненти ядра Windows NT розташовуються в пам'яті що витісняється і взаємодіють один з одним шляхом передачі повідомлень, як і належить в мікроядерним операційним системам. У той же час всі компоненти ядра працюють в одному адресному просторі і активно використовують загальні структури даних, що властиво операційним системам з монолітним ядром.

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

ОС 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.

 Середовище для виконання призначених для користувача процесів надають три підсистеми оточення: Win32, POSIX і OS/2. Таким чином, призначені для користувача програми не можуть викликати системні виклики ОС Windows безпосередньо, а змушені звертатися до DLL.

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

  • ntoskrnl.exe - виконавча система і ядро;
  • ntdll.dll - внутрішні функції підтримки і інтерфейси диспетчера системних сервісів з функціями виконавчої системи;
  • hal.dll - рівень абстрагування від устаткування;
  • win32k.sys - частина підсистеми Win32, що працює в режимі ядра;
  • kernel32.dll, advapi32.dll, user32.dll, gdi32.dll - основні dll підсистеми 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, незважаючи на те, що самі системні виклики в різних системах різні . Таким шляхом корпорація Microsoft забезпечує спадкоємність своїх операційних систем.

 

 

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

 

При виклику додатком однієї з Win32-функцій dll-підсистем може виникнути одна з трьох ситуацій .

  • Функція повністю виконується всередині даної 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 становить кілька десятків тисяч.

Перелік функцій, що експортуються кожною конкретною dll, можна подивитися за допомогою утиліти depends, що входить в пакет Platform SDK. Так, на мал. 1.7 наведена інформація про структуру бібліотеки kernel32.dll ОС Windows XP, що експортує 949 функцій.

Мал. 1.7. Вікно утиліти depends.exe

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

Під процесом розуміється контейнер ресурсів, використовуваних потоками.

Процес включає:

  •  закритий адресний простір, в якому розташовуються: код, дані та стеки потоків;
  • список відкритих описувачів (handles) ресурсів;
  • контекст захисту;
  • ідентифікатор процесу.

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