Добавил:
twitch.tv Заведующий методическим кабинетом, преподаватель на кафедре компьютерного спорта и прикладных компьютерных технологий. Образование - Магистр Спорта. Суета... Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
9
Добавлен:
29.04.2022
Размер:
5.97 Mб
Скачать
  • Сегментно - сторінкова схема організації віртуальної пам’яті..

    Метою організації сегментно – сторінкового механізму організації віртуальної пам’яті є уникнення недоліків сторінкового способу за рахунок збільшення накладних витрат на реалізацію сегментно – сторінкового способу.

    Так само як і у випадку з сегментами вся програма розділяється на логічно завершені частини сегментів і віртуальна адреса містить вказівник на номер відповідного сегменту. Інша складова віртуальної адреси складається з двох частин: віртуальної сторінки та індексу.

    Рис. 6.3. Сегментно - сторінкова схема організації віртуальної пам’яті.

    РТС – регістр таблиці сегментів;

    S – сегмент;

    Р – сторінка;

    І – індекс;

    ТС – таблиця сторінок.

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

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

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

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

    Однак, недоліком є значні обчислювальні затрати на її організацію. Тому така схема, як правило використовується в дуже дорогих і потужних обчислювальних системах, наприклад в паралельних комп’ютерах. Такий механізм закладений і в процесорах Intel 80x86, але через високу складність організації такої системи він практично не використовується в сучасних ОС.

    Тема 7. Архітектурні особливості мікропроцесорів Intel 80x86.

    1. Реальний і захищений режими роботи процесора.

    2. Нові системні регістри мікропроцесорів і80x86.

    3. Підтримка сегментного способу організації віртуальної пам'яті.

    4. Підтримка сторінкового способу організації віртуальної пам'яті.

    5. Режим віртуальних машин для виконання додатків реального режиму.

    6. Захист адресного простору задач.

    7. Механізм шлюзів для передачі керування на сегменти коду з іншими рівнями привілеїв.

    1. Реальний і захищений режими роботи процесора.

    Широко відомо, що першим мікропроцесором, на базі якого була створена IBM РС, був Intel 8088. Цей мікропроцесор відрізнявся від першого 16-розрядного мікропроцесора фірми Intel — 8086 — насамперед тим, що в нього була 8-бітова шина даних, а не 16-бітова (як у 8086). Обидва ці мікропроцесори призначалися для створення обчислювальних пристроїв, які б працювали в однозадачному режимі, тобто спеціальних апаратних засобів для підтримки надійних і ефективних мультипрограмних ОС у них не було. Однак на той час, коли розробники усвідомили необхідність включення в мікропроцесор спеціальної апаратної підтримки для мультипрограмних обчислень, вже було створено дуже багато програмних продуктів. Тому для сумісності з першими комп'ютерами в наступних версіях мікропроцесорів була реалізована можливість використовувати їх у двох режимах — реальному (real mode — так назвали режим роботи перших 16-бітових мікропроцесорів) і захищеному (protect mode – означає, що рівнобіжні обчислення можуть бути захищені апаратно-програмними механізмами).

    Докладно розглядати архітектуру перших 16-бітових мікропроцесорів i8086/i8088 ми не будемо, оскільки цей матеріал повинен вивчатися в попередніх дисциплінах навчального плану. Однак нагадаємо, що в цих мікропроцесорах (а виходить, і в інших мікропроцесорах сімейства і80х86 при їх роботі у реальному режимі) звертання до пам'яті з можливим адресним простором у 1 Мбайт здійснюється за допомогою механізму сегментної адресації (мал. 3.1). Цей механізм був використаний для збільшення кількості розрядів, що беруть участь у вказівці адреси комірки пам'яті, з якою у даний момент здійснюється робота, з 16 до 20 і тим самим збільшення обсягу пам'яті.

    Конкретизуємо задачу й обмежимося розглядом визначення адреси команди. Для адресації операндів використовується аналогічний механізм, тільки беруть участь у цьому випадку інші сегментні регістри. Нагадаємо, що для визначення фізичної адреси команди вміст сегментного регістра СS (code segment) перемножується на 16 за рахунок додавання зправа (до молодших бітів) чотирьох нулів, після чого до отриманого значення додається вміст покажчика команд (регістр ІР, instruction pointer). Виходить двадцатибітівое значення, що і дозволяє вказати будь-який байт із 220. Насправді, оскільки відбувається саме додавання і кожен з доданків може мати значення в інтервалі від нуля до 216-1 = 65535 – 64К, ми можемо вказати адресу початку сегмента, рівний FFFFFFFF00Н, і до нього додати зсув FFFFFFFFН. У цьому випадку ми одержимо переповнення розрядної сітки, але для сучасних 32-бітових процесорів (і для вже забутого i80286) мається можливість вказати перші 64Кбайт вище першого мегабайта.

    Мал. 3.1 Схема визначення фізичної адреси для процесора 8086.

    У захищеному режимі роботи визначення фізичної адреси здійснюється зовсім інакше. Насамперед використовується сегментний механізм для організації віртуальної пам'яті. При цьому адреси задаються 32-бітовими значеннями. Крім цього, можлива сторінкова трансляція адрес, також з 32-бітовими значеннями. Нарешті, при роботі в захищеному режимі, що за замовчуванням припускає 32-бітовий код, можливе виконання подвійних програм, створених для роботи мікропроцесора в 16-бітовому режимі. Для цього введений режим віртуальної 16-бітової машини і 20-бітові адреси реального режиму транслюються за допомогою сторінкового механізму в 32-бітові значення захищеного режиму. Нарешті, є ще один режим — 16-бітовий захищений, що дозволяє 32-бітовим мікропроцесорам виконувати захищений 16-бітовий код, що був характерний для мікропроцесора 80286. Правда, слід зазначити, що цей останній режим практично не використовується, оскільки програм, створених для нього, не так вже і багато.

    Для вивчення цих можливостей розглянемо спочатку нові архітектурні можливості мікропроцесорів i80х86.

    2. Нові системні регістри мікропроцесорів і80x86.

    Основні регістри мікропроцесора і80x86, знання яких необхідно для розуміння захищеного режиму роботи, приведені на мал. 3.2. Варто звернути увагу на наступне:

    • покажчик команди ЕIP — 32 бітовий регістр, молодших 16 розрядів цього регістра є регістр IP;

    • регістр флагів EFLAGS — 32 біта, молодших 16 розрядів представляють регістр FLAGS;

    • регістри загального призначення ЕАХ, ЕВХ, ЕСХ, EDX, а також ESP, EBP, ESI, EDI — 32-бітові, однак їх молодші 16 розрядів являють собою відомі регістри АХ, ВХ, СХ, DX, SP, BP, SI, DI;

    • сегментні регістри CS, SS, DS, ES, FS, GS — 16-бітові. При кожному з регістрів CS, SS, DS, ES, FS, GS зображені пунктиром сховані від програмістів (недоступні нікому, крім власне мікропроцесора) 64-бітові регістри, у які завантажуються дескриптори відповідних сегментів;

    • регістр-покажчик на локальну таблицю сегментів поточної задачі- - LDTR (16 бітів). При цьому регістрі також є «тіньовий» (схований від програміста) 64-бітовий регістр, у який мікропроцесор заносить дескриптор, що вказує на таблицю дескрипторів сегментів задачі, що описують її локальний віртуальний адресний простір;

    • регістр-покажчик задачі TR (task register, 16 бітів). Указує на дескриптор у глобальній таблиці дескрипторів, що дозволяє одержати доступ до дескриптора задачі TSS2 — інформаційній структурі, що підтримує мікропроцесор для керування задачами;

    • регістр CDTR1 (48 бітів) глобальної таблиці GDT, що містить як дескриптори загальних сегментів, так і спеціальні системні дескриптори. Зокрема, у GDTR знаходяться дескриптори, з допомогу яких можна одержати доступ до сегментів TSS;

    • регістр IDTR (48 бітів) таблиці дескрипторів переривань. Містить інформацію, необхідну для доступу до ”таблиці переривань” IDT;

    • керуючі регістри CR0 - CR3 (32-бітові) і деякі інші регістри.

    Мал. 7.2 Основні системні регістри мікропроцесорів і80x86.

    Керуючий регістр CR0 містить цілий ряд флагівв, що визначають режими роботи мікропроцесора. Самий молодший біт (РЕ, protect enable) цього регістра визначає режим роботи процесора. При РЕ=0 процесор функціонує в реальному режимі роботи, а при одиничному значенні мікропроцесор переключається в захищений режим. Самий старший біт регістра CR0 (біт PG, paging) визначає, включений (PG=1) чи немає (PG=0) режим сторінкового перетворення адрес.

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

    3. Підтримка сегментного способу організації віртуальної пам'яті.

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

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

    • щоб існував загальний (розподілений) адресний простір.

    Тому в мікропроцесорах і80x86 реалізований сегментний спосіб організації розподілу пам'яті. Крім цього, в цих мікропроцесорах може бути задіяна і сторінкова трансляція. Оскільки для кожного сегмента потрібний дескриптор, пристрій керування пам'яттю підтримує відповідну інформаційну структуру. Формат дескриптора сегмента приведений на мал. 3.3. Поля дескриптора (базова адреса, поле межі) розміщені в дескрипторі не безупинно, а в розбивку, по-перше, через те, що розробники постаралися мінімізувати кількість перехресних з'єднань в напівпровідниковій структурі мікропроцесора, а по-друге – унаслідок необхідності забезпечити повну сумісність мікропроцесорів (попередній мікропроцесор і80286 працював з 16-бітовим кодом і теж підтримував сегментний механізм реалізації віртуальної пам'яті). Необхідно помітити, що формат дескриптора сегмента, зображений на мал. 3.3, справедливий тільки для випадку перебування відповідного сегмента в оперативній пам'яті. Якщо ж біт присутності в полі прав доступу рівний нулю(сегмент відсутній в памяті), то всі біти за виключенням поля прав доступу, вважаються невизначеними і можуть використовуватися системними програмістами (для вказівки адреси сегмента в зовнішній пам'яті) довільним чином.

    Мал. 7.3 Дескриптор сегменту.

    Локальний адресний простір задачі визначається через таблицю LDT (local descriptor table). У кожної задачі може бути свій локальний адресний простір. Загальний чи глобальний адресний простір визначається через таблицю GDT (global descriptor table). Само собою, що роботу з цими таблицями (їхнє заповнення і наступну модифікацію) повинна здійснювати операційна система. Доступ до таблиць LDT і GDT з боку прикладних задач повинен бути неможливий.

    При переключенні мікропроцесора в захищений режим він починає зовсім іншим чином, ніж у реальному режимі, обчислювати фізичні адреси команд і операндів. Насамперед, вміст сегментних регістрів інтерпретується інакше: вважається, що там міститься не адреса початку сегмента, а номер відповідного сегмента. Для того щоб підкреслити цей факт, сегментні регістри CS, SS, DS, ES, FS, GS у такому випадку навіть називаються інакше — селекторами сегментів. При цьому кожен селекторний регістр розбивається на наступні три поля (мал. 3.4):

    • поле індексу (index) — старші 13 бітів (3-15). Визначає власне номер сегмента (його індекс у відповідній таблиці дескрипторів);

    • поле індикатора таблиці сегментів (table index, TI) — біт з номером 2. Визначає частину віртуального адресного простору (загальне чи приналежне тільки даній задачі). Якщо TI=1, то Index вказує на елемент у глобальній таблиці дескрипторів GDT, тобто йде звертання до загальної пам'яті. Якщо TI=1, то йде звертання до локальної області пам'яті поточної задачі; цей простір описується локальною таблицею дескрипторів LDT;

    • поле рівня привілеїв – біти 0 і 1. Вказує запитуваний рівень привілеїв (RPL, requested privilege level).

    Операційна система в процесі свого запуску ініціалізує багато регістрів і, насамперед, GDTR. Цей регістр містить початковий адрес глобальної таблиці дескрипторів (GDT) і її розмір. Як ми вже знаємо, у GDT знаходяться дескриптори глобальних сегментів і системні дескриптори.

    Мал. 7.4. Селектор сегменту.

    Для маніпулювання задачами ОС має інформаційну структуру, що ми уже визначили як дескриптор задачі. Мікропроцесор підтримує роботу з найбільш важливою частиною дескриптора задачі, що найменше залежить від операційної системи. Ця інваріантна частина дескриптора, з яким і працює мікропроцесор, названа сегментом стану задачі (task state segment, TSS). Перелік полів TSS зображений на мал. 3.5. Видно, що в основному цей сегмент містить контекст задачі. Процесор одержує доступ до цієї структури за допомогою регістра задачі (task register, TR).

    Регістр TR містить індекс (селектор) елемента в GDT. Цей елемент являє собою дескриптор сегмента TSS. Дескриптор заноситься в тіньову частину регістра (див. мал. 3.2). До розгляду TSS ми ще повернемося, а зараз помітимо, що в одному з полів TSS міститься покажчик (селектор) на локальну таблицю дескрипторів даної задачі. При переході процесора з однієї задачі на іншу вміст поля LDTR заноситься мікропроцесором в однойменний регістр. Ініціалізувати регістр TR можна і явно.

    Отже, регістр LDTR містить селектор, що вказує на один з дескрипторів глобальної таблиці GDT. Цей дескриптор заноситься мікропроцесором у тіньову частину регістра LDTR і описує таблицю LDT для поточної задачі. Тепер, коли в нас визначені як глобальна, так і локальна таблиця дескрипторів, можна розглянути процес визначення лінійної адреси. Для прикладу розглянемо процес одержання адреси команди. Адреси операндів визначаються за аналогією, але задіяні будуть інші регістри.

    Мікропроцесор аналізує біт TI селектора коду й у залежності від його значення, витягає з таблиці GDT чи LDT дескриптор сегмента коду з номером (індексом), що рівний полю index (біти 3-15 селектора, див. мал. З.4). Цей дескриптор заноситься в тіньову (сховану) частину регістра CS. Далі мікропроцесор порівнює значення регістра EIP (extended instruction pointer — покажчик інструкції команди) з полем розміру сегмента, що міститься у взятому дескрипторі, і якщо зсув відносно початку сегмента не перевищує розміру межі, то значення EIP додається до значення поля початку сегмента і ми одержуємо шукану лінійну адресу команди. Лінійна адреса - це одна з форм віртуальної адреси. Вихідна двійкова віртуальна адреса, що обчислюється відповідно до використовуваної адресації, перетвориться в лінійну. В свою чергу, лінійна адреса буде дорівнювати або фізичному (якщо сторінкове перетворення відключене), або за допомогою сторінкової трансляції перетвориться у фізичну адресу. Якщо ж зсув з регістра EIP перевищує розмір сегмента коду, то ця аварійна ситуація викликає переривання і керування повинне передаватися супервізору ОС.

    Мал. 7.5 Сегмент стану задачі (tss).

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

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

    Мал. 7.6 Процес отримання лінійної адреси команди.

    4. Підтримка сторінкового способу організації віртуальної пам'яті.

    При створенні мікропроцесора i80386 розробники зштовхнулися з дуже серйозною проблемою в реалізації сторінкового механізму. Справа в тім, що мікропроцесор має широку шину адресу — 32 біта — і виникає питання про розбивку всієї адреси на поле сторінки і поле індексу. Якщо велику кількість бітів адреси відвести під індекс, то сторінки стануть дуже великими, що спричинить великі втрати і на фрагментацію, і на операції введення/виведення, зв'язані з заміщенням сторінок. Хоча кількість сторінок сталася б при цьому менше, і накладні витрати при їхній підтримці теж би зменшилися. Якщо ж розмір сторінки зменшити, то велике поле номера-сторінки привело б до появи величезної кількості можливих сторінок і необхідно було або вводити якісь механізми контролю за номером сторінки (для того, щоб він не виходив за розміри таблиці сторінок), або створювати ці таблиці максимально можливого розміру. Розробники пішли по шляху, при якому розмір сторінки все-таки невеликий (він обраний рівним 212 = 4096 = 4К), а поле номера сторінки завбільшки 20 бітів, у свою чергу, розбивається на два поля і здійснюється двохетапна (двохкрокова) сторінкова трансляція.

    Для опису кожної сторінки створюється відповідний дескриптор. Довжина дескриптора обрана рівною 32 бітам: 20 бітів лінійної адреси визначають номер сторінки (власне кажучи — її адресу, оскільки додавання до нього (приписування як молодші розряди) 12 нулів приводить до визначення початкової адреси сторінки), а інші біти розбиті на наступні поля, що зображені на мал. 3.7. Як видно, три біти дескриптора зарезервовані для використання системними програмістами при розробці підсистеми організації віртуальної пам'яті. З цими бітами мікропроцесор сам не працює.

    Мал. 7.7 Дескриптор сторінки.

    Насамперед, мікропроцесор аналізує самий молодший біт дескриптора — біт присутності, тому що якщо поле present дорівнює нулю, те це означає відсутність даної сторінки в оперативній пам'яті, і така ситуація призводить до переривання в роботі процесора з передачею керування відповідній програмі, що повинна буде завантажити викликану сторінку. Біт dirty — «брудний» — призначений для оцінки, що дану сторінку модифікували і при заміщенні цього сторінкового кадру наступним її необхідно зберегти в зовнішній пам'яті. Біт звертання (access) свідчить про те, що до даної таблиці чи сторінки здійснювався доступ. Він використовується для визначення сторінок), що буде брати участь у заміщенні при використанні дисциплін LRU чи LFU. Нарешті, перший і другий біти використовуються для захисту пам'яті.

    Старші 10 бітів лінійної адреси визначають номер таблиці сторінок (раgе table entry, РТЕ), з якої за допомогою других 10 бітів лінійної адреси вибирається відповідний дескриптор віртуальної сторінки. І вже з цього дескриптора вибирається номер фізичної сторінки, якщо дана віртуальна сторінка відображена зараз на оперативну пам'ять. Ця схема визначення фізичної адреси по лінійному зображена на мал. 3.8.

    Чорна таблиця, що ми індексуємо першими (старшими) 10 бітами лінійної адреси, названа таблицею каталогів таблиць сторінок (раge directory entry PDE). Її адреса в оперативній пам'яті визначається старшими 20 бітами керуючого регістра CR3.

    Мал. 7.8 Трансляція лінійної адреси в мікропроцесорах і80x86.

    Кожна з таблиць PDE і РТЕ складається з 1024 елементів (210=1024). У свою чергу, кожен елемент (дескриптор сторінки) має довжину 4 байти (32 біта), тому розмір цих таблиць саме відповідає розміру сторінки. Оцінимо тепер цю двохкрокову схему трансляції з позицій витрати пам'яті. Кожен дескриптор описує сторінку розміром 4 Кбайт. Отже, одна таблиця сторінок, що містить 1024 дескриптора, описує простір пам'яті в 4 Мбайт. Якщо наша задача користується віртуальним адресним простором, наприклад, у 50 Мбайт (припустимо, що мова йде про деякий графічний редактор, що обробляє зображення, що складається з великої кількості пикселов), то для опису цієї пам'яті необхідно мати 14 сторінок, що містять таблиці РТЕ. Крім цього, нам буде потрібно для цієї задачі ще одна таблиця PDE (теж розміром в одну сторінку), у якій 14 дескрипторів будуть вказувати на місцезнаходження згаданих таблиць РТЕ. Інші дескриптори PDE можуть бути не задіяні. Разом, для опису 50 Мбайт адресного простору задачі буде потрібно всього 15 сторінок, тобто 60 Кбайт пам'яті, що можна вважати прийнятним.

    Якби не був використаний такий двохкроковий механізм трансляції, то втрати пам'яті на опис адресного простору могли б скласти 4(Кбайт) * 210 = 4 (Мбайт)! Очевидно, що це вже неприйнятне рішення.

    Отже, мікропроцесор для кожної задачі, для якої в нього є TSS, дозволяє мати таблицю PDE і деяку кількість РТЕ. Оскільки це дає можливість адресуватися до будь-якого байта з 232, а шина адреси саме і дозволяє використовувати фізичну пам'ять з таким обсягом, то можна як би відмовитися від сегментного способу адресації. Іншими словами, якщо вважати, що завдання полягає з одного єдиного сегмента, що, у свою чергу, розбитий на сторінки, то фактично ми одержуємо тільки один сторінковий механізм роботи з віртуальною пам'яттю. Цей підхід одержав назву «плоскої пам'яті». При використанні плоскої моделі пам'яті спрощується створення і операційних системи, і систем програмування. Крім цього, зменшуються витрати пам'яті для підтримки системних інформаційних структур. Тому в абсолютній більшості сучасних 32-розрядних ОС, створюваних для мікропроцесорів i80x86, використовується плоска модель пам'яті.

    5. Режим віртуальних машин для виконання додатків реального режиму.

    Розробники розглянутого сімейства мікропроцесорів у своєму прагненні забезпечити максимально можливу сумісність архітектури пішли не тільки на те, щоб забезпечити можливість програмам, створеним для перших 16-розрядних ПК, без проблем виконуватися на комп'ютерах з більш пізніми моделями мікропроцесорів за рахунок введення реального режиму роботи. Вони також забезпечили можливість виконання 16-розрядних додатків реального режиму за умови, що сам процесор при цьому функціонує в захищеному режимі роботи й операційна система, використовуючи відповідні апаратні засоби мікропроцесора, організує мультипрограмний (мультизадачный) режим. Іншими словами, мікропроцесори i80x86 підтримують можливість створення операційних середовищ реального режиму при роботі мікропроцесора в захищеному режимі. Якщо умовно назвати 16-розрядні додатки DOS-додатками (оскільки в абсолютній більшості випадків це саме так), то можна сказати, що введено підтримку для організації віртуальних DOS-машин, що працюють разом зі звичайними 32-бітовими додатками захищеного режиму. Це навіть знайшло відображення в назві режиму роботи мікропроцесорів і80x86 — режим віртуального процесора i8086, іноді (для стислості) його називають режимом V86 чи просто віртуальним режимомпри якому у захищеному режимі роботи може виконуватися код DOS-додатка. Мультизадачність при виконанні декількох програм реального режиму буде підтримана апаратними засобами захищеного режиму.

    Перехід у віртуальний режим здійснюється за допомогою зміни біта VM (virtual mode) у регістрі EFLAGS. Коли процесор знаходиться у віртуальному режимі, для адресації пам'яті використовується схема реального режиму роботи - (сегмент: зсув) з розміром сегментів до 64 Кбайт, що можуть розташовуватися в адресному просторі розміром у 1 Мбайт, однак отримані адреси вважаються не фізичними, а лінійними. У результаті застосування сторінкової трансляції здійснюється відображення віртуального адресного простору 16-бітового додатка на фізичний адресний простір. Це дозволяє організувати рівнобіжне виконання декількох задач, розроблених для реального режиму, так ще і разом зі звичайними 32-бітовими додатками потребуючих захищеного режиму роботи.

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

    Питання, зв'язане з операціями введення/виведення, які недоступні для звичайних додатків, зважується аналогічно. При спробі виконати неприпустимі команди введення/виведення виникають переривання, і необхідні операції виконуються операційною системою, хоча задача про цьому і «не підозрює». При виконанні команд IN, OUT, INS, OUTS, CLI, STI процесор, що знаходиться у віртуальному режимі і виконує код на рівні привілеїв третього (самого нижнього) кільця захисту, за рахунок виникаючих унаслідок цього переривань переводиться на виконання високо привілейованого коду операційної системи.

    Таким чином, ОС можуть цілком віртуалізувати ресурси комп'ютера: і апаратні, і програмні, створюючи інше повноцінне операційне середовище; при існуванні так званих нативных додатків, створюваних по власних специфікаціях даної ОС. Дуже важливим моментом для організації повноцінної віртуальної машини є реалізація віртуалізації не тільки програмних, але й апаратних ресурсів. Так, наприклад, в ОС Windows NT ця задача виконана явно невдало, тоді як у OS/2 є повноцінна віртуальна машина як для DOS-додатків, так і для додатків, що працюють у середовищі специфікацій Win16. Правда, останнім часом це вже перестало бути актуальним, оскільки з'явилася велика кількість додатків, що працюють по специфікаціях Win32 API.

    6. Захист адресного простору задач.

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

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

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

    Рівні привілеїв для захисту адресного простору задач.

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

    У мікропроцесорах i80x86 маються не два, а чотири рівні привілеїв. Часто рівні привілеїв називають кільцями захисту, оскільки це іноді допомагає пояснити принцип дії самого механізму; тому говорять, що деякий програмний модуль «виконується в кільці захисту з таким-то номером». Для вказівки рівня привілеїв використовуються два біти, тому код 00 позначає самий вищий рівень, а код 11 (=3) — самий нижчий. Найвищий рівень привілеїв призначений для операційної системи (насамперед, для ядра ОС), найнижчий — для прикладних задач користувача. Проміжні рівні привілеїв введені для більшої свободи системних програмістів в організації надійних обчислень при створенні ОС і іншого системного ПЗ. Передбачалося, що рівень з номером (кодом) 1 може бути використаний, наприклад, для системного сервісу — програм обслуговування апаратури, драйверів, що працюють з портами введення/виведення. Рівень привілеїв з кодом 2 може бути використаний для створення користувацьких інтерфейсів, систем керування базами даних і т.п., тобто для реалізації спеціальних системних функцій, що стосовно супервізора ОС поводяться як звичайні додатки. Так, наприклад, система OS/2 використовує три рівні привілеїв: з нульовим рівнем привілеїв виконується код самої ОС, на другому рівні виповнюються системні процедури підсистеми введення/виведення, на третьому рівні виповнюються прикладні задачі користувачів. Однак найчастіше на практиці використовуються тільки два рівні — нульової і третій. Таким чином, згаданий режим супервізора для мікропроцесорів і80x86 відповідає виконанню коду з рівнем привілеїв 0 (його позначають так: PL0 – privilege level). Підводячи підсумок, можна констатувати, що саме рівень привілеїв задач визначає, які команди в них можна використовувати і яка підмножина сегментів і/чи сторінок у їхньому адресному просторі вони можуть обробляти.

    Основними системними об'єктами, якими маніпулює процесор при роботі в захищеному режимі, є дескриптори. Дескриптори сегментів містять інформацію про рівень привілею відповідного сегмента чи коду даних. Рівень привілею задачі, що виконується, визначається значенням поля привілею, що знаходиться в дескрипторі її поточного кодового сегмента. Нагадаємо, що в кожнім дескрипторі сегмента (див. мал.3.3) мається поле DPL у байті прав доступу, що і визначає рівень привілею зв'язаного з ним сегмента. Таким чином, поле DPL поточного сегмента коду стає полем CPL. При звертанні до якого-небудь сегмента і відповідному селекторі вказується запитуваний рівень привілеїв RPL (див. мал. 3.4).

    У межах однієї задачі використовуються сегменти з різним рівнем привілею й у визначені моменти часу виконуються чи обробляються сегменти з відповідними їм рівнями привілею. Механізм перевірки привілеїв працює в ситуаціях, які можна назвати міжсегментними переходами (звертаннями). Це доступ до сегмента даних чи стековому сегменту, міжсегментні передачі керування у випадку переривань (і особливих ситуацій), при використанні команд CALL, JMP, INT, IRET, RET. У таких міжсегментних звертаннях беруть участь два сегменти: цільовий сегмент (до якого ми звертаємося) і поточний сегмент коду, з якого йде звертання.

    Процесор порівнює згадані значення CPL, RPL, DPL і на основі поняття ефективного рівня привілеїв (EPL = max (RPL, DPL)) обмежує можливості доступу до сегментів за наступними правилами, у залежності від того, чи йде мова про звертання до коду чи до даних.

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

    Якщо цільовий сегмент є сегментом стека, то правило перевірки має вид

    CPL-DPL=RPL.

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

    Правила для передачі керування, тобто коли здійснюється міжсегментний перехід з одного сегмента коду на інший сегмент коду, трохи складніше. Якщо для переходу з одного сегмента даних на інший сегмент даних вважається припустимим обробляти менш привілейовані сегменти, то передача керування з високо привілейованого коду на менш привілейований код повинна контролюватися додатково. Іншими словами, код операційної системи не повиннен довіряти коду прикладних задач. І навпаки, не можна просто так давати задачам можливість виконувати високо привілейований код, хоча потреба в цьому є завжди (адже багато функцій, у тому числі і функції введення/виведення, вважаються привілейованими і повинні виконуватися тільки самою ОС). Для реалізації можливостей передачі керування в сегменти коду з іншими рівнями привілеїв уведений механізм шлюзування, що ми коротенько розглянемо нижче. Отже, якщо DPL = CPL, то перехід в інший сегмент коду можливий. Більш докладний розгляд порушених питань за задумом авторів виходить за рамки дійсного підручника. Тут ми розглянемо тільки основні ідеї.

    7. Механізм шлюзів для передачі керування на сегменти коду з іншими рівнями привілеїв.

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

    Мал. 7.9 Механізм шлюзів для переходу на другий рівень привілеїв.

    Крім дескрипторів сегментів системними об'єктами, з якими працює мікропроцесор, є спеціальні системні дескриптори, названі шлюзами чи вентилями. Головне розходження між дескриптором сегмента і шлюзом виклику полягає в тім, що вміст дескриптора вказує на сегмент у пам'яті, а шлюз звертається до дескриптора. Іншими словами, якщо дескриптор служить механізмом відображення пам'яті, то шлюз служить механізмом перенапрямку.

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

    У цьому дескрипторі замість адреси сегмента вказуються селектор, що дозволяє знайти дескриптор шуканого сегмента коду, і адреса (зсув призначення), з якого буде виконуватися підлеглий сегмент, тобто повна 32 бітна адреса. Формат дескриптора шлюзу приведений на мал. 3.11. Адресувати шлюз виклику можна за допомогою команди CALL. Власне кажучи, дескриптори шлюзів виклику не є дескрипторами (сегментів), але вони можуть бути розташовані серед звичайних дескрипторів у дескрипторних таблицях процесу. Зсув, що вказується в команді переходу на інший сегмент (FAR CALL), ігнорується, і фактично здійснюється перехід на команду, адресу якої визначається через зсув зі шлюзу виклику. Цим гарантується попадання тільки на дозволені крапки входу в підлеглі сегменти.

    Мал. 7.10 Перехід на сегмент більш привілейованого коду.

    Мал. 7.11 Формат дескриптора шлюзу.

    Уведено наступні правила використання шлюзів:

    • значення DPL шлюзу виклику повинне бути більше чи дорівнювати значенню поточного рівня привілеїв CPL;

    • значення DPL шлюзу виклику повинне бути більше чи дорівнювати значенню поля RPL селектора шлюзу;

    • значення DPL шлюзу виклику повинне бути більше чи дорівнювати значенню DPL цільового сегмента коду;

    • значення DPL цільового сегмента коду повинне бути менше чи дорівнювати значенню поточного рівня привілеїв CPL.

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

    • привілейований код надійно захищений і визиваючі його програми не можуть його зруйнувати. Природньо, що такий системний код повинний бути особливо ретельно налагодженим, не містити помилок, бути максимально ефективним;

    • шлюзи міжсегментних переходів для виклику системних функцій роблять ці самі системні функції невидимими для програмних модулів, розташованих на зовнішніх (більш низьких) рівнях привілеїв;

    • оскільки викликаюча програма безпосередньо адресує тільки шлюз виклику, реалізовані викликаючим модулем (сегментним кодом) функції можна змінити чи перемістити в адресному просторі, не торкаючись інтерфейсу зі шлюзом;

    • програмні модулі викликаються з більш привілейованого рівня.

    Викладений коротко апаратний механізм захисту по привілеях виявляється досить складним і жостким.

    Основний ризик зв'язаний з передачею керування через шлюз виклику більш привілейованій процедурі. Не можна надавати викликаючій програмі ніяких переваг, що випливають через тимчасове підвищення привілеїв. Це зауваження особливо важливе для процедур нульового рівня привілеїв (PL0-процедур).

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

    1. Варто перевіряти лічильники циклів і повторень на мінімальні і максимальні значення.

    2. Необхідно перевірити 8- і 16-бітні параметри, передаваємі в 32-бітних регістрах. Коли процедурі передається короткий параметр, його варто розширити з знаком чи нулем для заповнення всього 32-бітного регістра.

    3. Потрібно прагнути звести до мінімуму час роботи процесора з забороненими перериваннями. Якщо процедурі потрібно заборонити переривання, необхідно, щоб викликаюча програма не могла впливати на час перебування процесора з забороненими перериваннями (флаг IF=0).

    1. Процедура ніколи не повинна сприймати як параметр чи код покажчик коду.

    2. В операціях процесора варто явно задавати стан флагця напрямку DF для ланцюгових команд.

    3. Заключна команда RET чи RETn у процедурі повинна точно відповідати полю лічильника WC шлюзу виклику; при цьому n= 4x(WC), тому що лічильник задає число подвійних слів, а n відповідає байтам.

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

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

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

    Рекомендується контролювати всі звертання до пам'яті. Неважко уявити собі, що PL3-програма передасть PL0-процедурі покажчик селектор:зсув і запросить зчитування чи запис декількох байтів по цій адресі. Типовим прикладом може служити процедура дискового введення/виведення, що сприймає як параметр системний номер файлу, лічильник байт і адреса, по якому записуються дані з диска. Хоча PL0-процедура має привілеї для здійснення такої операції, але в PL3-програми дозволу на це може не бути.

    Тема 8. Організація системи переривань 32-розрядних мікропроцесорів i80х80.

    1. Робота системи переривань у реальному режимі роботи процесора.

    2. Типи переривань.

    3. Каскадні переривання.

    4. Узагальнена процедура обробки переривання.

    5. Особливості системи переривань.

    6. Процедура обробки переривань в захищеному режимі.

    7. Процедура обробки переривань при перемиканні на нову задачу.

    У мікропроцесорах сімейства i80x86 система переривань побудована таким чином, щоб, з одного боку, забезпечити можливість створювати ефективні і надійні мультипрограмні операційні системи, що повинні функціонувати в захищеному режимі, а з іншого боку — забезпечити можливість виконувати програми, розроблені для реального режиму. Розглянемо коротко обидва режими.

    1. Робота системи переривань у реальному режимі роботи процесора.

    У реальному режимі роботи система переривань використовує поняття вектора переривання. Термін «вектор переривань» використовується тому, що для вказівки адреси використовується не одне значення, а два, тобто ми маємо справу не зі скалярною величиною, а з «векторною».

    Отже, кожен вектор переривань складається з 4 байтів чи 2 слів: перші два містять нове значення для регістра IP, а наступні два — нові значення регістра CS. Таблиця векторів переривань займає 1024 байта. У такий спосіб у ній може бути задано 256 векторів переривань. У процесорі і8086 ця таблиця розташовується на адресах 00000H-003FFH. Розташування цієї таблиці в процесорах і80286 і старше визначається значенням регістра IDTR - Interrupt Descriptor Table Register. При включенні чи скиданні процесора і80x86 цей регістр обнуляется. Однак при необхідності можна в регістрі IDTR вказати зсув і, таким чином, перейти на нову таблицю векторів переривань.

    Таблиця векторів переривань заповнюється (ініціалізується) при запуску системи, але в принципі може бути змінена чи переміщена.

    Кожен вектор переривання має свій номер, названий номером переривання, що вказує його місце в таблиці. Цей номер, помножений на чотири (зсув на два розряди вліво і заповнення бітів, що звільнилися нулями), і просумований із умістом регістра IDTR, дає абсолютну адресу першого байта вектора в оперативній пам'яті.

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

    2. Типи переривань.

    У IBM PC, як і в інших обчислювальних системах, переривання бувають двох видів: внутрішні і зовнішні.

    Внутрішні переривання, як ми вже знаємо, виникають у результаті роботи процесора. Вони виникають у ситуаціях, що мають потребу в спеціальному обслуговуванні, чи при виконанні спеціальних інструкцій — INT чи INTO. Це наступні переривання:

    • переривання при діленні на нуль, номер переривання — 0;

    • переривання по флазі TF (trap flag). В цьому випадку переривання зазвичай використовується спеціальними програмами налагодження типу DEBUG. Номер переривання – 1;

    • інструкції INT (interrupt - виконати переривання з відповідним номером) і INTO (interrupt if overflow — переривання по переповненню). Ці переривання називаються програмними.

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

    Зовнішні переривання виникають по сигналі якого-небудь зовнішнього пристрою. Існують два спеціальних зовнішніх сигнали серед вхідних сигналів процесора, за допомогою яких можна перервати виконання поточної програми і тим самим переключити роботу центрального процесора. Це сигнали NMI (nо mask interrupt, немасковане переривання) і INTR (interrupt request, запит на переривання). Відповідно, зовнішні переривання підрозділяються на немасковані і масковані.

    Масковані переривання генеруються контролером переривань за заявкою визначених периферійних пристроїв. Контролер переривань (його позначення — і8259A) підтримує вісім рівнів (ліній) пріоритету; до кожного рівня «прив'язаний» один периферійний пристрій. Масковані переривання часто називають ще апаратними перериваннями. У ПК, починаючи з IBM PC AT, побудованих на базі мікропроцесора i80286, використовуються два контролери переривань S8259A; вони з'єднуються каскадним образом. Схема послідовного з'єднання цих контролерів зображена на мал. 3.12.

    Таким чином, на IBM PC AT передбачено 15 ліній IRQ (interrupt request), частина яких використовується внутрішніми контролерами системної плати, а інші зайняті стандартними адаптерами або не використовуються. Нижче перераховані лінії запиту на переривання, які ми приводимо тому, що кожен фахівець по обчислювальній техніці повинен знати основні стандарти ПК. Отже, лінії IRQ:

    0 - системний таймер;

    1 - контролер клавіатури;

    2 - сигнал повернення по кадрі (EGA/VGA), на AT з'єднаний з IRQ 9;

    3 - звичайно СОМ2/СОМ4;

    4 - звичайно СОМ 1/СОМЗ;

    5- контролер HDD (па перших комп'ютерах IBM PC XT), звичайно вільний на IBM PC AT і використовується звуковою картою;

    6 - контролер FDD;

    7 - LPT1, багатьма LPT-контролерами не використовується;

    8- годинник реального часу з автономним харчуванням (RTC — real time clock);

    9 - рівнобіжна IRQ 2;

    1. - не використовується, тобто вільно;

    2. - вільно;

    3. - звичайно контролер миші типу PS/2;

    13 - математичний співпроцесор;

    14 - звичайно контролер IDEO (перший канал);

    15 - звичайно контролер IDE1 (другий канал).

    Мал. 8.1 Каскадування контролерів переривання.

    4. Узагальнена процедура обробки переривання.

    Як відомо, переривання можуть бути ініційовані зовнішнім пристроєм ПК чи спеціальною командою переривання з програми. У будь-якому випадку, якщо переривання дозволені, то виконується наступна процедура:

    1. У стек поміщається регістр флагів PSW.

    2. Флаг включення/вимикання переривань IF і флаг трасування TF, що знаходяться в регістрі PSW, обнуляются для блокування інших маскованих переривань і виключення покрокового режиму виконання команд.

    3. Значення регістрів CS і IP зберігаються в стеці слідом за PSW.

    4. Обчислюється адреса вектора переривання, і з вектора, який відповідає номеру переривання, завантажуються нові значення IP і CS.

    Коли системна підпрограма приймає керування, вона може знову дозволити масковані переривання командою STI (set interrupt flag, установити флаг переривань), що переводить флаг IF у стан 1, що дозволяє мікропроцесору знову реагувати на переривання, ініціалізовані зовнішніми пристроями, оскільки стекова організація дозволяє вкладення переривань одне в одного.

    Закінчивши роботу, підпрограма обробки переривання повинна виконати інструкцію IRET (interrupt return), що витягає зі стека три 16-бітових значення і завантажує їх у покажчик команд IP, регістр сегмента команд CS і регістр PSW відповідно. Таким чином, процесор зможе продовжити роботу з того місця, де він був перерваний.

    У випадку зовнішніх переривань процедура переходу на підпрограму обробки переривання доповнюється наступними кроками:

    1. Контролер переривань одержує заявку від визначеного периферійного пристрою і, дотримуючи схеми пріоритетів, генерує сигнал INTR (interrupt request), що є вхідним для мікропроцесора.

    2. Мікропроцесор перевіряє флаг IF у регістрі PSW. Якщо він встановлений у 1, то переходимо до кроку 3. У противному випадку робота процесора не переривається. Часто говорять, що переривання замасковані, хоча вірніше говорити, що вони відключені. Маскуються (забороняються) окремі лінії запиту на переривання за допомогою програмування контролера переривань.

    3. Мікропроцесор генерує сигнал INTA (підтвердження переривання). У відповідь на цей сигнал контролер переривання посилає по шині даних номер переривання. Після цього виконується описана нами раніше процедура передачі керування відповідній програмі обробки переривання.

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

    5. Робота системи переривань у захищеному режимі роботи процесора.

    У захищеному режимі роботи система переривань діє зовсім інакше. Насамперед, система переривань мікропроцесора i80x86 при роботі в захищеному режимі замість таблиці векторів, про яку ми говорили вище, має справу з таблицею дескрипторів переривань (IDT, interrupt descriptor table). Справа тут не стільки в назві таблиці, скільки в тім, що таблиця IDT являє собою не таблицю з адресами оброблювачів переривань, а таблицю зі спеціальними системними структурами даних (дескрипторами), доступ до якої з боку користувацьких (прикладних) програм неможливий. Тільки сам мікропроцесор (його система переривань) і код операційної системи можуть одержати доступ до цієї таблиці, що являє собою спеціальний сегмент, адреса і довжина якого містяться в регістрі IDTR (див. мал. 3.2). Цей регістр аналогічний регістру GDTR у тім відношенні, що він ініціалізується один раз при завантаженні системи. Цікаво помітити, що в реальному режимі роботи регістр IDTR так само вказує адресу таблиці переривань, але при цьому, як і в процесорі і8086, кожен елемент таблиці переривань (вектор) займає всього 4 байти і містить 32-бітну адресу у форматі селектор:зсув (CS:IP). Початкове значення цього регістра дорівнює нулю, але в нього можна занести й інше значення. У цьому випадку таблиця векторів переривань буде знаходитися в іншому місці оперативної пам'яті. Природньо, що перед тим, як це зробити (занести в регістр IDTR нове значення), необхідно підготувати саму таблицю векторів. У захищеному режимі роботи завантаження регістра IDTR може зробити тільки код з максимальним рівнем привілеїв. Кожен елемент у таблиці дескрипторів переривань, про яку ми говоримо вже в захищеному режимі, являє собою 8-байтову структуру, більш схожу на дескриптор шлюзу (gate), ніж на дескриптор сегмента. Як ми вже знаємо, у залежності від причини переривання процесор автоматично індексує таблицю переривань і вибирає відповідний елемент, за допомогою якого і здійснюється перенапрямок у виконанні коду, тобто передача керування на оброблювач переривання. Однак таблиця IDT містить тільки шлюзи, а не дескриптори сегментів коду, тому фактично виходить непряма адресація, але з використанням розглянутого раніше механізму захисту за допомогою рівнів привілею. Завдяки цьому користувачі вже не можуть самі змінити обробку переривань, що визначається системним програмним забезпеченням.

    Дескриптор переривань може належати до одного з трьох типів:

    • комутатор переривання (interrupt gate);

    • комутатор перехоплення (trap gate);

    • комутатор задачі (task gate).

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

    Обробка переривань у контексті поточної задачі.

    Розглянемо мал. 3.13, що пояснює обробку переривання в контексті поточної задачі. При виникненні переривання процесор по номеру переривання індексує таблицю IDT, тобто адреса відповідного комутатора визначається шляхом додавання вмісту поля адреси в регістрі IDTR і номера переривання, помноженого на 8 (праворуч до номера переривання додаються три нулі). Отриманий дескриптор аналізується, і якщо його тип відповідає комутатору trap gate чи комутатору interrupt gate, то виконуються наступні дії.

    1. У стек на рівні привілеїв поточного сегмента коду поміщаються:

    • значення SS і SP, якщо рівень привілеїв у комутаторі вище рівня привілеїв раніше виповнювався коду;

    • регістр флагів EFLAGS;

    • регістри CS і IP.

    1. Якщо розглянутому перериванню відповідав комутатор interrupt gate, то забороняються переривання (флаг IF:=0 у регістрі EFLAGS). У випадку комутатора trap gate флаг переривань не скидається й обробка нових переривань на період обробки поточного переривання тим самим не забороняється.

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

    Мал. 8.2 Схема передачі управління при перериванні в контексті поточної задачі.

    Таким чином, у випадку обробки переривань, коли дескриптором переривань є комутатор interrupt gate чи trap gate, ми залишаємося в тому же віртуальному адресному просторі, і повної зміни контексту поточної задачі не відбувається. Просто ми переключаємося на виконання іншого (як правило, більш привілейованого) коду, але також приналежного (або, вірніше сказати, доступного) задачі, що виконується. Цей код створюється системними програмістами, і прикладні програмісти його просто використовують. У той же час механізми захисту мікропроцесора дозволяють забезпечити неприступність цього коду для його виправлення (з боку додатків, які його викликають) і неприступність самої таблиці дескрипторів переривань. Зручніше за все код оброблювачів переривань розташовувати в загальному адресному просторі, тобто селектори, що вказують на такий код, повинні розташовуватися в глобальній таблиці дескрипторів.

    7. Обробка переривань з переключенням на нову задачу.

    Зовсім інакше здійснюється обробка переривань у випадку, якщо дескриптором переривань є комутатор задачі. Формат комутатора задачі (task gate) відрізняється від комутаторів interrupt gate і trap gate, насамперед, тим, що в ньому замість селектора сегмента коду, на який передається керування, указується селектор сегмента стану задачі (TSS). Це ілюструється за допомогою мал. 3.14. У результаті здійснюється процедура переходу на нову задачу з повною зміною контексту, тому що сегмент стану задачі цілком визначає новий віртуальний простір і адресу початку програми, а поточний стан задачі, що переривається, апаратно (по мікропрограмі мікропроцесора) зберігається в її власному TSS.

    Рис. 8.3 Схема передачі керування при перериванні з переключенням на нову задачу.

    При цьому відбувається повне переключення на нову задачу з вкладенням, тобто виконуються наступні дії:

    1. Зберігаються всі робочі регістри процесора в поточному сегменті TSS, базова адреса цього сегмента береться в регістрі TR.

    2. Поточна задача відзначається як зайнята.

    3. По селекторі з Task Gate вибирається новий TSS (поле селектора міститься в регістр TR) і завантажується стан нової задачі. Нагадаємо, що завантажуються значення регістра LDTR, EFLAGS, вісім регістрів загального призначення, покажчик команди регістр EIP і шість сегментних регістрів.

    4. Установлюється біт NT (next task).

    5. У поле зворотного зв'язку TSS міститься селектор перерваної задачі.

    6. Значення CS:IP, узяті з нового TSS, дозволяють знайти і виконати першу команду оброблювача переривання.

    Таким чином, комутатор task gate дає вказівку процесору зробити переключення задачі, і обробка переривання здійснюється під контролем окремої зовнішньої задачі. У кожнім сегменті TSS є селектор локальної дескрипторної таблиці LDT, тому при переключенні задачі процесор завантажує в регістр LDTR нове значення. Це дозволяє звернутися до сегментів коду, що абсолютно не перетинаються із сегментами коду будь-яких інших задач, оскільки саме локальні дескрипторні таблиці забезпечують ефективне ізолювання віртуальних адресних просторів. Нова задача починає своє виконання на рівні привілеїв, обумовленому полем RPL нового вмісту регістра CS, що завантажується із сегмента TSS. Перевагою цього комутатора є те, що він дозволяє зберегти всі регістри процесора за допомогою механізму переключення задач, тоді як комутатори trap gate і interrupt gate зберігають тільки вміст регістрів IFLAGS, CS і IP і збереження інших регістрів покладається на програміста, що розробляє відповідну програму обробки переривання.

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

    Тема 9. Керування вводом/виводом даних.

    1. Основні поняття і визначення процесу вводу/виводу даних. Основні задачі супервізора вводу/виводу даних.

    2. Режими керування вводом/виводом.

    3. Закріплення пристроїв, загальні пристрої вводу/виводу.

    4. Основні системні таблиці вводу/виводу.

    5. Синхронний і асинхронний ввід/вивід.

    6. Кешування операцій вводу/виводу при роботі з накопичувачами на магнітних дисках.

    1. Основні поняття і визначення процесу вводу/виводу.

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

    Тому самим головним є наступний принцип: будь-які операції по керуванню вводом/виводом об‘являються привілейованими і можуть виконуватися тільки кодом самої ОС. Для забезпечення цього принципу в більшості процесорів навіть вводяться режими користувача і супервізора. Як правило, у режимі супервізора виконання команд вводу/виводу дозволено, а в користувацькому режимі — заборонено. Використання команд вводу/виводу в користувацькому режимі викликає виключення і керування через механізм переривань передається коду ОС. Хоча можливі і більш складні системи, в яких у ряді випадків користувацьким програмам дозволене безпосереднє виконання команд вводу/виводу.

    Ще раз підкреслимо, що, насамперед, ми говоримо про мультипрограмні ОС, для яких існує проблема поділу ресурсів. Одним з основних видів ресурсів є пристрої вводу/виводу і відповідне програмне забезпечення, за допомогою якого здійснюється керування обміном даними між зовнішніми пристроями й оперативною пам'яттю. Крім поділюваних пристроїв вводу/виводу (ці пристрої допускають поділ за допомогою механізму доступу) існують неподілювані пристрої. Прикладами поділюваного пристрою можуть служити накопичувач на магнітних дисках, пристрій для читання компакт-дисків. Цей пристрій з прямим доступом. Приклади неподілюваних пристроїв — принтер, накопичувач на магнитних стрічках. Цей пристрій з послідовним доступом. Операційні системи повинні керувати і тими й іншими пристроями, надаючи можливість паралельно виконуваним задачам використовувати різні пристрої вводу/виводу. Можна назвати три основні причини, по яких не можна дозволяти кожній окремій користувацькій програмі звертатися до зовнішніх пристроїв безпосередньо:

    • Необхідність вирішувати можливі конфлікти доступу до пристроїв вводу/виводу. Наприклад, дві паралельно виконуємі програми намагаються вивести на друк результати своєї роботи. Якщо не передбачити зовнішнє керування пристроєм друкку, то в результаті ми можемо одержати текст, що абсолютно нечитається, тому що кожна програма буде час від часу виводити свої дані, що будуть перемежовуватися з даними іншої програми. Інший приклад: ситуація, коли одній програмі необхідно прочитати дані з деякого сектора магнітного диска, а іншій — записати результати в інший сектор того ж накопичувача. Якщо операції вводу/виводу не будуть відслідковуватися якимось третім (зовнішнім) процесом-арбітром, то після позиціювання магнітної голівки для першого запиту може відразу з'явитися команда позиціювання голівки для другої задачі, і обидві операції вводу/виводу не зможуть бути виконані коректно.

    • Бажання збільшити ефективність використання цих ресурсів. Наприклад, у накопичувача на магнітних дисках час підведення голівки читання/запису до необхідної доріжки і звертання до визначеного сектора може значно (до тисячі разів) перевищувати час пересилання даних. У результаті, якщо задачі по черзі звертаються до циліндрів, що знаходяться далеко один від одного, то корисна робота, виконувана накопичувачем, може бути істотно знижена.

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

    Отже, керування вводом/виводом здійснюється операційною системою, компонентом, що найчастіше називають супервізором вводу/виводу. У перелік основних задач, покладених на супервізор, входять наступні:

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

    • супервізор вводу/виводу викликає відповідні розподільники каналів і контролерів, планує ввід/вивід (визначає чергу надання пристроїв вводу/виводу задачам, що потребують їх). Запит на введення/виведення або відразу виконується, або ставиться в чергу на виконання;

    • супервізор вводу/виводу ініціює операції вводу/виводу (передає керування відповідним драйверам) і у випадку керування вводом/виводом з використанням переривань надає процесор диспетчеру задач для того, щоб передати його першій задачі, що стоїть в черзі на виконання;

    • при одержанні сигналів переривань від пристроїв вводу/виводу супервізор ідентифікує їх (рис.9.1) і передає керування відповідній програмі обробки переривання (як правило, на секцію продовження драйвера);

    • супервізор вводу/виводу здійснює передачу повідомлень про помилки, якщо такі виникають в процесі керування операціями вводу/виводу;

    • супервізор вводу/виводу посилає повідомлення про завершення операції вводу/виводу процесу, що запросив цю операцію, і знімає його зі стану чекання вводу/виводу, якщо процес очікував завершення операції.

    У випадку якщо пристрій вводу/виводу є ініціативним, керування з боку супервізора вводу/виводу буде полягати в активізації відповідного обчислювального процесу (переклад його в стан готовності до виконання). Ініціативним називають такий пристрій (зазвичай це датчики, зовнішній пристрій, а не пристрій вводу/виводу), по сигналі переривання від якого запускається відповідна йому програма. Така програма, з одного боку, не є драйвером, і керувати операціями обміну даними немає необхідності. Але, з іншого боку, запуск такої програми здійснюється саме по подіях, які зв'язані з генерацією відповідного сигналу пристроєм вводу/виводу. Різниця між драйверами, що працюють по перериваннях, і ініціативними програмами полягає в статусі цих програмних модулів. Драйвер є компонентом операційної системи і часто виконується не як обчислювальний процес, а як системний об'єкт, а ініціативна програма є звичайним обчислювальним процесом, тільки його запуск здійснюється з ініціативи зовнішнього пристрою.

    Таким чином, прикладні програми (а в загальному випадку — всі обробні програми) не можуть безпосередньо зв'язуватися з пристроями вводу/виводу незалежно від використання пристроїв (монопольно чи спільно). Установивши відповідні значення параметрів у запиті на ввід/вивід, що визначають необхідну операцію і кількість споживаних ресурсів, вони можуть передати керування супервізору вводу/виводу, що і запускає необхідні логічні і фізичні операції.

    Згаданий вище запит на ввід/вивід повинний задовольняти вимогам API тієї операційної системи, у середовищі якої виконується додаток. Параметри, що вказуються в запитах на ввід/вивід, передаються не тільки в викликаючих послідовностях, створюваних по специфікаціях API, але і як дані, які зберігаються у відповідних системних таблицях. Усі параметри, які будуть стояти в викликаючій послідовності, поставляються компілятором і відбивають вимоги програміста і постійну інформацію про операційну систему й архітектуру комп'ютера в цілому. Змінна інформація про обчислювальну систему (її конфігурація, склад устаткування, склад і особливості системного програмного забезпечення) містяться в спеціальних системних таблицях. Процесору, каналам прямого доступу в пам'ять, контролерам необхідно передавати конкретну двійкову інформацію, за допомогою якої і здійснюється керування устаткуванням. Ця конкретна двійкова інформація у виді кодів і даних часто готується за допомогою препроцесорів, але частина її зберігається в системних таблицях.

    2. Режими керування вводом/виводом.

    Я к відомо, є два основних режими вводу/виводу: режим обміну з опитуванням готовності пристрою вводу/виводу і режим обміну з перериваннями. Розглянемо рис.9.1.

    Рис.9.1 Керування вводом/виводом.

    Нехай для простоти керуванням вводом/виводом здійснює центральний процесор (у цьому випадку часто говорять про наявність програмного каналу обміну даними між зовнішнім пристроєм і оперативною пам'яттю, на відміну каналу прямого доступу до пам'яті, при якому керування вводом/виводом здійснює спеціальне додаткове устаткування; ці питання ми обговоримо трохи пізніше). Центральний процесор посилає пристрою керування команду виконати деяку дію пристрою вводу/виводу. Останній виконує команду, транслюючи сигнали, зрозумілі центральному пристрою, пристрою керування в сигнали, зрозумілі пристрою вводу/виводу. Але швидкодія пристрою вводу/виводу набагато менша швидкодії центрального процесора (часом на кілька порядків). Тому сигнал готовності (трансльований чи згенерований пристроєм керування і сигналізуючий процесору про те, що команда вводу/виводу виконана і можна видати нову команду для продовження обміну даними) приходиться дуже довго очікувати, постійно опитуючи відповідну лінію інтерфейсу на наявність чи відсутність потрібного сигналу. Посилати нову команду, не дочекавшись сигналу готовності, що повідомляє про виконання попередньої команди, безглуздо. У режимі опитування готовності драйвер, керуючий процесом обміну даними з зовнішнім пристроєм, саме і виконує в циклі команду «перевірити наявність сигналу готовності». Доти поки сигнал готовності не з'явиться, драйвер нічого іншого не робить. При цьому, природно, нераціонально використовується час центрального процесора. Набагато вигідніше, видавши команду введення/виведення, на час забути про пристрій вводу/виводу і перейти на виконання іншої програми. А появу сигналу готовності трактувати як запит на переривання від пристрою вводу/виводу. Саме ці сигнали готовності і є сигналами запиту на переривання.

    Режим обміну з перериваннями по своїй суті є режимом асинхронного керування. Для того щоб не втратити зв'язок із пристроєм (після того як процесор видав чергову команду по керуванню обміном даними і переключився на виконання інших програм), може бути запушений відлік часу, протягом якого пристрій обов'язково повинен виконати команду і видати таки сигнал запиту на переривання. Максимальний інтервал часу, протягом якого пристрій введення/виведення чи його контролер повинні видати сигнал запиту на переривання, часто називають вставкою тайм-ауту. Якщо цей час минув після видачі пристрою чергової команди, а пристрій так і не відповів, то робиться висновок про те, що зв'язок із пристроєм загублений і керувати ним більше неможливо. Користувач і/чи задача одержують відповідне діагностичне повідомлення.

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

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

    Секція завершення звичайно виключає пристрій вводу/виводу або просто завершує операцію.

    Керування операціями вводу/виводу в режимі переривань вимагає великих зусиль з боку системних програмістів — такі програми створювати складніше, ніж ті, що працюють у режимі опитування готовності. Прикладом тому може служити ситуація з драйверами, що забезпечують друк. Так, в ОС Windows (і Windows 9x, і Windows NT) драйвер друку через паралельний порт працює не в режимі з перериваннями, як це зроблено в інших ОС, а в режимі опитування готовності, що приводить до 100%-го завантаження центрального процесора на весь час друку. При цьому, природньо, виконуються й інші задачі, запущені на виконання, але винятково за рахунок того, що ОС Windows реалізує витісняючу мультизадачність і час від часу перериває процес керування друком і передає центральний процесор іншим задачам.

    3. Закріплення пристроїв, загальні пристрої вводу/виводу.

    Як відомо, багато пристроїв не допускають спільного використання. Насамперед, це пристрої з послідовним доступом. Такі пристрої можуть стати закріпленими, тобто бути наданими деякому обчислювальному процесу на весь час життя цього процесу. Однак це приводить до того, що обчислювальні процеси часто не можуть виконуватися паралельно — вони очікують звільнення пристроїв вводу/виводу. Для організації використання багатьма паралельно виконуючими задачами пристроїв вводу/виводу, що не можуть бути поділюваними, вводиться поняття віртуальних пристроїв. Використання принципу віртуалізації дозволяє підвищити ефективність обчислювальної системи.

    Узагалі говорячи, поняття віртуального пристрою ширше, ніж використання цього терміну для позначення спулінгу (SPOOLing — simultaneous peripheral operation on-line, тобто імітація роботи з пристроєм у режимі «он-лайн»). Головна задача спулінгу — створити видимість паралельного поділу пристрою вводу/виводу з послідовним доступом, що фактично повинно використовуватися тільки монопольно і бути закріпленим. Наприклад, ми вже говорили, що у випадку, коли кілька програм повинні виводити на друк результати своєї роботи, якщо дозволити кожній такій програмі друкувати рядок на першу вимогу, то це приведе до потоку рядків, що не представляють ніякої цінності. Однак можна кожному обчислювальному процесу надавати не реальний, а віртуальний принтер і потік виведених символів (чи керуючих кодів для їхнього друку) спочатку направляти в спеціальний файл на магнітному диску. Потім, по закінченні віртуального друку, відповідно до прийнятої дисципліни обслуговування і пріоритетами додатків виводити вміст спул-файла на принтер. Системний процес, що керує спул-файлом називається спулером (spool-reader чи spool-writer).

    4. Основні системні таблиці вводу/виводу.

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

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

    Перша таблиця (чи список) містить інформацію про всі пристрої вводу/виводу, підключених до обчислювальної системи. Назвемо її умовно таблицею устаткування (equipment table), а кожен елемент цієї таблиці нехай називається UCB (unit control block, блок керування пристроєм вводу/виводу). Кожен елемент UCB таблиці устаткування, як правило, містить наступну інформацію про пристрій:

    • тип пристрою, його конкретна модель, символічне ім'я і характеристики пристрою;

    • як цей пристрій підключений (через який інтерфейс, до якого роз‘єму, які порти і лінія запиту переривання використовуються і т.д.);

    • номер і адресу каналу (і підканалу), якщо такі використовуються для керування пристроєм;

    • вказівка на драйвер, що повинний керувати цим пристроєм, адреса секції запуску і секції продовження драйвера;

    • інформація про те, використовується чи ні буферизація при обміні даними з цим пристроєм, «ім'я» (чи просто адреса) буфера, якщо такий виділяється із системної області пам'яті;

    • уставка тайм-ауту і комірки для лічильника тайм-ауту;

    • стан пристрою;

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

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

    Друга таблиця призначена для реалізації ще одного принципу віртуалізації пристроїв вводу/виводу — незалежності від пристрою. Бажано, щоб програміст не був заклопотаний обліком конкретних параметрів (і/чи можливостей) того чи іншого пристрою вводу/виводу, що встановлене (чи не встановлене) у комп'ютер. Для нього повинні бути важливі тільки самі загальні можливості, характерні для даного класу пристроїв вводу/виводу, якими він бажає скористатися. Наприклад, принтер повинний уміти виводити (друкувати) символи чи графічне зображення. А накопичувач на магнітних дисках —зчитувати чи записувати по зазначеній адресі (у координатах C-H-S) порцію даних. Хоча найчастіше програміст і не використовує пряму адресацію при роботі з магнітними дисками, а працює на рівні файлової системи. Однак у такому випадку вже розроблювачі файлової системи не повинні залежати від того, накопичувач якого конкретного типу і моделі, а також якого виробника використовується в даному конкретному комп'ютері (наприклад, HDD IBM DTLA 307030, WDAC 450AA чи який-небудь ще). Важливим повинний бути тільки сам факт існування накопичувача, що має деяку кількість циліндрів, голівок читання/запису і секторів на доріжці магнітного диска. Згадані значення кількості циліндрів, голівок і секторів повинні бути взяті з елемента таблиці устаткування. При цьому для програміста також не повинне мати значення, яким чином той чи інший пристрій підключений до обчислювальної системи, а не тільки яка конкретна модель пристрою використовується. Тому в запиті на ввід/вивід програміст вказує саме логічне ім'я пристрою. Дійсний пристрій, що зіставляється віртуальному (логічному), вибирається супервізором за допомогою таблиці, про яку ми зараз говоримо. Отже, спосіб підключення пристрою, його конкретна модель і відповідний їй драйвер містяться у вже розглянутій таблиці устаткування. Але для того, щоб зв'язати деякий віртуальний пристрій, використаний програмістом при створенні додатку із системною таблицею, що відображає інформацію про те, який конкретний пристрій і яким чином підключений до комп'ютера, використовується друга системна таблиця. Назвемо її умовно таблицею опису віртуальних логічних пристроїв (DRT, device reference table). Призначення цієї другої таблиці — встановлення зв'язку між віртуальними (логічними) пристроями і реальними пристроями, описаними за допомогою першої таблиці устаткування. Іншими словами, друга таблиця дозволяє супервізору перенаправляти запит на ввід/вивід з додатку на ті програмні модулі і структури даних, які (або адреси яких) зберігаються у відповідному елементі першої таблиці. У багатьох багатокористувацьких системах така таблиця не одна, а декілька: одна загальна і по одній — на кожного користувача, що дозволяє будувати необхідні зв'язки між логічними (символьними) іменами пристроїв і реальних фізичних пристроїв, що є в системі.

    Нарешті, третя таблиця необхідна для організації зворотного зв'язку між центральною частиною і пристроями вводу/виводу. Це таблиця переривань, що вказує для кожного сигналу запиту на переривання той елемент UCB, що співставлений даному пристрою, підключеному так, що воно використовує дійсну лінію (сигнал) переривання. Як системна таблиця вводу/виводу, таблиця переривань може в явному виді і не бути присутньою. В принципі можна відразу з основної таблиці переривань попадати на програму обробки (драйвер), що має зв'язки з елементом UCB. Важлива наявність зв'язку між сигналами переривань і таблицею устаткування.

    У сучасних складних ОС є набагато більше системних таблиць чи списків, використовуваних для організації процесів керування операціями вводу/виводу. Наприклад, однією з можливих і часто реалізованих інформаційних структур, що супроводжують практично кожен запит на ввід/вивід, є блок керування даними (data control block, DCB). Призначення цього DCB — підключення препроцесорів до процесу підготовки даних на ввід/вивід, тобто облік конкретних технічних характеристик і використовуваних перетворень. Це необхідно для того, щоб наявний пристрій одержував не якісь незрозумілі йому коди або формати даних, що не відповідають режиму його роботи, а коди, створені спеціально під даний пристрій і використовуваний у даний момент формат представлення даних.

    Взаємозв'язок між описаними таблицями зображені на рис.9.2.

    Рис.9.2 Взаємозв‘язок системних таблиць вводу/виводу.

    Тепер нам залишилося лише ще раз, з урахуванням викладених принципів і таблиць розглянути процес керування введенням/виведенням за допомогою рис.9.3.

    Рис.9.3 Процес управління вводом/виводом.

    Запит на операцію вводу/виводу від програми, що виконується, надходить на супервізор (дія 1). Той перевіряє системний виклик на відповідність прийнятим специфікаціям і у випадку помилки повертає задачі відповідне повідомлення (дія 1-1). Якщо ж запит коректний, то він перенаправляється в супервізор вводу/виводу (дія 2). Останній по логічному (віртуальному) імені за допомогою таблиці DRT знаходить відповідний елемент UCB у таблиці устаткування. Якщо пристрій уже зайнятий, то описувач задачі, запит якої зараз обробляється супервізором вводу/виводу, поміщаєте в список задач, що очікують дійсний пристрій. Якщо ж пристрій вільний, то супервізор вводу/виводу визначає з UCB тип пристрою і при необхідності запускає препроцесор, що дозволяє одержати послідовність керуючих кодів і даних, що зможе правильно зрозуміти і відробити пристрій (дія 3). Коли «програма» керування операцією вводу/виводу, буде готова, супервізор вводу/виводу передасть керування відповідному драйверу на секцію запуску (дія 4). Драйвер ініціалізує операцію керування, обнуляє лічильник тайм-ауту і повертає керування супервізору (диспетчеру задач) для того, щоб він поставив на процесор готову до виконання задачу (дія 5). Система працює своєю чергою, але коли пристрій вводу/виводу відробить послану йому команду, він виставляє сигнал запиту на переривання, по якому через таблицю переривань керування передається на секцію продовження (дія 6). Одержавши нову команду, пристрій знову починає її обробляти, а керування процесором знову передається диспетчеру задач, і процесор продовжує корисну роботу. Таким чином, виходить паралельна обробка задач, на тлі якої процесор здійснює керування операціями вводу/виводу.

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

    При описі цієї схеми ми не стали торкатись питань розподілу каналів, контролерів і власне самих пристроїв. Також були опущені деталі одержання канальних програм. Будемо вважати, що вони виходять за коло питань, розглянутих у підручнику по дисципліні «Системне програмне забезпечення».

    1. Синхронний і асинхронний ввід/вивід.

    Задача, що видала запит на операцію вводу/виводу, переводиться супервізором у стан чекання завершення замовленої операції. Коли супервізор одержує від секції завершення повідомлення про те, що операція завершилася, він переводить задачу в стан готовності до виконання, і вона продовжує свою роботу. Ця ситуація відповідає синхронному вводу/виводу. Синхронний ввід/вивід є стандартний для більшості ОС. Щоб збільшити швидкість виконання додатків, було запропоновано при необхідності використовувати асинхронний ввід/вивід.

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

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

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

    Апаратуру вводу/виводу можна розглядати як сукупність апаратури процесорів, що здатні працювати паралельно відносно один одного також щодо центрального процесора (процесорів). На таких «процесорах» виконуються так звані зовнішні процеси. Наприклад, для зовнішнього пристрою (пристрою вводу/виводу) зовнішній процес може являти собою сукупність операцій, що забезпечують переклад друкуючої голівки, просування паперу на одну позицію, зміну кольору чорнила чи друк якихось символів. Зовнішні процеси, використовуючи апаратуру вводу/виводу, взаємодіють як між собою, так і зі звичайними «програмними» процесами, що виконуються на центральному процесорі. Важливим при цьому є та обставина, що швидкості виконанні зовнішніх процесів будуть істотно (часом, па чи порядок більше) відрізнятися від швидкості виконання звичайних («внутрішніх») процесів. Для своєї нормальної роботи зовнішні і внутрішні процеси обов'язково повинні синхронізуватися. Для згладжування цього дефекту сильної невідповідності швидкостей між внутрішніми і зовнішніми процесами використовують згадане вище буферизація. Таким чином, можна говорити про систему рівнобіжних взаємодіючих процесів. Буфери є критичним ресурсом у відношенні внутрішніх (програмних) і зовнішніх процесів, що при рівнобіжному своєму розвитку информационно взаємодіють. Через буфер (буфери) дані або посилаються від деякого процесу до адресуемому зовнішнього (операція виведення даних на зовнішній пристрій), або від зовнішнього процесу передаються деякому програмному процесу (операція зчитування даних). Введення буферування як засобу інформаційної взаємодії висуває проблему в керування цими системними буферами, що зважується засобами супервізорної частини ОС. При цьому на супервізор покладаються задачі не тільки по виділенню і звільненню буферів у системній області пам'яті, але і синхронізації процесів відповідно до стану операцій по заповненню чи звільненню буферів, а також їхнього чекання, якщо вільних буферів у наявності немає, а запит на ввід/вивід вимагає буферування. Звичайно супервізор вводу/виводу для рішення перерахованих задач використовує стандартні засоби синхронізації, прийняті в даній ОС. Тому якщо ОС має розвинуті засоби для рішення проблем паралельного виконання взаємодіючих додатків і задач, то, як правило, вона реалізує й асинхронний ввід/вивід.

    6. Кешування операцій вводу/виводу при роботі з накопичувачами на магнітних дисках.

    Як відомо, накопичувачі на магнітних дисках мають вкрай низьку швидкість в порівнянні з швидкодією центральної частини комп'ютера. Різниця у швидкодії відрізняється на кілька порядків. Наприклад, сучасні процесори за один такт роботи, а вони працюють уже з частотами і 1 ГГц і більше, можуть виконувати по дві операції. Таким чином, час виконання операції (з позиції зовнішнього спостерігача, що не бачить конвеєризації при виконанні машинних команд, завдяки якій продуктивність зростає в кілька разів) може складати 0,5 нс (!). У той же час перехід магнітної голівки з доріжки на доріжку складає декілька мілісекунд. Такі ж тимчасові інтервали мають місце і при чеканні, поки під голівкою читання/запису не виявиться потрібний сектор даних. Як відомо, у сучасних приводах середня тривалість на читання випадковим чином обраного сектора даних складає близько 20 мс, що істотно повільніше, ніж вибірка команди чи операнда з оперативної пам'яті і тим більше з кешу. Правда, після цього дані читаються великим пакетом (сектор, як ми вже говорили, має розмір у 512 байтів, а при операціях з диском часто читається чи записується відразу кілька секторів). Таким чином, середня швидкість роботи процесора з оперативною пам'яттю на 2-3 порядки вище, ніж середня швидкість передачі даних із зовнішньої пам'яті на магнітних дисках в оперативну пам'ять.

    Для того щоб згладити таку сильну невідповідність у продуктивності основних підсистем, використовується буферизація і/чи кешування даних. Найпростішим варіантом прискорення дискових операцій читання даних можна вважати використання подвійного буферування. Його суть полягає в тім що поки в один буфер заносяться дані з магнітного диска, із другого буфера раніше зчитані дані можуть бути прочитані і передані їх задачі, що подавала запит на них. Аналогічний процес відбувається і при записі даних. Буферизація використовується у всіх операційних системах, але крім буферування застосовується і кешування. Кешування винятково корисно в тому випадку, коли програма неодноразово читає з диска ті самі дані. Після того як вони один раз будуть поміщені в кеш, звертань до диска більше не потрібно і швидкість роботи програми значно зросте.

    Якщо не вдаватися в подробиці, то під кешім можна розуміти деякий пул буферів, якими ми керуємо за допомогою відповідного системного процесу. Якщо ми зчитуємо якусь безліч секторів, що містять записи того чи іншого файлу, то ці дані, пройшовши через кеш, там залишаються (до тих пір поки інші сектори не замінять ці буфери). Якщо в наслідку буде потрібне повторне читання, то дані можуть бути витягнуті безпосередньо з оперативної пам'яті без фактичного звертання до диска. Прискорити можна й операції запису: дані поміщаються в кеш, і для задачі, що запросила цю операцію, можна вважати, що вони уже фактично і записані. Задача може продовжити своє виконання, а системні зовнішні процеси через якийсь час запишуть дані на диск. Це називається операцією відкладеного запису (lazy write «ледачий запис»). Якщо відкладений запис відключений, тільки одна задача може записувати на диск свої дані. Інші додатки повинні чекати своєї черги. Це чекання піддає інформацію ризику не меншому (якщо не більшому), чим відкладений запис, що до того ж і більш ефективний по швидкості роботи з диском.

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

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

    Отже, шлях інформації від диска до прикладної програми пролягає як через буфер, так і через файловий кеш. Коли додаток запитує з диска дані, програма кешування перехоплює цей запит і читає разом з необхідними секторами і ще декілька додаткових. Потім вона поміщає в буфер інформацію, яка потрібна задачі, і повідомляє про це операційну систему. Операційна система повідомляє задачі, що її запит виконаний і дані з диска знаходяться в буфері. При наступному звертанні додатка до диска програма кешування насамперед перевіряє, чи не знаходяться вже в пам'яті викликані дані. Якщо це так, то вона копіює їх у буфер; якщо ж їх у кеші немає, то запит на читання диска передається операційній системі. Коли задача змінює дані в буфері, вони копіюються в кеш. У ряді ОС є можливість вказати в явному виді параметри кешування, у той час як в інших за ці параметри відповідає сама ОС. Так, наприклад, у системі Windows NT немає можливості в явному виді керувати ні обсягом файлового кешу, ні параметрами кешування. У системах Windows 95/98 така можливість вже є, але вона представляє не дуже великий вибір. Фактично ми можемо вказати тільки обсяг пам'яті, що відводиться для кешування, і обсяг порції даних ( чи буфер chunk - шматочок), з яких набирається кеш. У файлі System.ini є можливість у секції [VCACHE] прописати, наприклад, наступні значення:

    [vcache]

    MinFileCache = 4096

    MaxFileCache = 32768

    ChunkSize = 512

    Тут зазначено, що мінімально під кешування даних зарезервовано 4 Мбайт оперативної пам'яті, максимальний обсяг кешу може досягати 32 Мбайт, а розмір даних, якими маніпулює менеджер кешу, рівний одному сектору.

    В інших ОС можна вквзувати більше параметрів, що визначають роботу підсистеми кешування. Приклад, що демонструє ці можливості, можна подивитися в розділі «Файлова система HPFS».

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

    • SSTF (shortest seek time — first) — з найменшим часом пошуку — першим. Відповідно до цієї дисципліни при позиціюванні магнітних голівок наступним вибирається запит, для якого необхідно мінімальне переміщення з циліндра на циліндр, навіть якщо цей запит не був першим у черзі на ввід/вивід. Однак для цієї дисципліни характерна різка дискримінація визначених запитів, але ж вони можуть йти від високопріоритетних задач. Звертання до диска виявляють тенденцію концентруватися, у результаті чого запити на звертання до самих зовнішніх і самих внутрішніх доріжок можуть обслуговуватися істотно довше і немає ніякої гарантії обслуговування. Достоїнством такої дисципліни є максимально можлива пропускна здатність дискової підсистеми.

    • Scan (сканування). По цій дисципліні голівки переміщаються то в одному то в іншому «привілейованому» напрямку, обслуговуючи «по шляху» придатні запити. Якщо при переміщенні голівок читання/запису більш немає побіжних запитів, то рух починається в зворотному напрямку.

    • Next-Step Scan — відрізняється від попередньої дисципліни тим, що на кожнім проході обслуговуються тільки запити, що вже існували на момент початку проходу. Нові запити, що з'являються в процесі переміщення голівок читання/запису, формують нову чергу запитів, причому таким чином, щоб їх можна було оптимально обслужити на зворотному ходу.

    • C-Scan (циклічне сканування). По цій дисципліні голівки переміщаються циклічно із самої зовнішньої доріжки до внутрішніх, але по шляху обслуговуючи наявні запити, після чого знову переносяться до зовнішніх циліндрів. Цю дисципліну іноді реалізують таким чином, щоб запити, що надходять під час поточного прямого ходу голівок, обслуговувалися не попутно, а при наступному ході, що дозволяє виключити дискримінацію запитів до самих крайніх циліндрів; вона характеризується дуже малою дисперсією часу чекання обслуговування. Цю дисципліну обслуговування часто називають «елеваторною».

    Тема 10.Організація файлових систем.

    1. Функції файлової системи ОС і ієрархія даних.

    2. Головний завантажувальний запис диску.

    3. Таблиця розділів.

    4. Розбиття диску на розділи.

    5. Основні утиліти ОС Windows для розбиття диску на розділи.

    Функції файлової системи ОС і ієрархія даних.

    Нагадаємо, що під файлом звичайно розуміють набір даних, організованих у виді сукупності записів однакової структури. Для керування цими даними створюються відповідні системи керування файлами. Можливість мати справу з логічним рівнем структури даних і операцій, виконуваних над ними в процесі їхньої обробки, надає файлова система. Таким чином, файлова система — це набір специфікацій і відповідне їм програмне забезпечення, що відповідають за створення, знищення, організацію, читання, запис, модифікацію і переміщення файлової інформації, а також за керування доступом до файлів і за керування ресурсами, що використовуються файлами. Саме файлова система визначає спосіб організації даних на диску чи на якому-небудь іншому носії даних. Як приклад можна привести файлову систему FAT, реалізація для якої є в абсолютній більшості ОС, що працюють у сучасних ПК.

    Як правило, усі сучасні ОС мають відповідні системи керування файлами. Надалі постараємося розрізняти файлову систему і систему керування файлами.

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

    • створення, видалення, перейменування (і інші операції) іменованих наборів даних (іменованих файлів) зі своїх програм чи за допомогою спеціальних керуючих програм, що реалізують функції інтерфейсу користувача з його даними й активно використовують систему керування файлами;

    • робота з не дисковими периферійними пристроями як з файлами;

    • обмін даними між файлами, між пристроями, між файлом і пристроєм (і навпаки);

    • робота з файлами за допомогою звертань до програмних модулів системи керування файлами (частина API орієнтована саме на роботу з файлами);

    • захист файлів від несанкціонованого доступу.

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

    Іншими словами, термін «файлова система» визначає, насамперед, принципи доступу до даних, організованих у файли. Цей же термін часто використовують і стосовно конкретних файлів, розташованих на тім чи іншім носії даних. А термін «система керування файлами» варто вживати стосовно конкретної реалізації файлової системи, тобто це — комплекс програмних модулів, що забезпечують роботу з файлами в конкретній операційній системі.

    Потрібно ще раз відмітити, що будь-яка система керування файлами не існує сама по собі — вона розроблена для роботи в конкретній ОС. Як приклад можна сказати, що усім відома файлова система FAT (file allocation table) має безліч реалізацій як система керування файлами. Так, система, що одержала цю назву і розроблена для перших персональних комп'ютерів, називалася просто FAT (зараз її називають FAT-12). Її розробляли для роботи з дискетами, і якийсь час вона використовувалася при роботі з жорсткими дисками. Потім її удосконалили для роботи з жорсткими дисками більшого об’єму, і ця нова реалізація одержала назву FAT-16. Цю назву файлової системи ми використовуємо і стосовно системи керування файлами самої MS-DOS. Реалізацію же системи керування файлами для OS/2, що використовує основні принципи системи FAT, називають super-FAT; основна відмінність — можливістъ підтримувати для кожного файлу розширені атрибути. Є версія системи керування файлами з принципами FAT і для Windows 9.1/98, для Windows NT і т.д. Іншими словами, для роботи з файлами, організованими відповідно до деякої файлової системи, для кожної ОС повинна бути розроблена відповідна система керування файлами. Ця система керування файлами буде працювати тільки в тієї ОС, для якої вона і створена; але при цьому вона дозволить працювати з файлами, створеними за допомогою системи керування файлами інший ОС, що працює по тим же основним принципам файлової системи.

    Структура магнітного диска (розбивка дисків на розділи).

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

    Як відомо, інформація на магнітних дисках розміщається і передається блоками. Кожен такий блок називається сектором (sector), сектори розташовані на концентричних доріжках поверхні диска. Кожна доріжка (track) утвориться при обертанні магнітного диска під зафіксованою в деякім визначеному положенні голівкою читання/запису. Накопичувач на жорстких магнітних дисках (НЖМД) містить один чи більше дисків (у сучасних розповсюджених НЖМД часто — два чи три). Однак звичайно під терміном «жорсткий диск» розуміють весь пакет магнітних дисків. Групи доріжок (треків) одного радіуса, розташованих на поверхнях магнітних дисків, утворять так звані циліндри (cylinder). Сучасні жорсткі диски можуть мати кілька десятків тисяч циліндрів, у той час як на поверхні дискети число доріжок (число циліндрів) нині, як правило, складає всього вісімдесят.

    Кожен сектор складається з поля даних і поля службової інформації, що обмежує й ідентифікує його. Розмір сектора (точніше — ємність поля даних) встановлюється контролером чи драйвером. Користувальницький інтерфейс DOS підтримує єдиний розмір сектора — 512 байт. BIOS же безпосередньо надає можливості роботи із секторами розміром 128, 256, 512 чи 1024 байт. Якщо керувати контролером безпосередньо, а не через програмний інтерфейс більш високого рівня (наприклад, рівень DOS), то можна обробляти сектори і з іншими розмірами. Однак у більшості сучасних ОС розмір сектора вибирається рівним 512 байт. Фізична адреса сектора на диску визначається за допомогою трьох «координат», тобто представляється тріадою [c-h-s], де c — номер циліндра (доріжки на поверхні диска, cylinder), h — помер робочої поверхні диска (магнітної голівки, head), а s — номер сектора на доріжці. Номер циліндра c лежить у діапазоні 0..C-1, де C — кількість циліндрів. Номер робочої поверхні диска h належить діапазону 0..Н-1, де Н — число магнітних голівок у накопичувачі. Номер сектора на доріжці s вказується в діапазоні 1..S, де S — кількість секторів на доріжці. Наприклад, тріада [1-0-2] адресує сектор 2 на доріжці 0 (звичайно верхня робоча поверхня) циліндра 1. Надалі ми теж будемо користуватися саме цими позначеннями.

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

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

    Розділи диска можуть бути двох типівprimary (звичайно цей термін переводять як первинний) і extended (розширений). Максимальне число primary розділів дорівнює чотирьом. При цьому на диску обов'язково повинний бути принаймні один primary-розділ. Якщо primary-розділів декілька, то тільки один з них може бути активним. Саме завантажнику, розташованому в активному розділі, передається керування при включенні комп'ютера і завантаженню операційної системи. Інші primary-розділи в цьому випадку вважаються «невидимими, схованими» (hidden).

    Відповідно до специфікацій на одному жорсткому диску може бути тільки один extended - розділ, що, у свою чергу, може бути розділений на велику кількість підрозділів — логічних дисків (logical). У цьому змісті термін «первинний» варто визнати не зовсім вдалим перекладом слова primary; можна це слово перевести і як «найпростіший, примітивний». У цьому випадку стає зрозумілим і логічним термін extended.

    Один з primary-розділів повинний бути активним, саме з його повинна завантажувати програма завантаження операційної системи, чи так званий менеджер завантаження, призначення якого — завантажити програму завантаження ОС з якого-небудь іншого розділу, і вже з її допомогою завантажувати операційну систему. Оскільки до завантаження ОС система керування файлами працювати не може, то варто використовувати для вказівки згаданих завантажників винятково абсолютні адреси у форматі [c-h-s].

    По фізичній адресі [0-0-1] на вінчестері розташовується головний завантажувальний запис (master hoot record, MBR), що містить позасистемний завантажник (non-system bootstrap — NSB), а також таблицю розділів (partition table, FT). Цей запис займає рівно один сектор, вона розміщується в пам'яті, починаючи з адреси 0:7C00h, після чого керування передається коду, що міститься в цьому найпершому секторі магнітного диска. Таким чином, у найпершому (стартовому) секторі фізичного жорсткого диска знаходиться не звичайний запис boot record, як на дискеті, a master boot record.

    MBR є основним засобом завантаження з жорсткого диска, підтримуваним BIOS. У MBR знаходяться три важливих елементи:

    • програма початкового завантаження (non-system bootstrap). Саме вона запускається BIOS після успішного завантаження в пам'ять першого сектора з MBR. Вона, мабуть, не перевищує 512 байт і її вистачає тільки на те, щоб завантажити наступну, трохи більш складну програму, звичайно — стартовий сектор операційної системи — і передати йому керування;

    • таблиця опису розділів диска (partition table). Розташовується в MBR по зсуві Ox1BE і займає 64 байта;

    • сигнатура MBR. Останні два байти MBR повинні містити число AA55h. По наявності цієї сигнатури BIOS перевіряє, що перший блок був завантажений успішно. Сигнатура ця обрана не випадково. Її успішна перевірка дозволяє установити, що всі лінії передачі даних можуть передавати і нулі, і одиниці.

    Таблиця partition table описує розміщення і характеристики наявних на вінчестері розділів. Можна сказати, що ця таблиця розділів — одна з найбільш важливих структур даних на жорсткому диску. Якщо ця таблиця ушкоджена, то не тільки не буде завантажуватися операційна система (чи одна з операційних систем, встановлених на вінчестері), але перестануть бути доступними і дані, розташовані на вінчестері, особливо якщо жорсткий диск був розбитий на кілька розділів.

    Зміщення (Offset)

    Розмір

    (Sise)(байт)

    Вміст (Contents)

    0

    446

    Програма аналізу Partition Table і загрузки System Bootstrap з активного розділу жорсткого диску

    +1BEh

    16

    Partition 1 entry (Описувач розділу)

    +1CEh

    16

    Partition 2 entry

    +1DEh

    16

    Partition 3 entry

    +1EEh

    16

    Partition 3 entry

    +1FEh

    16

    Сигнатура (АА55Н)

    Рис.10.4. Структура MBR.

    Спрощено структура MBR представлена на рис.10.4. З неї видно, що на початку цього сектора розташовується програма аналізу таблиці розділів і читання першого сектора з активного розділу диска. Сама таблиця partition table - розташовується наприкінці MBR, і для опису кожного розділу в цій таблиці приділяється по 16 байтів. Першим байтом в елементі розділу йде прапор активності розділу boot indicator (0 - не активна, 128 (80Н) - активний). Він служить для визначення, чи є розділ системним завантажувальним і чи є необхідність робити завантаження операційної системи з нього при старті комп'ютера. Активним може бути тільки один розділ. За прапором активності розділу іде байт номера голівки, з яким починається розділ. За ним ідуть два байти, що означають відповідно номер сектора і номер циліндра завантажувального сектора, де розташовується перший сектор завантажника операційної системи. Потім іде кодовий ідентифікатор System ID (довжиною в один байт), що вказує на приналежність даного розділу до тієї чи іншої операційної системи й установки на ньому відповідної файлової системи. У табл.10.1 приведені деякі (найбільш відомі) ідентифікатори.

    Таблиця 10.1. Сигнатури (типи) розділів

    System ID

    Тип розділу

    System ID

    Тип розділу

    00

    Empty («пустий» розділ)

    41

    PPC PreP Boot

    01

    FAT 12

    42

    SFS

    02

    XENIX root

    4D

    QNX 4.x

    03

    XENIX usr

    4E

    QNX 4.x 2nd part

    04

    FAT 16 (<32 Мбайт)

    4F

    QNX 4.x 3nd part

    05

    Extended

    50

    OnTrack DM

    06

    FAT 16

    51

    OnTrack DM6 Aux

    07

    HPFS/NTFS

    52

    CP/M

    08

    AIX

    53

    OnTrack DM6

    09

    AIX bootable

    54

    OnTrack DM6

    0A

    OS/2 Boot Manager

    55

    EZ Drive

    0B

    Win95 FAT32

    56

    Golden Bou

    Win95 FAT32 LBA

    5C

    Priam Edisk

    0E

    Win95 FAT 16 LBA

    61

    Speed Stor

    0F

    Win95 Extended

    64

    Novell Netware

    10

    OPUS

    65

    Novell Netware

    11

    Hidden FAT12

    75

    PC/1X

    12

    Compaq diagnost

    80

    Old Minix

    14

    Hidden FAT16 (<32 Мбайт)

    82

    Linux swap

    16

    Hidden FAT16

    83

    Linux native

    17

    Hidden HPFS/NTFS

    84

    OS/2 hidden C:

    18

    AST Windows swap

    85

    Linux Extended

    1B

    Hidden Win95 Fat

    86

    NTFS volume set

    1C

    Hidden Win95 Fat

    A5

    BSD/386

    IE

    Hidden Win95 Fat

    A6

    Open BSD

    24

    NEC DOS

    A7

    Next Step

    3C

    Partition Magic

    EB

    Be OS

    40

    Venix 8028G

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

    Таблиця 10.2 Формат елемента таблиці розділів.

    Назва запису елемента Partition Table

    Довжина, байт

    Флаг активності розділу

    1

    Номер головки початку розділу

    1

    Номер сектора і номер циліндра завантажуючого сектору розділу

    2

    Кодовий ідентифікатор операційної системи

    1

    Номер головки кінця розділу

    1

    Номер сектора і циліндра останнього сектора розділу

    2

    Молодше і старше двухбайтове слово відносного номера сектора

    4

    Молодше і старше двухбайтове слово розміру розділу в секторах

    4

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

    Як ми вже сказали, завантажник non-system bootstrap служить для пошуку за допомогою partition table активного розділу, копіювання в оперативну пам'ять комп'ютера завантажника system bootstrap з обраного розділу і передачі йому керування, що дозволяє здійснити завантаження ОС.

    Слідом за сектором MBR розмішаються власне самі розділи (рис.10.5). У процесі початкового завантаження сектора MBR, що містить таблицю partition table, працюють програмні модулі BIOS. Початкове завантаження вважається виконано коректно тільки в тому випадку, коли таблиця розділів містить припустиму інформацію.

    У MS-DOS і первинному розділі може бути сформований тільки один логічний диск, а в розширеному – будь-яку їхню кількість. Кожен логічний диск «керується» своїм логічним приводом. Кожному логічному диску на вінчестері відповідає своя (відносна) логічна нумерація. Фізична ж адресація жорсткого диска наскрізна.

    Первинний розділ DOS включає тільки системний логічний диск без яких-небудь додаткових інформаційних структур.

    Рис. 10.5. Розбивка диска на розділи

    Розширений розділ DOS містить вторинний запис MBR (secondary MBR SMBR), до складу якого замість partition table входить таблиця логічного диска (LDT, logical disk table), їй аналогічна. Таблиця LDT описує розміщення і характеристики розділу, що містить єдиний логічний диск, а також може специфікувати наступний запис SMBR. Отже, якщо в розширеному розділі DOS створено K логічних дисків, то він містить K екземплярів SMBR, зв'язаних у список. Кожен елемент цього списку описує відповідний логічний диск і посилається (крім останнього) на наступний елемент списку.

    Утиліти, що дозволяють розбити диск на розділи і тим самим сформувати як partition table, так і, можливо, спискову структуру з LDT (подібно тому як це зображено на рис.10.6), звичайно називаються FDISK (від form disk), хоча мережа утиліти і з іншою назвою, що вміють виконати розбивку диска. Нагадаємо, що FD1SK від MS-DOS дозволяє створити тільки один primary-розділ і один extended, що, у свою чергу, пропонується розділити на кілька логічних дисків. Аналогічні утиліти інших ОС мають істотно більше можливостей. Так, наприклад. FDISK системи OS/2 дозволяє створювати кілька primary-розділів, причому їх можна виділяти не тільки послідовно, починаючи з перших циліндрів, але і з кінця вільного дискового простору. Це зручно, якщо потрібно виключити з роботи деякий діапазон дискового простору (наприклад, через дефекти на поверхні магнітного диска). За допомогою цієї утиліти можна установити і менеджер завантаження (boot-менеджер).

    Перш ніж перейти до boot-менеджерів, розглянемо ще раз процес завантаження ОС. Процедура початкового завантаження (bootstrap loader) викликається як програмне переривання (BIOS INT 19h). Ця процедура визначає перший готовий пристрій зі списку дозволених і доступних (гнучкий чи жорсткий диск, у сучасних комп'ютерах це можуть бути також CD-ROM, привод ZIP-drive компанії iomega, мережний адаптер чи інший пристрій) і намагається завантажити з нього в ОЗУ коротку головну програму-завантажник. Для вінчестерів — це завантажник non-system bootstrap з MBR, і йому передається керування. Головний завантажник визначає на диску активний розділ, завантажує його власний завантажник (system bootstrap) і передає керування йому. І, нарешті, цей завантажник завантажує необхідні файли операційної системи і передає їй керування. Далі операційна система виконує ініціалізацію підвідомчих їй програмних і апаратних засобів. Вона додає нові сервіси, викликаємі, як правило, теж через механізм програмних переривань, і розширює (чи заміняє) деякі сервіси BIOS. Необхідно відзначити, що в сучасних мультипрограмних операційних системах більшість сервісів BIOS, споконвічно розташованих в ПЗУ, як правило, заміняються власними драйверами, оскільки вони повинні працювати в режимі переривань, а не в режимі сканування готовності.

    Відповідно розглянутому процесу завантаження, ми ще раз при запуску комп'ютера будемо попадати в ту саму ОС. Але іноді це нас не влаштовує. Так звані boot-менеджери (менеджери завантаження) призначені для того, щоб користувач міг вибрати серед декількох установлених на комп'ютері ОС потрібну і передати керування завантажнику цієї обраної ОС. Існує велика кількість таких менеджерів. На наш погляд, одним із кращих довгий час був Boot manager компанії IBM, що входить до складу утиліт OS/2. Для його розміщення створюється окремий primary-розділ, що, природно, і є активним (він позначається як startable). Розділ для Boot-менеджера OS/2 займає всього один циліндр і може розміщатися не тільки на нульовому (початковому) циліндрі, але і на останньому циліндрі. У цьому розділі не організується ніякої файлової системи, оскільки звертання до менеджера йде з використанням абсолютної адресації, а сам Boot manager являє собою найпростішу абсолютну двійкову програму. Установка Boot manager здійснюється з програми FDISK. При цьому з'являється можливість вказати, які розділи можуть бути завантажуваними (вони позначаються як bootable), тобто в яких розділах на першому логічному секторі будуть розміщені програми завантаження ОС. Завантажуючими можуть бути як primary-, так і extended-розділи. При цьому, природно, є можливість вказати як час на ухвалення рішення, так і завантаження деякої ОС «за замовчуванням». Зручним є і те, що при розбивці диска на розділи можна взагалі не створювати primary-розділів. Це особливо важливо, якщо в комп'ютері встановлено більш одного дискового накопичувача або якщо ми підготовляємо вінчестер, що повинний досить часто переноситися з одного комп'ютера на іншій. Справа в тім, що в більшості ОС прийняте наступне правило іменування логічних дисків: перший логічний диск позначається літерою C: другий — D: і т.д. При цьому літеру C: одержує активний primary розділ. Однак якщо до одного вінчестера в персональному комп'ютері підключити другий вінчестер і він теж має активний primary-розділ, то цей primary-розділ другого вінчестера одержить літеру D:, відсуваючи логічний диск D: першого вінчестера на місце диска Е: (і т.д. по ланцюжку). Якщо ж другий (і наступні) вінчестер не має primary-розділу з встановленої на ньому файловою системою, яку дана ОС знає, то «іменування» логічних дисків першого вінчестера не порушується. Природно, що логічні диски другого вінчестера одержують літери логічних дисків слідом за дисками першого вінчестера Boot manager OS/2, створюючи тільки логічні диски на вінчестері, насправді створює і «порожній» primary-розділ, однак цей розділ не стає активним і не одержує статус логічного диска. На жаль, усе більш популярна в наші дні ОС Windows 2000 тепер не тільки знімає прапор активності з розділу, у якому розміщений Boot manager (як це відбувалося при інсталяції будь-яких ОС від компанії Microsoft), але і фізично знищує його двійковий код. Заміна драйвера FASTFAT.SYS системи Windows 2000 на більш ранню версію (у бета-версії ОС Windows 2000 система не знищувала код Boot manager) допомагає лише до установки Service pack. Тому рекомендувати цей менеджер завантаження вже не можна. З останніх менеджерів завантаження, мабуть, найбільш могутнім є Boot star, але його не можна рекомендувати непідготовленим користувачам.

    Однієї з найвідоміших і дотепер досить часто використовуваних утиліт за допомогою якої можна подивитися і відредагувати таблицю розділів а також виконати й інші дії, зв'язані з вивченням і виправленням даних як на дискеті, так і на вінчестері, є програма Disk editor з комплекту нортоновских утиліт. Потрібно відмітити, що Disk editor, з одного боку, дуже могутній засіб, і тому його варто використовувати з великою обережністю, а з іншого боку - ця утиліта працює тільки в середовищі DOS. На сьогоднішній день головним недоліком цієї утиліти є обмеження на максимальний розмір диска в 8 Гбайт.

    Треба визнати, що останнім часом з'явилася велика кількість утиліт які надають можливість більш наочно представити розбивку диска на розділи, оскільки в них використовується графічний інтерфейс. Ці програми успішно і коректно працюють з найбільш розповсюдженими типами розділів (розділи під FAT, FAT32, NTFS). Однак створені вони в основному для роботи в середовищі Win32API, що часто обмежує можливість їхнього використання. Однією з найвідоміших і могутніх програм для роботи з розділами жорсткого диска є Partition Magic фірми Power Quest

    Тема 11. Файлові системи fat, vfat, fat32, hpfs.

    1. Файлова система FAT.

    2. Таблиці розміщення розділів.

    3. Структура завантажувального запису.

    4. Файлова система VFAT.

    5. Файлова система FAT32.

    6. Атрибути файлів.

    7. Файлова система HPFS.

    Файлова система FAT.

    Як ми уже відзначали, абревіатура FAT (file allocation table) розшифровується як «таблиця розміщення файлів». Цей термін відноситься до лінійної табличної структури зі зведеннями про файли — іменами файлів, їхніми атрибутами й іншими даними, що визначають місцезнаходження файлів (чи їхніх фрагментів) у середовищі FAT. Елемент FAT визначає фактичну область диска, у якій зберігається початок фізичного файлу.

    У файловій системі FAT логічний дисковий простір будь-якого логічного диска поділяється на дві області (рис.10.6): системну область і область даних.

    Рис.10.6. Структура логічного диску

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

    • завантажуючого запису (boot record, BR);

    • зарезервованих секторів (reserved sector, ResSecs);

    • таблиці розміщення файлів (file allocation table, FAT);

    • кореневого каталогу (root directory, Rdir).

    Таблиця розміщення файлів.

    Таблиця розміщення файлів є дуже важливою інформаційною структурою. Можна сказати, що вона представляє собою карту (образ) області даних, у якій описується стан кожної частини області даних. Область даних розбивають на так звані кластери. Кластер представляє собою один або декілька суміжних секторів у логічному дисковому адресному просторі (точніше – тільки в області даних). У таблиці FAT кластери, які належать одному файлу (не кореневому каталогу), зв'язуються в ланцюги. Для вказівки номера кластера в системі управління файлами FAT-16 використовується 16-бітове слово, з цього виходить, що можна мати до 216=65536 кластерів (з номерами від 0 до 65535).

    Кластер – це мінімальна адресуєма одиниця дискової пам‘яті, яка виділяється файлу (чи не кореневому каталогу). Файл чи каталог займає ціле число кластерів. Останній кластер при цьому може бути задіяний не цілком, що приведе до помітної втрати дискового простору при великому розмірі кластера. На дискетах кластер займає один чи два сектори, а на жорстких дисках — у залежності від обсягу розділу (див. табл. 10.3).

    Таблиця 10.3. Співвідношення між розміром розділу і розміром кластерів у FAT16

    Об‘єм розділу, Мбайт

    Кількість секторів в кластері

    Розмір кластерів, Кбайт

    16-127

    4

    2

    128-255

    8

    4

    256-511

    16

    8

    512-1023

    32

    16

    1024-2047

    64

    32

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

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

    Однак занадто великий розмір кластера веде до неефективного використання області даних, особливо у випадку великої кількості маленьких файлів. Як ми тільки що помітили, у середньому на кожен файл губиться біля половини кластера. З табл. 4.3 випливає, що при розмірі кластера в 32 сектори (обсяг розділу - від 512 Мбайт до 1023 Мбайт), тобто 16 Кбайт, середня величина втрат на файл складе 8 Кбайт, і при числі файлів у кілька тисяч втрати можуть складати більше 100 Мбайт. Тому в сучасних файлових системах (до них, насамперед, варто віднести HPFS, NTFS, FAT32 і деякі інші, підтримувані ОС сімейства UNIX) розміри кластерів обмежуються (звичайно - від 512 байт до 4 Кбайт). У FAT32 проблема зважується за рахунок того, що власне сама FAT у цій файловій системі може містити до 228 кластерів. Нарешті, помітимо, що системи керування файлами, створені для Windows 9х і Windows NT, можуть працювати з роздачами розміром до 4 Гбайт, на яких встановлена система FAT, тоді як DOS, природно, з такими розділами працювати не зможе.

    Досить наочно ідея файлової системи з використанням таблиці розміщення файлів FAT проілюстрована мал. 4.7. З цього малюнка видно, що файл з ім'ям MYFILE.TXT розміщається починаючи з восьмого кластера. Усього файл MYFILE.TXT займає 12 кластерів. Ланцюжок кластерів (chain) для нашого прикладу може бути записаний в такий спосіб: 8, 9, 0А, 0В, 15, 16, 17, 19, 1А, 1В, 1C, ID. Кластер з номером 18 позначений спеціальним кодом F7 як поганий (bad), він не може бути використаний для розміщення даних. При форматуванні звичайно перевіряється поверхня магнітного диска, і ті сектори, при контрольному читанні з який відбувалися помилки, позначаються в FAT як погані. Кластер ID позначений кодом FF як кінцевий (останній у ланцюжку) кластер, що належить даному файлу. Вільні (незайняті) кластери позначаються кодом 00; при виділенні нового кластера для запису файлу береться перший вільний, кластер. Оскільки файли на диску змінюються — знищуютьсяся, переміщаються, збільшуються чи зменшуються, — то згадане правило виділення першого вільного кластера для нової порції даних приводить до фрагментації файлів, тобто дані одного файлу можуть розташовуватися не в суміжних кластерах, а, часом, в дуже віддалених один від одного, утворюючи складні ланцюжки. Природно, що це приводить до істотного уповільнення роботи з файлами.

    Рис.10.7. Основна концепція FAT

    Так, як FAT використовується при доступі до диска дуже інтенсивно, вона звичайно завантажується в ОЗУ (в буфери введення/виведення чи кеш) і залишається там настільки довго, наскільки це можливо.

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

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

    Таблиця 4.4. Елемент каталогу

    Розмір поля даних, байт

    Вміст поля

    11

    Ім‘я файлу чи каталогу

    1

    Атрибути файлу

    1

    Резервне поле

    3

    Час створення

    2

    Дата створення

    2

    Дата останнього доступу

    2

    Зарезервовано

    2

    Час останньої модифікації

    2

    Дата останньої модифікації

    2

    Номер початкового кластера в FAT

    4

    Розмір файлу

    Структура системи файлів є ієрархічною. Це ілюструється рис.10.8, з якого видно, що елементом каталога може бути такий файл, який сам, в свою чергу, являється каталогом.

    Рис. 10.8 Структура системи файлів.

    Структура завантажуючого запису DOS.

    Сектор, який містить завантажуючий запис, являється самим першимна логічному диску (на дискеті – має фізичний адрес [0-1-1]). Boot Record складається, як ми вже знаєм, з двух частин – disk parameter block (DPB) і system bootstrap (SB). Структура блоку параметрів диску (DPB) служить для ідентифікації фізичного і логічного форматів логічного диску, а загрузчик system bootstrap грає суттєву роль в процесі загрузки DOS. Ця інформаційна структура приведена в табл.4.5.

    Таблиця 4.5. Структура завантажуючого запису Boot Record для FAT16

    Зміщення поля, байт

    Довжина поля, байт

    Позначення поля

    Вміст поля

    00Н (0)

    з

    JUMP3EH

    Безумовний перехід на початок SB

    03Н (3)

    8

    Системний iдентифікатор

    0ВН (11)

    2

    SectSize

    Розмір сектора, байт

    0DН (13)

    1

    ClastSize

    Число секторів в кластері

    0EН (14)

    2

    ResSecs

    Число зарезервованих секторів

    10Н (16)

    1

    FATcnt

    Число копій FAT

    11H(17)

    2

    RootSize

    Максимальне число елементів Rdir

    13Н (19)

    2

    TotSecs

    Число секторів на логічному диску, якщо його розмір не перевищує 32 Мбайт інакше ООООН

    15Н (21)

    1

    Media

    Дескриптор носія __

    16H (22)

    2

    FATsize

    Розмір FAT, секторів

    18H (24)

    2

    TrkSecs

    Число секторів на доріжці __

    1AН (26)

    2

    HcadCnt

    Число робочих поверхонь

    1СН (28)

    4

    HidnSccs

    Число скритих секторів

    20Н (32)

    4

    Число секторів на логічному диску, якщо його розмір перевищує 32 Мбайт

    24H (36)

    1

    Тип логічного диску(ООН гнучкий, 80H -орсткий)

    25H (37)

    1

    Пусто (резерв)

    26 H (38)

    1

    Маркер з кодом 29H

    27H (39)

    4

    Серійний номер тому

    2BH(43)

    Мітка тому

    36Н (54)

    8

    Ім‘я файлової системи

    3ЕН (62)

    System bootstrap

    1FEH(510)

    2

    Сигнатура (слово АА55Н)

    Перші два байти boot record займає JMP — команда безумовного переходу в програму SB. Третій байт містить код 90Н (NOP — немає операції). Далі розташовується восьмибайтовый системний ідентифікатор, що включає інформацію про фірму-розроблювача і версію операційної системи. Потім слідує DPB, а після нього — SB.

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

    Завантажувальні записи інших операційних систем відрізняються від розглянутої. Так, наприклад, у завантажувальному секторі для тому з FAT32 у блоці DPB містяться додаткові поля, а ті поля, що знаходяться в звичному для системи FAT16 місці, перенесені. Тому ОС, у якій є можливість працювати з файловою системою FAT16, але немає системи керування файлами, що розуміє специфікації FAT32, не може читати дані з томів, відформатованих під файлову систему FAT32. У завантажувальному секторі для файлової системи FAT32 як і раніше байти 00Н по 0АН містять команду переходу і OEM ID, а в байтах 0ВН по 59Н містяться дані блоку DPB. Відмінність полягає саме в іншій структурі блоку DBP; його вміст приведений у табл. 4.6.

    Таблиця 4.6. Структура завантажувального запису boot record для FAT32

    Зміщення поля, байт

    Довжина поля, байт

    Позначення поля

    Вміст поля

    00H(0)

    3

    JUMP 3EH

    Безумовний перехід на початок SB

    03H(3)

    8

    Системний ідентифікатор

    0BH(11)

    2

    SectSize

    Розмір сектора, байт

    0DH(13)

    1

    ClastSize

    Число секторів в кластері

    0EH(14)

    2

    ResSecs

    Число зарезервованих секторів, для FAT32 рівне 32

    10H(16)

    1

    FATent

    Число копій FAT

    11H(17)

    2

    RootSize

    0000H

    13H(19)

    2

    TotSecs

    0000H

    15H(21)

    1

    Media

    Дескриптор носія

    16H(22)

    2

    FATsize

    0000H

    18H(24)

    2

    TrkSecs

    Число секторів на доріжці

    1AH(26)

    2

    HeadCnt

    Число робочих поверхонь

    1CH(28)

    4

    HidnSecs

    Число скритих секторів (розташовуються перед завантажуючим сектором). Використовується при завантажені для обчислення абсолютного зміщення кореневого каталогу і даних

    20H(32)

    4

    Число секторів на логічному диску

    24H(36)

    4

    Число секторів в таблиці FAT

    28H(37)

    2

    Розширені флаги

    2AH(38)

    2

    Версія файлової системи

    2CH(39)

    4

    Номер кластера для першого кластера кореневого каталогу

    34H(43)

    2

    Номер сектору з резервною копією завантажуючого сектора

    36H(54)

    12

    Зарезервовано

    Файлові системи VFAT і FAT32.

    Однією з найважливіших характеристик вихідної FAT було використання імен файлів формату «8.3», у якому 8 символів приділяється на вказівку імені файлу і 3 символи - для розширення імені. До стандартного FAT (мається на увазі насамперед реалізація FAT16) додалися ще два різновиди, використовувані в широко розповсюджених операційних системах Microsoft (конкретно - у Windows 95 і Windows NT): VFAT (віртуальна FAT) і FAT32, використовувана в одній з редакцій ОС Windows 95 і Windows 98. Нині ця файлова система (FAT32) підтримується і такими ОС, як Windows Millennium Edition, і всіма ОС сімейства Windows 2000. Є реалізації систем керування файлами для FAT32, Windows NT і ОС Linux.

    Файлова система VFAT уперше з'явилася в Windows for Workgroups 3.11 і була призначена для виконання файлового введення/виведення в захищеному режимі. З виходом Windows 95 у VFAT додалася підтримка довгих імен файлів (long file name, LFN). Проте VFAT зберігає сумісність з вихідним варіантом FAT; це означає, що поряд з довгими іменами в ній підтримуються імена формату «8.3», а також існує спеціальний механізм для перетворення імен «8.3» у довгі імена, і навпаки. Саме файлова система VFAT підтримується вихідними версіями Windows 95, Windows NT 4. При роботі з VFAT вкрай важливо використовувати файлові утиліти, що підтримують VFAT взагалі і довгі імена зокрема. Справа в тім, що більш ранні файлові утиліти DOS запросто модифікують те, що здається їм вихідною структурою FAT. Це може привести до втрат чи псування довгих імен з таблиці FAT, підтримуваної VFAT (чи FAT32). Отже, для томів VFAT необхідно користуватись файловими утилітами, що розуміють і зберігають файлову структуру VFAT.

    У вихідній версії Windows 95 основною файловою системою була 32-розрядна VFAT. VFAT може використовувати 32-розрядні драйвери захищеного режиму чи 16-розрядні драйвери реального режиму. При цьому елементи FAT залишаються 12- чи 16-розрядними, тому на диску використовується та ж структура даних, що й у попередніх реалізаціях FAT. VFAT обробляє всі звертання до жорсткого диска і використовує 32-розрядний код для всіх файлових операцій з дисковими томами.

    Основними недоліками файлових систем FAT і VFAT є великі втрати на кластеризацию при великих розмірах логічного диска й обмеження на сам розмір логічного диска. Це привело до розробки нової реалізації файлової системи з використанням тієї ж ідеї використання таблиці FAT. Тому в Microsoft Windows 95 OEM Service Release 2 (ця версія Windows 95 часто називається Windows 95 OSR2) на зміну системі VFAT прийшла файлова система FAT32. FAT32 є цілком самостійною 32-розрядною файловою системою і містить численні удосконалення і доповнення в порівнянні з попередніми реалізаціями FAT.

    Принципова відмінність полягає в тім, що FAT32 набагато ефективніше витрачає дисковий простір. Насамперед, система FAT32 використовує кластери меншого розміру в порівнянні з попередніми версіями, що обмежувалися 65535 кластерами на том (відповідно, зі збільшенням розміру диска приходилося збільшувати і розмір кластерів). Отже, навіть для дисків розміром до 8 Гбайт FAT32 може використовувати 4-кілобайтні кластери. У результаті в порівнянні з дисками FAT16 заощаджується значний дисковий простір (у середньому 10-15%).

    FAT32 також може переміщати кореневий каталог і використовувати резервну копію FAT замість стандартної. Розширений завантажувальний запис FAT32 дозволяє створювати копії критичних структур даних; це підвищує стійкість дисків FAT32 до порушень структури FAT у порівнянні з попередніми версіями. Корнєвий каталог у FAT32 представлений у виді звичайного ланцюжка кластерів. Отже, кореневий каталог може знаходитися в довільному місці що знімає обмеження, що раніше діяло, на розмір кореневого каталогу (512 елементів).

    Windows 95 OSR2 і Windows 98 можуть працювати і з розділами VFAT, створеними Windows NT. To, що говорилося раніше про використання файлових утиліт VFAT з томами VFAT відноситься і до FAT32. Оскільки колишні утиліти FAT (для FAT32 у цю категорію входять обидві файлові системи, FAT і VFAT) можуть зашкодити чи знищити важливу службову інформацію, для томів FAT32 не можна користуватись ніякими файловими утилітами, крім утиліт FAT32. Крім підвищення ємкості FAT до величини в 4 Тбайт, файлова система FAT32 вносить ряд необхідних удосконалень у структуру кореневого каталогу. Попередні реалізації вимагали, щоб вся інформація кореневого каталогу FAT знаходилася в одному дисковому кластері. При цьому кореневий каталог міг містити не більш 512 файлів. Необхідність представляти довгі імена і забезпечити сумісність з колишніми версіями FAT привела розроблювачів компанії Microsoft до компромісного рішення: для представлення довгого імені вони стали використовувати елементи каталогу, у тому числі і кореневого. Розглянемо спосіб представлення в VFAT довгого імені файлу (мал. 10.9).

    Рис. 10.9. Елементи каталогів для FAT, VFAT і FAT32.

    Перші одинадцять бітів елемента каталогу DOS використовуються для збереження імені файлу. Кожне таке ім'я розділяється на дві частини: у перших восьми байтах зберігаються символи власне імені, а в останніх трьох — символи так званого розширення з допомогою якого реалізуються механізми визначених типів. Були уведені відповідні системні угоди, і файл; визначеного типу необхідно (бажано) іменувати з обговореним розширенням. Наприклад, файли, що виконуються з розширенням СОМ визначають двійкову програму, що виконується, з найпростішою односегментною структурою. Більш складні програми мають розширення ЕХЕ. Визначено розширення для великої кількості типів файлів, і ці розширення використовуються для асоційованого запуску оброблюючих файли програм.

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

    У дванадцятому байті елемента каталогу зберігаються атрибути файлу. Шість з восьми зазначених розрядів використовуються DOS. До атрибутів DOS відносяться наступні:

    • атрибут «архівний» (А — archive). Показує, що файл був відкритий програмою таким чином, щоб у неї була можливість змінити вміст цього файлу. DOS установлює цей розряд атрибута в стан ON (включено) при відкритті файлу. Програми резервного копіювання нерідко встановлюють його в OFF (виключено) при виконанні резервного копіювання файлу. Якщо застосовується подібна методика, то в наступну створювану по порядку резервну копію будуть додані тільки файли з даним розрядом, встановленим у стан ON;

    • атрибут каталогу (D- directory). Показує, що даний елемент каталогу вказує на підкаталог, а не на файл;

    • атрибут тому (V - volume). Застосовується тільки до одного елемента каталогу в кореневому каталозі. У ньому, власне, і зберігається ім'я дискового тому. Це атрибут також застосовується у випадку довгих імен файлів, про що можна буде довідатися з наступного розділу;

    • атрибут «системні» (S — system). Показує, що файл є частина операційної системи чи спеціально відзначений подібним чином прикладною програмою, що іноді робиться в якості складеної частини методу захисту від копіювання;

    • атрибут «схований» (Н — hidden). Сюди відносяться, зокрема, файли з встановленим у стан ON атрибутом «системний» (S), що не відображаються в звичайному списку, виведеному по команді DIR;

    • атрибут «тільки для читання» (R — read only). Показує, що даний файл не підлягає зміні. Зрозуміло, оскільки це лише розряд байта, що зберігається на диску, то будь-яка програма може змінити цей розряд, після чого DOS вільно дозволила би зміну даного файлу. Цей атрибут в основному використовується для примітивного захисту від користувацьких помилок, тобто він дозволяє уникнути ненавмисного видалення чи зміни ключових файлів.

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

    На дисках FAT12 чи FAT16 наступні за ім'ям десять байтів не використовуються. Звичайно вони заповнюються нулями і вважаються резервними значеннями. А на диску з файловою системою FAT32 ці 10 байт містять саму різну інформацію про файл. При цьому байт, відзначений як «зарезервовано для NT», являє собою, що видно з його назви, поле, не використовуване в DOS чи Windows 9х, але застосовуване в Windows NT.

    З поглядів сумісності поля, що зустрічаються в елементах каталогу для коротких імен формату FAT12 і FAT16, знаходяться на тих же місцях і в елементах каталогу для коротких імен формату FAT32. Інші поля, що зустрічаються тільки в елементах каталогу для коротких імен формату FAT32, відповідають зарезервованій області довжиною в десять байтів в елементах каталогу для коротких імен форматів FAT12 і FAT16.

    Як видно з мал.10.9, для довгого імені файлу використовується кілька елементів каталогу. Таким чином, поява довгих імен фактично привело до подальшого зменшення кількості файлів, що можуть знаходитися в кореневому каталозі. Оскільки довге ім'я може містити до 256 символів, всього один файл із повним довгим ім'ям займає до 25 елементів FAT (1 для імені 8.3 і ще 24 для самого довгого імені). Кількість елементів кореневого каталогу VFAT зменшується до 21. Очевидно, що це не саме витончене рішення, тому компанія Microsoft радить уникати довгих імен у кореневих каталогах FAT при відсутності FAT32, у якого кількість елементів каталогу відповідно просто збільшений. Пам‘ятайте і про те, що довжина повної файлової специфікації, що включає шлях і ім'я файлу (довге чи у форматі 8.3), теж обмежується 260 символами. FAT32 успішно справляється з проблемою довгих імен у кореневому каталозі, але проблема з обмеженням довжини повної файлової специфікації залишається. З цієї причини Microsoft рекомендує обмежувати довгі імена 75-80 символами, щоб залишити досить місця для шляху (180-185 символів).

    Файлова система HPFS.

    Скорочення HPFS розшифровується як «High Performance File System» — високопродуктивна файлова система. HPFS уперше з'явилася в OS/2 1.2 і LAN Manager. HPFS була розроблена спільними зусиллями кращих фахівців компанії IBM і Microsoft на основі досвіду IBM по створенню файлових систем MVS, VM/CMS і віртуального методу доступу. Архітектура HPFS-початку створюватися як файлова система, що зможе використовувати переваги багатозадачного режиму і забезпечить у майбутньому більш ефективну і надійну роботу з файлами на дисках великого обсягу.

    HPFS була першою файловою системою для ПК, у якій була реалізована підтримка довгих імен. HPFS, як FAT і багато інших файлових систем, має структуру каталогів, але в ній також передбачені автоматичне сортування каталогів і спеціальних розширених атрибутів, що спрощують реалізацію безпеки файлового рівня і створення множинних імен. HPFS підтримує ті ж самі атрибути, що і файлова система FAT, по історичних причинах, але також підтримує і нову форму file-associated, тобто інформацію, так звану розширеними атрибутами (EAs). Кожен ЕА концептуально подібний змінній оточення. Але самою головною відмінністю все-таки є базові принципи збереження інформації про місце розташування файлів.

    Принципи розміщення файлів на диску, покладені в основу HPFS, збільшують як продуктивність файлової системи, так і її надійність і відмовостійкість. Для досягнення цих цілей запропоновано кілька способів: розміщення каталогів у середині дискового простору, використання методів бінарних збалансованих дерев для прискорення пошуку інформації про файл, розосередження інформації про місце розташування записів файлів по всьому диску, при тім що записи кожного конкретного файлу розміщаються (по можливості) у суміжних секторах і поблизу від даних про їхнє місце розташування. Дійсно, система HPFS прагне, насамперед, до того, щоб розташувати файл у суміжних кластерах, чи, якщо такої можливості немає, розмістити його на диску таким чином, щоб екстенти (фрагменти, фрагменти файлу, що розташовуються в суміжних секторах диска. Файл має принаймні один екстент, якщо він не фрагментований, а в противному випадку декілька екстентів) файлу фізично були якнайближче один до одного. Такий підхід істотно зменшує час позиціювання голівок запису/читання жорсткого диска і час чекання (rotational latency — затримка між установкою голівки читання/запису на потрібну доріжку диска і початком читання даних з диска). Можна сказати, що файлова система HPFS має, у порівнянні з FAT, що випливають основні переваги:

    • висока продуктивність;

    • надійність;

    • робота з розширеними атрибутами, що дозволяє керувати доступом до файлів і каталогів;

    • ефективне використання дискового простору.

    Усі ці переваги обумовлені структурою диска HPFS. Розглянемо її більш докладно (мал. 4.10).

    Рис. 4.10. Структура розділу HPFS

    На початку диска розташовано кілька керуючих блоків. Весь інший дисковий простір у HPFS розбито на частини («смуги», «стрічки» із суміжних секторів, в оригіналі — band). Кожна така група даних займає на диску простір у 8 Мбайт і має свою власну бітову карту розподілу секторів. Ці бітові карти показують, які сектори даної смуги зайняті, а які — вільні. Кожному сектору стрічки даних відповідає один біт у її бітовій карті. Якщо біт має значення 1, то відповідний сектор зайнятий, а якщо 0 — вільний.

    Бітові карти двох смуг розташовуються на диску поруч, так само розташовуються і самі смуги. Тобто послідовність смуг і карт виглядає в такий спосіб: бітова карта, бітова карта, стрічка з даними, стрічка з даними, бітова карта, бітова карта і т.д. Таке розташування «стрічок» дозволяє безупинно розмістити на жорсткому диску файл розміром до 16 Мбайт і в той же час не видаляти від самих файлів інформацію про їхнє місцезнаходження. Це ілюструється мал. 10.10.

    Очевидно, що якби на весь диск була тільки одна бітова карта, як це зроблено в FAT, то для роботи з нею приходилося б переміщати голівки читання/запису в середньому через половину диска. Саме для того, щоб уникнути цих втрат, у HPFS і розбитий диск на «смуги». Виходить свого роду розподілена структура даних про використовувані і вільні блоки.

    Дисковий простір у HPFS виділяється не кластерами, як в FAT, а блоками. У сучасній реалізації розмір блоку взятий рівним розміру одного сектору, але в принципі він міг би бути й іншого розміру. По суті діла, блок – це і є кластер. Розміщення файлів у таких невеликих блоках дозволяє більш ефективно використовувати простір диска, тому що непродуктивні втрати вільного місця складають у середньому всього 256 байт на кожен файл. Згадайте, що чим більше розмір кластера, тим більше місця на диску витрачається дарма. Наприклад, кластер на відформатованому під FAT диску обсягом від 512 до 1024 Мбайт має розмір 16 Кбайт. Отже, непродуктивні втрати вільного простору на такому розділі в середньому складають 8 Кбайт (8192 байт) на один файл, у той час як на розділі HPFS ці втрати завжди будуть складати всього 256 байт на файл. Таким чином, на кожен файл заощаджується майже 8 Кбайт.

    На мал. 10.10 показано, що крім «стрічок» із записами файлів і бітових карт у томі з HPFS є ще три інформаційні структури. Це так званий завантажувальний блок (boot block), додатковий блок (super block) і запасний (резервний) блок (spare block). Завантажувальний блок (boot block) розташований у секторах з 0 по 15; він містить ім'я тому, його серійний номер, блок параметрів BIOS і програму початкового завантаження. Програма початкового завантаження знаходить файл OS2LDR, зчитує його в пам'ять і передає керування цій програмі завантаження ОС, що, у свою чергу, завантажує з диска в пам'ять ядро OS/2 - OS2KRNL. І вже OS2KRNL за допомогою зведень з файлу CONFIG.SYS завантажує в пам'ять всі інші необхідні програмні модулі і блоки даних.

    У блоці (super block) міститься покажчик на список бітових карт (bitmap bloc; list). У цьому списку перераховані всі блоки на диску, у яких розташовані бітові карти, використовувані для виявлення вільних секторів. Також у додатковому блоці зберігається покажчик на список дефектних блоків (bad bloc list), покажчик на групу каталогів (directory b and), покажчик на файловий вузол (F-node) кореневого каталогу, а також дата останньої перевірки розділу програмою CHKDSK. У списку дефектних блоків перераховані всі ушкоджені сектори (блоки) диска. Коли система виявляє ушкоджений блок, він вноситься в цей список і для збереження інформації більше не використовується. Крім цього в структурі super block міститься інформація про розмір «смуги». Нагадаємо, що в поточній реалізації HPFS розмір «смуги» узятий рівним 8 Мбайт. Блок super block розміщається в секторі з номером 16 логічного диска, на якому встановлена файлова система HPFS.

    Резервний блок (spare block) містить покажчик на карту аварійного заміщення (hotfix map чи hotfix-areas), покажчик на список вільних запасних блоків (directory emergency free block list), використовуваних для операцій на майже переповненому диску, і ряд системних прапорів і дескрипторів. Цей блок розміщається в 17 секторі диска. Резервний блок забезпечує високу відмовостійкість файлової системи HPFS і дозволяє відновлювати ушкоджені дані на диску.

    Файли і каталоги в HPFS базуються на фундаментальному об'єкті, називаному F-Node. Ця структура характерна для HPFS і аналога у файловій системі FAT не має. Кожен файл і каталог диска має свій файловий вузол F-Node. Кожен об'єкт F-Node займає один сектор і завжди розташовується поблизу від свого файлу чи каталогу (звичайно — безпосередньо перед файлом чи каталогом). Об'єкт F-Node містить довжину і перші 15 символів імені файлу, спеціальну службову інформацію, статистику по доступі до файлу, розширені атрибути файлу і список прав доступу (чи тільки частина цього списку, якщо він дуже великий), асоціативну інформацію про розташування і підпорядкування файлу і т.д. Структура розподілу в F-node може приймати кілька форм у залежності від розміру каталогу чи файлів. HPFS переглядає файл як сукупність одного чи більше секторів. З прикладної програми це не видно; файл поновляється як безупинний потік байтів. Якщо розширені атрибути занадто великі для файлового вузла, то в нього записується покажчик на них.

    Скорочене ім'я файлу (у форматі 8.3) використовується, коли файл із довгим ім'ям копіюється чи переміщається на диск із системою FAT, що не допускає подібних імен. Скорочене ім'я утвориться з перших 8 символів оригінального імені файлу, крапки і перших трьох символів розширення імені, якщо розширення є. Якщо в імені файлу присутні кілька крапок, що не суперечить правилам іменування файлів у HPFS, то для розширення скороченого імені використовуються три символи після самої останньої з цих крапок.

    Тому що HPFS при розміщенні файлу на диску прагне уникнути його фрагментації, то структура інформації, що міститься у файловому вузлі, досить проста. Якщо файл безупинний, то його розміщення на диску описується двома 32-бітними числами. Перше число являє собою покажчик на перший блок файлу, а друге — довжину екстента, тобто число йдучих один за одним блоків, що належать файлу. Якщо файл фрагментований, то розміщення його екстентів описується у файловому вузлі додатковими парами 32-бітних чисел. Фрагментація відбувається, коли на диску немає неперервної вільної ділянки, досить великої, щоб розмістити файл цілком. У цьому випадку файл приходиться розбивати на декілька екстентів і розташовувати їх на диску роздільно. Файлова система HPFS намагається розмістити екстенти фрагментованого файлу якнайближче один до одного, щоб скоротити час позиціювання голівок читання/запису жорсткого диска. Для цього HPFS використовує статистику, а також старається умовно резервувати хоча б 4 кілобайти місця наприкінці файлів, що ростуть. Ще один спосіб зменшення фрагментування файлів — це розташування файлів, що ростуть назустріч один одному, ­­­­чи файлів, відкритих різними тредами чи процесами, у різних смугах диска.

    У файловомуому вузлі можна розмістити інформацію максимум про вісім екстентів файлу. Якщо файл має більше екстентів, то в його файловий вузол записується покажчик на блок розміщення (allocation block), що може містити до 40 покажчиків на екстенти чи, за аналогією з блоком дерева каталогів, на інші блоки розміщення. Таким чином, дворівнева структура блоків розміщення може зберігати інформацію про 480 сектори, що дозволяє працювати з файлами розміром до 7,68 Гбайт. На практиці розмір файлу не може перевищувати 2 Гбайт, але це обумовлено поточною реалізацією інтерфейсу прикладного програмування.

    «Смуга», що знаходиться в центрі диска, використовується для збереження каталогів. Ця смуга називається directory band. Як і всі інші «смуги», вона має розмір 8 Мбайт. Однак, якщо вона буде цілком заповнена, HPFS починає розташовувати каталоги файлів в інших смугах. Розташування цієї інформаційної структури в середині диска значно скорочує середній час позиціювання голівок читання/запису. Дійсно, для переміщення голівок читання/запису з довільного місця диска в його центр потрібно в два рази менше часу, чим для переміщення до краю диска, де знаходиться кореневий каталог у випадку файлової системи FAT. Уже тільки одне це забезпечує більш високу продуктивність файлової системи HPFS у порівнянні з FAT. Аналогічне зауваження справедливе і для NTFS, що теж розташовує свій master file table на початку дискового простору, а не в його середині.

    Однак істотно більший (у порівнянні з розміщенням Directory Band у середині логічного диска) внесок у продуктивність HPFS дає використання методу збалансованих двійкових дерев для збереження і пошуку інформації про місцезнаходження файлів. Як відомо, у файловій системі FAT каталог має лінійну структуру, спеціальним чином не упорядковану, тому при пошуку файлу потрібно послідовно переглядати його із самого початку. У HPFS структура каталогу являє собою збалансоване дерево з записами, розташованими за абеткою (мал. 4.11). Кожен запис, що входить до складу В-Тгее дерева, містить атрибути файлу, покажчик на відповідний файловий вузол, інформацію про час і дату створення файлу, часу і даті останнього відновлення і звертання, довжині даних, що містять розширені атрибути, лічильник звертань до файлу, довжині імені файлу і саме ім'я, і іншу інформацію.

    Рис. 4.11. Збалансоване двійкове дерево.

    Файлова система HPFS при пошуку файлу в каталозі переглядає тільки необхідні вітки двійкового дерева (B-Tree). Такий метод у багато разів ефективніший, ніж послідовне читання всіх записів у каталозі, що є в системі FAT. Для того щоб знайти шуканий файл у каталозі (точніше, покажчик на його інформаційну структуру F-node), організованому на принципах збалансованих двійкових дерев, більшість записів взагалі читати не потрібно. У результаті для пошуку інформації про файл необхідно виконати істотно меншу кількість операцій читання диска.

    Дійсно, якщо, наприклад, каталог містить 4096 файлів, то файлова система FAT зажадає читання в середньому 64 секторів для пошуку потрібного файлу усередині такого каталогу, у той час як HPFS здійснить читання усього тільки 2-4 секторів (у середньому) і знайде шуканий файл. Нескладні розрахунки дозволяють побачити явні переваги HPFS над FAT. Так, наприклад, при використанні 40 входів на блок блоки каталогу дерева з двома рівнями можуть містити 1640 входів, а каталогу дерева з трьома рівнями — вже 65 640 входів. Другими словами, деякий файл може бути знайдений у типовому каталозі з 65 640 файлів максимум за три звертання. Це набагато краще файлової системи FAT, де для пошуку файлу потрібно прочитати в гіршому випадку більш 4000 секторів.

    Розмір кожного з блоків, у термінах яких виділяються каталоги в поточній реалізації HPFS, дорівнює 2 Кбайт. Розмір запису, що описує файл, залежить від розміру імені файлу. Якщо ім'я займає 13 байтів (для формату 8.3), то блок з 2 Кбайт вміщає до 40 описувачів файлів. Блоки зв'язані один з одним за допомогою спискової структури (як і описувачі екстентів) для полегшення послідовного обходу.

    При перейменуванні файлів може виникнути так зване перебалансування дерева. Створення файлу, перейменування чи стирання може приводити до каскадування блоків каталогів. Фактично, перейменування може зазнати невдачі через недолік дискового простору, навіть якщо файл безпосередньо в розмірах не збільшився. Щоб уникнути цього «нещастя» HPFS підтримує невеликий пул вільних блоків, що можуть використовуватися при «аварії». Ця операція може зажадати виділення додаткових блоків на заповненому диску. Покажчик на цей пул вільних блоків зберігається в SpareBlock.

    Важливе значення для підвищення швидкості роботи з файлами має зменшення їхньої фрагментації. У HPFS вважається, що файл є фрагментованим якщо він містить більше одного екстента. Зниження фрагментації файлів скорочує час позиціювання і час чекання за рахунок зменшення кількості переміщень голівок, необхідного для доступу до даних файлу. Алгоритми роботи файлової системи HPFS працюють таким чином, щоб по можливості розміщати файли в послідовних суміжних секторах диска, що забезпечує максимально швидкий доступ до даних згодом. У системі FAT, навпаки, запис наступної порції даних у перший же вільний кластер неминуче приводить до фрагментації файлів. HPFS теж, якщо це є можливим, записує дані і суміжні сектори диска (але не в перший попавший). Це дозволяє трохи знизити число переміщень голівок читання/запису від доріжки до доріжки. При цьому, коли дані дописуються в існуючий файл, HPFS відразу ж резервує як мінімум 4 Кбайт неперервного простору на диску. Якщо ж частина цього простору не знадобилася, то після закриття файлу вона звільняється для подальшого використання. Файлова система HPFS рівномірно розміщає неперервні файли по всьому диску для того, щоб згодом без фрагментації забезпечити їхнє можливе збільшення. Якщо ж файл не може бути збільшений без порушення його неперервності, HPFS знов-таки резервує 4 Кбайт суміжних блоків якнайближче до основної частини файлу з метою скоротити час позиціювання голівок читання/запису і час чекання відповідного сектора.

    Очевидно, що ступінь фрагментації файлів на диску залежить як від числа файлів, розташованих на ньому, їхніх розмірів і розмірів самого диска, так і від характеру й інтенсивності самих дискових операцій. Незначна фрагментація файлів практично не позначається на швидкодії операцій з файлами Файли, що складаються з двох-трьох екстентів, практично не знижують продуктивність HPFS, тому що ця файлова система стежить за тим, щоб області даних, приналежні тому самому файлу, розташовувалися якнайближче один від одного. Файл із трьох екстентів має тільки два порушення неперервності і, отже, для його читання буде потрібно всього лише два невеликих переміщення голівки диска. Програми (утиліти) дефрагментації, що є для цієї файлової системи, за замовчуванням вважають наявність двох-трьох екстентів у файлі нормою. Наприклад, програма HPFSOPT з набору утиліт Gamma Tech за замовчуванням не дефрагментує файли, що складаються з трьох і менше екстентів, а файли, що мають більшу кількість екстентів, приводяться до 2 чи 3 екстентам, якщо це можливо (файли обсягом у кілька десятків мегабайт завжди будуть фрагментовані, тому що максимально можливий розмір екстента, як ви пам‘ятаєте, дорівнює 8 Мбайт). Треба сказати, що практика показує що в середньому на диску є не більш 2 відсотків файлів, що мають три і 6ільше екстентів. Навіть загальна кількість фрагментованих файлів, як правило, не перевищує 3 відсотків. Така незначна фрагментація робить досить малий вплив на загальну продуктивність системи.

    Тепер коротко розглянемо питання надійності збереження даних у HPFS. Будь-яка файлова система повинна мати засоби виправлення помилок, що виникають при записі інформації на диск. Система HPFS для цього використовує механізм аварійного заміщення (hotfix).

    Якщо файлова система HPFS зіштовхується з проблемою в процесі запису даних на диск, вона виводить на екран відповідне повідомлення про помилку. Потім HPFS зберігає інформацію, що повинна була бути записана в дефектний сектор, в одному з запасних секторів, заздалегідь зарезервованих на цей випадок. Список вільних запасних блоків зберігається в резервному блоці HPFS. При виявленні помилки під час запису даних в нормальний блок HPFS вибирає один з вільних запасних блоків і зберігає ці дані в ньому. Потім файлова система обновляє карту аварійного заміщення в резервному блоці. Ця карта являє собою просто пари подвійних слів, кожне з яких є 32-бітним номером сектора. Перший номер вказує на дефектний сектор, а другий — на той сектор серед наявних запасних секторів, що був обраний для його заміни. Після заміни дефектного сектора запасним карта аварійного заміщення записується на диск, і на екрані з'являється спливаюче вікно, що інформує користувача про помилку запису, що відбулася, на диск. Щораз, коли система виконує запис чи читання сектора диска, він переглядає карту аварійного заміщення і підмінює всі номери дефектних секторів номерами запасних секторів з відповідними даними. Варто помітити, що це перетворення номерів істотно не впливає на продуктивність системи, тому що воно виконується тільки при фізичному звертанні до диска, але не при читанні даних з дискового кешу. Очищення карти аварійного заміщення автоматично виконується програмою CHKDSK при перевірці диска HPFS. Для кожного заміщеного блоку (сектора) програма CHKDSK виділяє новий сектор у найбільш придатному для файлу (якому належать дані) місці жорсткого диска. Потім програма переміщає дані з запасного блоку в цей сектор і обновляє інформацію про положення файлу, що може зажадати нового балансування дерева блоків розміщення. Після цього CHKDSK вносить ушкоджений сектор у список дефектних блоків, що зберігається в додатковому блоці HPFS, і повертає звільнений сектор у список вільних запасних секторів резервного блоку. Потім видаляє запис з карти аварійного заміщення і записує відредаговану карту на диск.

    Всі основні файлові об'єкти в HPFS, у тому числі файлові вузли, блоки розміщення і блоки каталогів, мають унікальні 32-бітні ідентифікатори і покажчики на свої батьківські і дочірні блоки. Файлові вузли, крім того, містять скорочене ім'я свого файлу чи каталогу. Надмірність і взаємозв'язок файлових структур HPFS дозволяють програмі CHKDSK цілком відновлювати файлову структуру диска, послідовно аналізуючи усі файлові вузли, блоки розміщення і блоки каталогів. Керуючись зібраною інформацією, CHKDSK реконструює файли і каталоги, а потім заново створює бітові карти вільних секторів диска. Запуск програми CHKDSK варто здійснювати з відповідними ключами. Так, наприклад, один з варіантів роботи цієї програми дозволяє знайти і відновити вилучені файли.

    HPFS відноситься до так званих монтуючим файловим системам. Це означає, що вона не вбудована в операційну систему, а додається до неї при необхідності. Файлова система HPFS встановлюється оператором IFS у файлі CONFIG.SYS. Цей оператор завжди поміщається в першому рядку даного конфігураційного файлу. У прикладі, що далі приводиться, оператор IFS встановлює файлову систему HPFS з кешем у 2 Мбайт, довжиною запису кешу в 8 Кбайт і автоматичною процедурою перевірки дисків С и D:

    IFS=E: \OS2\HPFS.IFS /CACHE :2048 /CRECL:4/AUTOCHECK:CD

    Для запуску програми керування процесом кешування варто прописати у файлі CONFIG.SYS ще один рядок:

    RUN=Е:\OS2\CACHE.EXE /Lazy:0n /BufferIdle:2000 /DiskIdle:4000 /MaxAge:8000 /DirtyMax:256 /ReadAhead:On

    У цьому рядку включається режим відкладеного («ледачого») запису, установлюються параметри роботи цього режиму, а також включається режим попереднього читання даних, що в цілому дозволяє істотно скоротити кількість звертань до диска і відчутно підвищити швидкодію файлової системи. Так, ключ Lazy з параметром On включає «ледачий запис», а з параметром Off — виключає. Ключ BufferIdle визначає час у мілісекундах, протягом якого буфер кешу повинний залишатися в неактивному стані, щоб стало можливим здійснити запис даних з кешу на диск. За замовчуванням (тобто якщо не прописувати даний ключ явно) цей час дорівнює 500 мс. Ключ DiskIdle задає час (у мілісекундах), протягом якого диск повинний залишатися в неактивному стані, щоб стало можливим здійснити запис даних з кешу на диск. За замовчуванням цей час дорівнює 1 с. Цей параметр дозволяє уникнути запису з кешу на диск під час виконання інших операцій з диском.

    Ключ MaxAge задає час (теж у мілісекундах), після закінчення якого часто охоронювані в кеші дані нарешті позначаються як «застарілі» і при переповненні кешу можуть бути заміщені новими. За замовчуванням цей час дорівнює 5 с. Інші подробиці установки параметрів і можливі значення ключів є в HELP-файлах, установлюваних разом з операційною системою OS/2 Warp.

    Нарешті, варто сказати і ще про одну систему керування файлами — мова йде про реалізацію HPFS для роботи на серверах, що функціонують під керуванням OS/2. Це система керування файлами, що одержала назву HPFS386.IFS. Її принципова відмінність від системи HPFS.IFS полягає в тім, що HPFS386.IFS дозволяє (за допомогою більш повного використання технології розширених атрибутів) організувати обмеження на доступ до файлів і каталогів за допомогою відповідних списків доступу — ACL (access control list). Ця технологія, як відомо, використовується у файловій системі NTFS. Крім цього, у системі HPFS386.IFS на відміну від HPFS.IFS немає обмежень на обсяг пам'яті, виділюваної для кешування файлових записів. Іншими словами, при наявності достатнього обсягу оперативної пам'яті обсяг файлового кешу може бути в кілька десятків мегабайт, у той час як для звичайної HPFS.IFS цей об‘єм не може перевищувати 2 Мбайт, що по сьогоднішніх мірках безумовно мало. Нарешті, при установці режимів роботи файлового кешу HPFS386.IFS є можливість явно вказати алгоритм кешування. Найбільш ефективним алгоритмом можна вважати так званий «елеваторний», коли при записі даних з кешу на диск вони попередньо упорядковуються таким чином, щоб мінімізувати час, що відводиться на позиціювання голівок читання/запису. Голівки читання/запису при цьому переміщаються від зовнішніх циліндрів до внутрішнього і по ходу свого руху здійснюють запис і читання даних у відповідності зі спеціальним образом впорядковуючим списком запитів на дискові операції.

    Приведемо приклад запису рядків у конфігураційному файлі CONFIG.SYS, що встановлюють систему HPFS386.IFS і визначають параметри роботи підсистеми кешування:

    IFS=E: \IBM386FS\HPFS386.IFS /AUTOCHECK:EGH

    RUN=E: \IBM386FS\CACHE386.EXE /Lauzy:0n /BufferIdle:4000 /MaxAge:20000

    Ці записи варто розуміти в такий спосіб. При запуску операційної системи у випадку виявлення прапора, що означає, що не усі файли були закриті в процесі попередньої роботи, система керування файлами HPFS386.IFS спочатку запустить програму перевірки цілісності файлової системи для томів Е:, G: і Н:. Для кешування файлів при роботі цієї системи керування файлами встановлюється режим відкладеного запису з часом життя буферів до 20 с. Інші параметри, зокрема алгоритм обслуговування запитів, встановлюються у файлі HPFS386.INI, що у даному випадку розташовується в директорії E:\IBM386FS.

    Опишемо коротко деякі найбільш цікаві параметри, що керують роботою кешу в цій системі керування файлами. Насамперед відзначимо, що файл HPFS386.INI розбитий на кілька секцій. В даний момент розглянемо секцію [ULTIMEDIA]:

    [ULTIMEOIA]

    QUEUESORT={FIFO|ELEVATOR|DEFAULT|CURRENT}

    QUEUEMETHOD={PRIORITY|NOPRIORITY|DEFAULT|CURRENT}

    QUEUEDEPTH-{1...255|DEFAULT|CURRENT}

    Параметр QUEUESORT задає спосіб ведення черги запитів до диска. Він може приймати значення FIFO, ELEVATOR, DEFAULT і CURRENT. Якщо задане значення FIFO, то кожен новий запит просто додається в кінець черги, тобто запити виконуються в тім порядку, у якому вони надходять у систему. Однак можна впорядкувати деяку кількість запитів по зростанню номерів доріжок. Якщо задане значення ELEVATOR, то включається режим підтримки впорядкованої черги запитів. При цьому запити починають оброблятися по алгоритму ELEVATOR (він же C-SCAN чи «режим плаваючої голівки»). Нагадаємо, цей алгоритм має на увазі, що голівка читання/запису сканує диск в обраному напрямку (наприклад, у напрямку зростання номерів доріжок), зупиняючись для виконання запитів, що знаходяться на шляху проходження. Коли вона доходить до останнього запиту, голівка читання/запису переноситься на початкову доріжку і процес обслуговування запитів продовжується. Якщо для параметра QUEUESORT задане значення DEFAULT, то вибирається алгоритм за замовчуванням. Зараз це ELEVATOR. Якщо задане значення CURRENT, то залишається в силі; той алгоритм, що був обраний DASD Manager при ініціалізації.

    Параметр QUEUEMETHOD визначає, чи повинні враховуватися пріоритети запитів при побудові черги. Він може приймати значення PRIORITY, NOPRIORITY, DEFAULT і CURRENT. Якщо задане значення NOPRIORITY, то всі запити включаються в загальну чергу, а їхні пріоритети ігноруються. Якщо додане значення PRIORITY, то модуль DASD Manager буде підтримувати кілька черг запитів, по одній на кожен пріоритет. Коли DASD Manager передасть запити на виконання драйверу диска, він спочатку вибирає запити із самої пріоритетної черги, потім з менш пріоритетної і т.д. Пріоритети призначає HPFS386, а розподілені вони в такий спосіб.

    High:

    1. Shutdown чи екстрений запис через збій живлення.

    2. Сторінковий обмін.

    3. Звичайні запити від foreground сесії.

    4. Звичайні запити від background сесії. (Пріоритети 3 і 4 рівні, якщо у файлі CONFIG.SYS заданий параметр RIORITY_DISK_IO=NO.)

    5. Read-ahead і низькопріоритетні запити сторінкового обміну (сторінкова предвибірка).

    6. Lazy-Write та інші запити, що не вимагають негайної реакції.

    Low:

    7. Предвибірка.

    Якщо для параметра QUEUEMETHOD задане значення DEFAULT, то вибирається метод за замовчуванням. Зараз це PRIORITY. Якщо задане значення CURRENT, то залишається в силі той метод, що був обраний DASD Manager при ініціалізації.

    Параметр QUEUEDEPTH задає глибину перегляду черги при вибірці запитів. Він може приймати значення з діапазону (1...255), а також DEFAULT і CURRENT. Якщо в якості значення параметра QUEUEDEPTH задане число, то воно визначає кількість запитів, що повинні знаходитися в черзі дискового адаптера одночасно. Наприклад, для SCSI-адаптерів має сенс підтримувати таку довжину черги, при якій вони зможуть завантажити всі запити у свої апаратні структури (tagged queue чи mailbox). Якщо черга запитів до адаптера буде занадто короткою, то апаратура буде працювати з неповним завантаженням, а якщо вона буде занадто довгою — драйвер SCSI-адаптера буде перевантажений «зайвими» запитами. Тому розумним значенням для QUEUEDEPTH буде число, що небагато перевищує довжину апаратної черги команд адаптера. Якщо для параметра QUEUEDEPTH задане значення DEFAULT, то глибина перегляду черги визначається автоматично на підставі значення, що рекомендоване драйвером дискового адаптера. Якщо задане значення CURRENT, то глибина перегляду черги не змінюється. У поточній реалізації CURRENT еквівалентно DEFAULT.

    Отже, поточні замовчування для HPFS386 мають вигляд:

    QUEUESORT=FIFO

    QUEUEMETHOD=DEFAULT

    QUEUEDEPTH=2

    А поточні замовчування для DASD Manager такі:

    QUEUESORT=ELEVATOR

    QUEUEMETHOD=PRIORITY

    QUEUEDEPTH=<залежить від адаптера диска>

    Замовчування DASD Manager можна змінювати за допомогою параметра /QF:

    BASEDEV=OS2DASD.DMD /QF:{1|2|3}

    де 1 - QUEUESORT = FIFO; 2 - QUEUEMETHOD = NOPRIORITY; 3 - QUEUESORT = FIFO і

    QUEUEMETHOD = NOPRIORITY.

    Нарешті, додамо ще кілька слів про встановлювані файлові системи (installable file systems — IPS), що представляють собою спеціальні «драйвери» для доступу до розділів, відформатованим під іншу файлову систему . Це дуже зручний і могутній механізм додавання в ОС нових файлових систем і заміни однієї системи керування файлами на іншу. Сьогодні, наприклад, для OS/2 уже реально існують IFS-модулі для файлової системи VFAT (FAT з підтримкою довгих імен), FAT32, Ext2FS (файлова система Linux), NTFS (правда, поки тільки для читання). Для роботи з даними на CD-ROM мається CDFS.IFS. Є і FTP.IFS, що дозволяє монтувати ftp-архіви як локальні диски. Механізм встановлюваних файлових систем був перенесений і в систему Windows NT.

    Тема 12.Файлова система ntfs (Mew Technology File System)

    1. Основні характеристики.

    2. Структура диску.

    3. Мета-файли.

    4. Атрибути файлів.

    5. Обмеження доступу до файлів та каталогів.

    6. Спеціальні права.

    7. Основні відмінності між FAT32 та NTFS.

    У назву файлової системи NTFS входять слова «New Technology», тобто «нова технологія». Дійсно, NTFS містить ряд значних удосконалень і змін, що істотно відрізняють її від інших файлових систем. З погляду користувачів, файли як і раніше зберігаються в каталогах (часто званих «папками» чи фолдерами в середовищі Windows). Однак у NTFS на відміну від FAT робота на дисках великого обсягу відбувається набагато ефективніше; є засоби для обмеження в доступі до файлів і каталогів, введені механізми, що істотно підвищують надійність файлової системи, зняті багато обмежень на максимальну кількість дискових секторів і/чи кластерів.

    Основні можливості файлової системи NTFS.

    При проектуванні системи NTFS особлива увага була приділена наступним характеристикам:

    • надійність. Високопродуктивні комп'ютери і системи спільного користування (сервери) повинні мати підвищену надійність, що є ключовим елементом структури і поводження NTFS. Одним зі способів збільшення надійності є введення механізму транзакцій, при якому здійснюється журналювання файлових операцій;

    • розширена функціональність. NTFS проектувалася з врахуванням можливого розширення. У ній були втілені багато додаткових можливостей — вдосконалена відмовостійкість, емуляція інших файлових систем, могутня модель безпеки, рівнобіжна обробка потоків даних і створення файлових атрибутів, обумовлених користувачем;

    • підтримка POSIX . Оскільки уряд США вимагав, щоб усі закуповувані ним системи хоча б у мінімальному ступені відповідали стандарту POSIX, така можливість була передбачена і в NTFS. До числа базових засобів файлової системи POSIX відноситься необов'язкове використання імен файлів з урахуванням регістра, збереження часу останнього звертання до файлу і механізм так званих «жорстких силок» — альтернативних імен, що дозволяють посилатися на той самий файл по двох і більше іменах;

    • гнучкість. Модель розподілу дискового простору в NTFS відрізняється надзвичайною гнучкістю. Розмір кластера може змінюватися від 512 байт до 64 Кбайт; він являє собою число, кратне внутрішньому кванту розподілу дискового простору. NTFS також підтримує довгі імена файлів, набір символів Unicode і альтернативні імена формату 8.3 для сумісності з FAT.

    NTFS чудово справляється з обробкою великих масивів даних і досить добре виявляє себе при роботі з томами обсягом від 300-400 Мбайт і вище. Максимально можливі розміри тому (і розміри файлу) складають 16 Ебайт(один екзабайт дорівнює 264, або приблизно 16000 млрд. гігабайт­­­­­ ). Кількість файлів у кореневому і некореневому каталогах не обмежено. Оскільки в основу структури каталогів NTFS закладена ефективна структура даних, звана «бінарним деревом» (див. розділ «Файлова система HPFS»), час пошуку файлів у NTFS (на відміну від систем на базі FAT) не зв'язано лінійною залежністю з їхньою кількістю.

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

    Файлова система NTFS підтримує об'єктну модель безпеки NT і розглядає всі томи, каталоги і файли як самостійні об'єкти. NTFS забезпечує безпеку на рівні файлів; це означає, що права доступу до томів, каталогів і файлів можуть залежати від облікового запису користувача і тих груп, до яких він належить. Щораз, коли користувач звертається до об'єкта файлової системи, його права доступу перевіряються за списком дозволів даного об'єкта. Якщо користувач має достатній рівень прав, його запит задовольняється; у противному випадку запит відхиляється. Ця модель безпеки застосовується як при локальній реєстрації користувачів на комп'ютерах з NT, так і при вилучених мережних запитах. Нарешті, крім величезних розмірів томів і файлів, система NTFS також має вбудовані засоби стиску, які можна застосовувати до окремих файлів, цілим каталогам і навіть томам (і згодом скасовувати чи призначати їх за своїм розсудом).

    Структура тому з файловою системою NTFS.

    Розглянемо тепер структуру файлової системи NTFS. Ми тут зачепим тільки основні моменти. Одним з основних понять, використовуваних при роботі з NTFS, є поняття тому (volume). Можливо також створення відмовостійкого тому, що займає кілька розділів, тобто використання RAID-технології. Як і багато інших систем, NTFS поділяє весь корисний дисковий простір тому на кластери — блоки даних, адресуємі як одиниці даних. NTFS підтримує розміри кластерів від 512 байт до 64 Кбайт; стандартом же вважається кластер розміром 2 чи 4 Кбайт.

    Весь дисковий простір у NTFS поділяється на дві нерівні частини (рис.12.1). Перші 12 % диска приділяються під так звану MFT-зону — простір, що може займати, збільшуючись у розмірі, головний службовий метафайл MFT(master file table — це спеціальний файл, головна системна структура даних, яка і дозволяє визначати місцезнаходження всіх інших файлів). Запис яких-небудь даних у цю область неможлива. МFТ-зона завжди тримається порожньою - це робиться для того, щоб самий головний, службовий файл (MFT) по можливості не фрагментувався при своєму росту. Інші 88 % тому являють собою звичайний простір для збереження файлів.

    Рис. 12.1. Структура тому NTFS.

    MFT (master file table, загальна таблиця файлів) являє собою централізований каталог всіх інших файлів диску, у тому числі і себе самого. MFT поділений на записи фіксованого розміру в 1 Кбайт, і кожен запис відповідає якому-небудь файлу (у загальному значенні цього слова). Перші 16 файлів носять службовий характер і недоступні операційній системі — вони називаються метафайлами, причому найперший метафайл — сам MFT. Ці перші 16 елементів MFT — єдина частина диска, що має строго фіксоване положення. Копія цих же 16 записів зберігається в середині тому для надійності, оскільки вони дуже важливі. Інші частини MFT-файлу можуть розташовуватися як і будь-який інший файл, у довільних місцях диску — відновити його положення можна за допомогою його самого, «зачепивши» за саму основу — за перший елемент MFT.

    Згадані перші 16 файлів NTFS (метафайли) носять службовий характер кожний з них відповідає за який-небудь аспект роботи системи. Метафайли знаходяться в кореневому каталозі NTFS-тому. Усі вони починаються із символу імені «$», хоча одержати яку-небудь інформацію про них стандартними засобами складно. У табл.12.1 приведені основні відомі метафайли і їхнє призначення. Таким чином, можна довідатися, наприклад, скільки операційна система витрачає на каталогізацію тому, подивившись на розмір файлу $MFT.

    Таблиця 12.1. Метафайли NTFS

    Ім‘я метафайла

    Призначення метафайла

    $MFT

    Сам Master File Table

    $MFTmirr

    Копія перших 16 записів MFT, яка розміщена посередині тому

    $LogFile

    Файл підтримки операцій журналювання

    $Volume

    Службова інформація — мітка тому, версія файлової системи і т. д.

    $AttrDef

    Список стандартних атрибутів файлів на томі

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

    $Bitmap

    Карта вільного місця тому

    $Boot

    Завантажуючий сектор (якщо розділ завантажуючий)

    $Quota

    Файл, в якому записані права користувачів на використання дискового простору (цей файл почав працювати тільки в Windows 2000 з системою NTFS 5.0)

    $Upcase

    Файл – таблиця відповідності заглавних і прописних букв в іменах файлів. В NTFS імена файлів записуються в Unicode (що складає 65 тисяч різних символів) і шукати великі і малі еквіваленти в даному випадку – нетривіальна задача

    Отже, усі файли тому згадуються в MFT. У цій структурі зберігається вся інформація про файли, за винятком власне даних. Ім'я файлу, розмір положення на диску окремих фрагментів і т.д. – усе це зберігається у відповіднімі записі. Якщо для інформації не вистачає одного запису MFT, то використовується кілька записів, причому не обов'язково йдучих підряд. Файли можуть мати не дуже великий розмір. Тоді застосовується досить вдале рішення: дані файлу зберігаються прямо в MFT, у місці, що залишився від основних даних, у межах одного запису MFT. Файли, що займають сотні байт, звичайно не мають свого «фізичного» втілення в основній файловій області - усі дані такого файлу зберігаються в одному місці, у MFT.

    Файл у томі з NTFS ідентифікується так званим файловим посиланням (File Referens), яке представлене як 64-розрядне число. Файлове посилання складається з номера файлу, що відповідає позиції його файлового запису в MFT, і номера послідовності. Останній збільшується всякий раз, коли дана позиція MFT використовується повторно, що дозволяє файловій системі NTFS виконувати внутрішні перевірки цілісності.

    Кожен файл у NTFS представлений за допомогою потоків (streams), тобто в нього немає «просто даних» як таких, а є «потоки». Для правильного розуміння досить вказати, що один з потоків і носить звичний нам зміст – дані файлу. Але більшість атрибутів файлу - це теж потоки. У такий спосіб виходить, що базова сутність у файлі тільки одна - номер у MFT, а все інше, включаючи і його потоки, - опційно. Даний підхід може ефективно використовуватися - наприклад, файлу можна «приліпити» ще один потік, записавши в нього будь-які дані. У Windows 2000 у такий спосіб записана інформація про автора і зміст файлу (одна з закладок у властивостях файлу, що переглядаються, наприклад, із провідника). Цікаво, що ці додаткові потоки не видні стандартними засобами роботи з файлами: розмір основного потоку, що спостерігається, що містить традиційні дані. Можна, приміром, мати файл нульової довжини, при стиранні якого звільниться 1 Гбайт вільного місця - просто тому, що яка-небудь хитра програма чи технологія «приліпила» до нього додатковий потік (альтернативні дані) такого великого розміру. Але насправді в даний час потоки практично не використовуються, так що побоюватися подібних ситуацій не потрібно, хоча гіпотетично вони можливі. Просто необхідно мати на увазі, що файл у NTFS — це більш глибоке поняття, чим можна собі представити, переглядаючи каталоги диска.

    Стандартні ж атрибути для файлів і каталогів у томі NTFS мають фіксовані імена і коди типу, вони перераховані в табл.12.2.

    Таблиця 12.2. Атрибути файлів в системі NTFS

    Системний атрибут

    Опис атрибута

    Стандартна інформація про файл

    Традиційні атрибути Read Only, Hidden, Archive, System, відмітки часу, включаючи час створення або останньої модифікації, число каталогів, які посилаються на файл

    Список атрибутів

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

    Ім‘я файлу

    Ім‘я файлу в символах Unicode. Файл може мати декілька атрибутів – імен файлу, подібно тому як це має місце в UNIX-системах. Це трапляється, коли є зв‘язок POSIX з даним файлом або, якщо в файла є автоматично згенероване ім‘я в форматі 8.3

    Дескриптор захисту

    Структура даних захисту (ACL), охороняючи файл від несанкціонованого доступу. Атрибут “дескриптор захисту” визначає, хто господар цього файлу і хто має доступ до нього

    Дані

    Дані файлу. В NTFS в файлі по замовчуванню є один безіменний атрибут даних, і він може мати доповнюючи іменовані атрибути даних. В каталогу немає атрибуту даних по замовчуванню, але він може мати необов‘язкові іменовані атрибути даних

    Корінь індексу, розміщення індексу, бітова карта (тільки для каталогів)

    Атрибути, які використовуються для індексів імен файлів у великих каталогах

    Розширені атрибути HPFS

    Атрибути, які використовуються для реалізації розширених атрибутів HPFS для підсистеми OS/2 і OS/2-клієнтів файл-серверів Windows NT

    Атрибути файлу в записах MFT розташовані в порядку зростання числових значень кодів типу, причому деякі типи атрибутів можуть зустрічатися в записі більш одного разу: наприклад, якщо у файлі є кілька атрибутів даних чи кілька імен. Обов'язковими для кожного файлу в томі NTFS є атрибут стандартної інформації, атрибут імені файлу, атрибут дескриптора захисту й атрибут даних. Інші атрибути можуть зустрічатися при необхідності.

    Ім'я файлу в NTFS, на відміну від файлових систем FAT і HPFS, може містити будь-які символи, включаючи повний набір національних алфавітів, тому що дані представлені в Unicode — 16-бітному представленні, що дає 65 535 різних символів. Максимальна довжина імені файлу в NTFS — 255 символів.

    Великий внесок в ефективність файлової системи вносить організація каталогу. Каталог у NTFS являє собою спеціальний файл, що зберігає посилання на інші файли і каталоги, створюючи ієрархічну будову даних на диску. Файл каталогу поділений на блоки, кожний з який містить ім'я файлу, базові атрибути і посилання на елемент MFT, що вже надає повну інформацію про елемент каталогу. Головний каталог диска — кореневий — нічим не відрізняється від звичайних каталогів, крім спеціального посилання на нього з початку метафайла MFT.

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

    Отже, як нам тепер відомо, бінарне дерево каталогу розташовує імена файлів таким чином, щоб пошук файлу здійснювався за допомогою одержання двохзначних відповідей на питання про положення файлу. Бінарне дерево здатне дати відповідь на питання: у якій групі, щодо даного елемента, знаходиться шукане ім'я — вище чи нижче? Ми починаємо з такого питання до середнього елемента, і кожна відповідь звужує зону пошуку в середньому в два рази. Якщо уявити, що файли відсортовані за алфавітом, то відповідь на питання здійснюється очевидним способом - порівнянням початкових букв. Область пошуку, звужена в два рази, починає досліджуватися аналогічним чином, починаючи знову ж із середнього елемента.

    Помітимо, що додавати файл у каталог у виді дерева не набагато складніше, ніж у лінійний каталог системи FAT. Це співставлені по часу операції. Для того щоб додати новий файл у каталог, потрібно спочатку переконатися, що файлу з таким ім'ям там ще немає. Тому в системі FAT з лінійною організацією записів каталогу в нас з'являються труднощі не тільки з пошуком файлу. І це компенсує саму простоту додавання файлу в каталог.

    Можливості файлової системи ntfs по обмеженню доступу до файлів і каталогів.

    Розглянемо основні можливості, зв'язані як з організацією різних прав доступу до файлів і каталогів при використанні мережного доступу, так і локальні обмеження на файли і каталоги. NTFS розглядає каталоги (папки) і файли як різнотипні об'єкти і веде окремі (хоча і перекриваючі) списки прав доступу для кожного типу. Нижче перераховані права NTFS, призначені папкам (відповідні права для файлів приведені нижче):

    • немає доступу (no access) (None)(немає);

    • повний доступ (full control) (А11)(А11) (усі) (усі);

    • право читання (read) (RX)(RX) (читання) (читання);

    • право додавання (add) (WX)(not specified) (запис/виконання не зазначене);

    • право додавання і читання (add&read) (RWX)(RX) (читання/запис/виконання) (читання/виконання);

    • право перегляду (list) (RX)(not specified) (читання/виконання)(не зазначене);

    • право зміни (change) (R\VXD)(RWXD) (читання/запис/ виконання/видалення) (читання/запис/виконання/видалення).

    Зверніть увагу на два вирази в дужках, зазначені після імені права доступу. Перший вираз відноситься до самої папки, а другий — до усіх файлів, що можуть бути створені всередині неї. Наприклад, при повному доступі для папки дозволяються будь-які дії, однак користувач з повним доступом до папки також буде мати повне право доступу до всіх створених у ній файлів (якщо тільки права доступу до файлу не були змінені його власником чи адміністратором). Іншими словами, у NTFS файли і папки за замовчуванням успадковують права доступу, встановлені для їхньої батьківської папки, однак ці права можуть бути змінені будь-яким користувачем, якому дозволено змінювати права доступу для відповідних об'єктів NTFS. Файли в NTFS можуть мати наступні права:

    • повний доступ (full control) (All) (її);

    • немає доступу (no access) (None) (немає);

    • право зміни (change) (RWXD) (читання/запис/виконання/видалення);

    • право читанні (read) (RX) (читання/виконання).

    Для прав доступу NTFS, як і для прав загальних каталогів, діє принцип поглинання. Виключення складає право «немає доступу», що скасовує доступ всіх інших прав.

    При мережному підключенні користувачів права NTFS можуть вступити в конфлікт із правами загальних каталогів. У такій ситуації застосовується право доступу з найбільш жорсткими обмеженнями. У багатьох виникають проблеми з розумінням одержуваних при мережному доступі обмежень. Однак тут можна легко розібратися, якщо пам'ятати, що при доступі по мережі до каталогів і файлів, що розташовуються на томах з NTFS, у нас виходять задіяними два послідовних механізми. Спочатку ми одержуємо доступ до файлів, що був визначений мережними механізмами. Це право «немає доступу» — «no access», право на «читання» — «read», право «зміна» — «change» і «повний доступ» — «full control». Після цього набирають сили обмеження на файли і каталоги, визначені властивостями NTFS. Тобто нам потрібно перебороти послідовно дві перешкоди. Іншими словами, підсумкові права на папки і файли будуть визначатися максимальними обмеженнями, що були задані в кожнім з механізмів.

    Крім перерахованих прав є ще так званий спеціальний доступ (Special Access). Якщо вибрати, це право доступу, то насправді з'являється можливість вибирати кілька прав одночасно з наступного переліку:

    • повний доступ (full control) (Аll);

    • читання (read) (R);

    • запис (write) (W);

    • виконання (execute) (X);

    • видалення (delete) (D);

    • зміна дозволів (change permissions) (P);

    • зміна власника (take ownership) (О).

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

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

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

    Три наступних важливі правила допоможуть визначити стан прав доступу при переміщенні, при копіюванні об'єктів NTFS:

    • При переміщенні файлів у границях розділу NTFS зберігаються вихідні права доступу.

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

    • При переміщенні файлів з розділу NTFS у розділ FAT усі права NTFS губляться.

    Основні відмінності FAT і NTFS.

    Якщо говорити про накладні витрати на збереження службової інформації, FAT відрізняється від NTFS більшою компактністю і меншою складністю. У більшості томів FAT на збереження таблиці розміщення, що містить інформацію про усі файли тому, витрачається менше 1 Мбайта. Настільки низькі накладні витрати дозволяють форматувати у FAT жорсткі диски малого обсягу і флопі-диски. У NTFS службові дані займають більше місця, ніж у FAT. Так, кожен елемент каталогу займає 2 Кбайт. Однак це має і свої переваги, тому що вміст файлів обсягом 1500 байт і менше може цілком зберігатися в елементі каталогу.

    Система NTFS не може використовуватися для форматування флопі-дисків. Не варто користуватися нею для форматування розділів обсягом менше 50-100 Мбайт. Відносно високі накладні витрати приводять до того, що для малих розділів службові дані можуть займати до 25 % обсягу носія. Корпорація Microsoft рекомендує використовувати FAT для розділів об‘ємом 256 Мбайт і менше, a NTFS — для розділів обсягом 400 Мбайт і більше.

    Наступний критерій порівняння — розмір файлів. Розділи FAT мають обсяг до 2 Гбайт, VFAT — до 4 Гбайт і FAT32 — до 4 Тбайт. Проте через особливості своєї внутрішньої будови розділи FAT найкраще працюють для розділів обсягом 200 Мбайт і менше. Розділи NTFS можуть досягати 16 Эбайт, однак на даний час через апаратних і інших системних причин, розмір файлів обмежується 2 Тбайт.

    Розділи FAT можуть використовуватися практично у всіх операційних системах. За рідкісними винятками, з розділами NTFS можна працювати прямо тільки з Windows NT, хоча і існують для ряду ОС відповідні реалізації систол керування файлами для читання файлів з томів NTFS. Так, наприклад, утиліта (драйвер) NTFSDOS дозволяє читати дані NTFS на комп'ютері, завантаженому в режимі MS-DOS. Однак повноцінних реалізацій для роботи з NTFS поза системою Windows NT поки немає.

    Розділи FAT не забезпечують локальної безпеки. З іншого боку, розділи NTFS забезпечують локальну безпеку як файлів, так і каталогів. Для розділів FAT можуть встановлюватися загальні права, зв'язані з загальним доступом до каталогів у мережі. Однак такий захист не перешкодить користувачу з локальним входом одержати доступ до файлів свого комп'ютера. У відношенні безпеки NTFS виявляється кращим варіантом. Розділи NTFS можуть забороняти чи обмежувати доступ як вилучених, так і локальних користувачів. Отже, до захищених файлів зможуть звернутися лише ті користувачі, яким були надані відповідні права. Нагадаємо, що Windows NT містить спеціальну утиліту CONVERT.EXE, яка перетворить томи FAT в еквівалентні томи NTFS, однак для зворотнього перетворення (з NTFS у FAT) подібних утиліт не існує. Щоб виконати таке зворотнє перетворення, вам доведеться створити розділ FAT, скопіювати в нього файли з розділу NTFS і потім видалити оригінали. Важливо при цьому не забувати і про те, що при копіюванні файлів з NTFS у FAT губляться всі атрибути безпеки NTFS (нагадаємо, що в FAT не передбачені засоби для визначення і наступного збереження цих атрибутів). Останнім часом появилася ще одна дуже важлива обставина, зв'язана з тим, що обсяги дискових механізмів набагато перевищили максимально припустимий розмір, прийнятний для FAT, — 8,4 Гбайт. Ця межа пояснюється максимально можливими значеннями в адресі сектора, для якого, як ми вже знаємо, приділяється всього 3 байти. Тому в переважній більшості випадків при роботі в середовищі Windows-систем використовують або FAT32, або NTFS. Остання, безумовно, краще, але вона не підтримується в широко розповсюджених ОС Windows 98 і нині все більш часто зустрічаєма Windows Millennium Edition.

    Тема 13. Інтерфейси операційних систем

    1. Основні поняття і визначення.

    2. Інтерфейс прикладного програмування АРІ.

    3. Реалізація функцій АРІ на рівні операційної системи.

    4. Реалізація функцій АРІ на рівні системи програмування.

    5. Реалізація функцій АРІ за допомогою зовнішніх бібліотек.

    6. POSIX інтерфейс.

    1. Основні поняття і визначення.

    Інтерфейс ОС – це спеціальний інтерфейс системного або прикладного програмування, який призначений для виконання в наступних задачах:

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

    • керування пам’яттю, що включає в себе такі функції як запит та розподілення певного блоку пам’яті, звільнення пам’яті, зміна параметрів блоку пам’яті та відображення файлів на пам’ять;

    • керування вводом/виводом, що включає запит на керування віртуальними пристроями та файлові операції, зокрема створення файлів, зміна та знищення інформації яка записана у файлах.

    Крім перерахованих вище функцій АРІ також відповідає за користувацький інтерфейс ОС. Цей інтерфейс реалізовується за допомогою спеціальних програмних модулів, які приймають команди користувачів на відповідній внутрішній мові і транслюють їх в звичайні виклики у відповідності з основним інтерфейсом ОС.

    В останніх ОС це здійснюється за допомогою графічного інтерфейсу GUI (graphic user interface). Використання інтерфейсу GUI це є частковий випадок виконання задачі вводу/виводу, який фактично не є частиною ядра ОС, але в деяких випадках функції GUI відносяться до основного системного АРІ.

    В сучасних ОС існує два підходи до керування задачами в залежності від реалізації АРІ:

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

    • в більш складних системах є не одна підпрограма входу, а декілька у відповідністю з кількістю функцій АРІ.

    1. Інтерфейс прикладного програмування арі.

    АРІ (application program interface – інтерфейс прикладного програмування) призначений для використання прикладними програмами системних ресурсів операційної системи, а також функцій які реалізує ОС.

    АРІ описує набір функцій та процедур які належать ядру та системним викликам ОС. АРІ призначений для організації взаємодії прикладної чи системної програми з обчислювальної системою в рамках якої виконується програма користувача.

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

    В сучасних ОС інтерфейс АРІ реалізовується на рівні операційної системи, на рівні системи програмування, а також на рівні зовнішніх бібліотек процедур і функцій. В будь – якому випадку система програмування надає розробнику засоби для під’єднання (використання) функцій АРІ у вихідному тексті програми, а також засоби для організації виклику функцій АРІ. Об’єктний код самих функцій АРІ включається в об’єктний код розроблюваної програми по мірі необхідності.

    Основні можливості інтерфейсу прикладного програмування доцільно оцінювати по наступних характеристиках:

    • ефективність виконання функцій АРІ, що включають в себе швидкість виконання функцій та об’єм обчислювальних ресурсів необхідних для їх виконання;

    • функціональна повнота, функції які надаються інтерфейсу;

    • залежність прикладної програми від архітектури обчислювальної системи.

    1. Реалізація функцій арі на рівні операційної системи.

    В цьому випадку відповідальність за реалізацію функцій АРІ несе ОС. Об’єктний код, який безпосередньо виконує функції АРІ безпосередньо входить в склад ОС (в деяких випадках навіть в склад ядра ОС) або реалізуються у вигляді динамічно - завантажувальних бібліотек, які розроблені для даної ОС.

    Система програмування відповідальна лише за те, щоб організувати виклик об’єктного коду. При такому підході програма звертається безпосередньо до ОС, тому тут досягається найбільша ефективність функцій АРІ в порівнянні зі всіма іншими методами.

    Недоліком організації АРІ по такому методу є практично повна відсутність властивості перемішуваності не тільки коду виконуваної програми, але і коду початкової програми, яка викликає функції АРІ.

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

    1. Реалізація функцій арі на рівні системи програмування.

    Якщо функції АРІ реалізуються на рівні системи програмування, то як правило вони надаються користувачу у вигляді бібліотеки функцій відповідної мови програмування, або іншими словами бібліотеки часу виконання RTL. В цьому випадку система програмування надає користувачу бібліотеку відповідної мови програмування і здійснює під’єднання до виконуваної програми об’єктного коду, який виконує функції АРІ. В цьому випадку ефективність функцій АРІ є трохи нижчою ніж у випадку з ОС. Це відбувається тому, що для виконання функцій АРІ бібліотека RTL все рівно повинна здійснювати виклик відповідних функцій ОС.

    Переміщуваність вихідного (початкового) коду програми в цьому випадку буде самою високою тому, що синтаксис і семантика всіх функцій АРІ є строго регламентовані стандартом певної мови програмування. Функції АРІ в цьому випадку залежать від мови програмування, а не від архітектури обчислювальної системи. Тому для переміщуваності коду вихідної програми достатньо буде скомпілювати програму за допомогою відповідної системи програмування на іншій обчислювальній системі.

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

    1. Реалізація функцій арі за допомогою зовнішніх бібліотек.

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

    Система програмування несе відповідальність тільки за те, щоб під’єднати об’єктний код бібліотеки до результуючої програми. Бібліотека може бути реалізована як статично завантажуваною, так і динамічно завантажуваною.

    З точки зору ефективності виконання коду цей метод реалізації АРІ має самі низькі результати, тому що зовнішня бібліотека звертається як до функцій ОС, так і до функцій відповідних бібліотек системного програмування. З погляду переміщуваності вихідного коду зовнішні бібліотеки повинні бути доступні в будь – якій з архітектур обчислювальних систем на які орієнтується розроблювана програма. Це можливо, коли зовнішня бібліотека підтримує певний стандарт і системи програмування також підтримують цей стандарт. Однак для більшості зовнішніх бібліотек інших фірм виробників це не так. Наприклад, бібліотека MFS (фірми Microsoft) і бібліотека VSE (фірми Borland) жорстко орієнтовані на архітектуру обчислювальної системи Windiws. Інший приклад, бібліотека SLX (фірми Borland) орієнтована на Windows і Linux.

    На даний час розвиток АРІ іде в напрямку створення бібліотек АРІ, які дозволяють переміщувати вихідний код. Однак, враховуючи корпоративні інтереси розробників програмного забезпечення створення єдиного АРІ, який би працював на будь – якій платформі є справою майбутнього.

    Щодо прикладного програмного забезпечення, то перспектива отримувати переміщуваний код надається таким технологіям, як технологія “клієнт – сервер”, або трьохрівнева архітектура створення програм (прикладна програма – клієнт сервер – функції операційної системи).

    Однією з основних характеристик АРІ повинна бути незалежність від системи програмування. Як правило, різні типи АРІ не стандартизовані. Кожному конкретному випадку набір викликів АРІ визначається архітектурою операційної системи та її призначення. В той же час стандартизується деякий обмежений набір функцій з метою полегшення переносу програм з однієї архітектури на іншу. Наприклад, до деякої міри стандарт Win АРІ фірми Microsoft є стандартизований. З точки зору Win АРІ основною задачею є вікно. Таким чином цей стандарт по визначенню орієнтований на роботу в графічному середовищі. Проте окремі функції цього стандарту (наприклад бібліотекиWin АРІ 32, Win АРІ 16, Win АРІ СЕ) не стандартизовані, що накладає певні обмеження при переносі програм з однієї ОС на іншу.

    1. Posix інтерфейс.

    POSIX (portable operation system interface for computer environment – платформенно незалежний інтерфейс операційних систем для комп’ютерного середовища).

    Цей інтерфейс стандартизований міжнародним інститутом ІЕЕЕ, який описує системні виклики для відкритих операційних систем, в тому числі оболонки, утиліти та інструментальні засоби. Крім того, згідно інтерфейсу POSIX стандартизованими також є задачі забезпечення безпеки задачі реального часу, задачі адміністрування, мережеві функції та задачі обробки трансакції. В основному POSIX інтерфейс стандартизований і використовується для ОС Unix, хоча він є реалізований для інших операційних систем.

    POSIX детально описує систему віртуальної пам’яті, багатозадачність та технологію переміщуваності операційних систем. Тому насправді POSIX є не єдиний стандарт, а набір стандартів POSIX.1 ... POSIX.12. Зокрема, стандарт POSIX.1 описує системний АРІ (мову програмування С), POSIX.4 – задачі реального часу, POSIX.6 – системну безпеку, POSIX.7 – адміністрування системи, POSIX.12 – графічний інтерфейс користувача, тощо. Таким чином програми, які розроблені з урахуванням даних стандартів будуть однаково виконуватись у всіх POSIX сумісних ОС. Однак, в деяких випадках POSIX стандарт має чисто рекомендаційний характер. Частина POSIX стандарту описана строго й детально і невиконання цих вимог не забезпечить переміщуваність програм, інша частина лише поверхнево описує основні вимоги. Деякі програми в документації можуть бути заявлені як POSIX сумісні, але вони такими не є. Ця ситуація виникає у випадках, коли з точки зору забезпечення продуктивності або з погляду впровадження фірмових технологій, які обмежують використання задачі відповідною операційною системою або операційним середовищем, для програмування використовуються інші функції, які безпосередньо працюють з ОС або апаратурою і не підтримують POSIX стандарт.

    Тема 14. Архітектура ОС Unix

    1. Основні поняття і визначення.

    2. Віртуальна машина.

    3. Типи та інтерфейс користувачів.

    4. Команди та командний інтерпретатор.

    5. Процеси та їх виконання.

    6. Підсистема вводу/виводу.

    7. Структура файлової системи.

    8. Засоби захисту файлів і даних.

    9. Сигнали і семафори.

    10. Програмні канали та черги повідомлень.

    11. Розділювана пам’ять та виклики віддалених процедур.

    12. Особливості ОС Linux.

    1. Основні поняття і визначення.

    Unix є прикладом виключно вдалої реалізації простої мультипрограмної і багатокористувацької ОС.

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

    • звертання до файлів, пристроїв вводу/виводу, буферів міжпроцесних повідомлень виконуються з допомогою одних і тих же примітивів;

    • одні і ті ж механізми найменування, присвоєння альтернативних імен і захисту від несанкціонованого доступу застосовується до файлів даних і до директорій і пристроїв;

    • одні і ті ж механізми працюють у відношенні програмних і апаратних ініціалізованих переривань.

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

    Unix системи поставляються з великим набором системних і прикладних програм, включаючи текстові редактори, інтерпретатори командної мови, компілятори з декількох популярних мов програмування (Perl, Assembler, Delphi, C, C++), компоновщики, відладчики, бібліотеки системних і користувацьких програм, засоби сортування і ведення баз даних, багаточисельні адміністративні і обслуговуючі програми. В Unix системах використовується ієрархічна файлова система з повним захистом, робота зі змінними томами (дисками), забезпечується незалежність від пристроїв. Центральною частиною системи Unix є ядро.

    1. Віртуальна машина.

    Система Unix є багато користувацькою, кожному користувачу після реєстрації надається віртуальний комп’ютер, в якому є всі необхідні ресурси:

    • процесор;

    • пам’ять;

    • пристрої;

    • файли.

    Поточний стан такого віртуального комп’ютера називається образом. Можна сказати, що процес – це виконання образу. Образ складається з:

    • образу пам’яті;

    • значень загальних регістрів процесора;

    • стану відкритих файлів;

    • поточної директорії і іншої інформації.

    Образ процесу під час його виконання розміщується в основній пам’яті (в старих системах вигружався на диск).

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

    • сегмент процедур (починається з нульового адресу у віртуальному адресному просторі процесу);

    • сегмент даних (розміщується після сегменту процедур і може зростати в сторону великих адресів);

    • сегмент стеку (починається зі старшого адресу і росте в сторону молодших адресів по мірі занесення в нього інформації при викликах підпрограм і при перериваннях).

    1. Типи та інтерфейс користувачів.

    ОС Unix при розробці планувалась як інтерактивна багатокористувацька система, іншими словами Unix призначена для мультитермінальної роботи. Щоб почати роботу потрібно ввійти в систему шляхом введення свого (account name) імені і можливо пароль. Користувач зареєстрований в облікових файлах системи і маючи account називається зареєстрованим користувачем системи. Реєстрація нових користувачів проводиться адміністратором.

    Файлова система OC Unix має деревоподібну структуру.

    Кожному зареєстрованому користувачу відповідає відповідний каталог (домашній каталог).

    Коротко розглянемо інтерфейс користувача. Традиційний спосіб взаємодії користувача з ОС Unix заснований на використанні командних мов. Після входу користувача в систему для нього запускається один із командних інтерпретаторів (в залежності від параметрів які зберігаються в файлі /etc/passwd). Загальна назва будь – якого командного інтерпретатора шел – оболонка. Визваний командний інтерпретатор дає запит дає запит на ввід користувачем командної стрічки, яка може містити просту команду, конвеєр команд, або послідовність команд. Після виконання наступної командної стрічки і видачі на екран терміналу або в файл потрібних результатів, shell знову робить запит на ввід нової командної стрічки.

    Командні мови які використовуються в ОС Unix є досить простими, для змоги швидкого навчання новими користувачами. Написання складних програм спирається механізм складних файлів shell – script.

    Привілейований користувач.

    Ядро ОС Unix ідентифікує кожного користувача по його ідентифікатору. Крім того кожен користувач відноситься до певної групи користувачів, яка також ідентифікується по деякому ідентифікатору. Значення цих ідентифікаторів зберігаються в облікових файлах системи.

    1. Команди та командний інтерпретатор.

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

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

    В ОС Unix існує мова програмування оболонки shell, яка складається з наступних частин:

    • службові конструкції, які дозволяють маніпулювати текстовими стрічками та будувати складні команди на мові простих;

    • вбудовані, які безпосередньо виконуються інтерпретатором;

    • команди, які представляються окремими виконуваними файлами.

    Простий приклад програмування на мові shell - вивід стрічки на екран.

    1. Процеси та їх виконання.

    Термін процес в ОС Unix розуміється як програма, яка виконується в власному віртуальному адресному просторі. Для створення нового процесу в ОС Unix використовуються наступні виклики АРІ:

    • fork ();

    • exec (ім’я програми яка завантажується).

    Виклик fork() створює новий адресний простір, стан якого є ідентичним головному процесу. Керування новим процесом передається на команду, яка безпосередньо знаходиться за викликом fork(). Виклик fork() повертає значення “0” в породженому процесі і ціле додаткове число в основному процесі. Це процес ідентифікації.

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

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

    В ОС Unix кожний процес є об’єктом який створюється в результаті виконання функції fork(). Кожний процес, за виключенням нульового (початкового) процесу, породжується в результаті завантаження чи виконання функції fork() у породженому процесі.

    Кожен процес має одного процеса – породжувача і в свою чергу може породжувати багато інших процесів.

    Нульовий (початковий) процес має ідентифікатор 0. Він породжується і виконується під час завантаження ОС. Після завантаження він реалізує механізм взаємодії з файлами підкачки, тобто реалізує механізм віртуальної пам’яті. Після процесу завантаження керування передається і який фактично є породжувачем усіх процесів ОС Unix.

    Процеси в загальному виконуються в одному з двох станів:

    • користувацькому стані – процес виконує тільки користувацьку програму і має доступ до користувацького сегменту даних;

    • системному стані – процес виконує підпрограми ядра ОС і має доступ до системного сегменту даних.

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

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

    Для розподілу процесорного часу між процесами використовуються дисципліни диспетчеризації.

    1. Підсистема вводу/виводу.

    Функції вводу/виводу в ОС Unix задаються за допомогою 5 системних викликів, а саме:

    • open;

    • close;

    • read;

    • write;

    • seek.

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

    • якщо читання (запис) відбувається перший раз з певного файлу, то воно відбувається послідовно з першого байту пам’яті;

    • якщо перед поточною операцією читання (запису) була попередня операція читання (запису), то буде зчитано (записано) байти з поточної позиції вказівника файлу;

    • якщо операції зчитування (запису) передувала команда пошуку seek, то поточна операція виконується з поточного зміщення вказівника файлу.

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

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

    • будь – яка операція вводу/виводу розглядається як запис в файл або зчитування з файлу. Клавіатура або термінал також інтерпретується як файл;

    • доступ до будь – якого файлу (пристрою) здійснюється через його дескриптор (номер). Існує декілька стандартних дескрипторів (файл з дескриптором 1 – стандартний ввід, 2 – стандартний вивід, 3 – стандартне повідомлення про помилки);

    • задача (чи процес) яка породжується в певному процесі наслідує всі відкриті дескриптори цього батьківського процесу.

    Тому для правильного функціонування підсистеми вводу/виводу доцільно при розробці власних програм забезпечити правильне використання системних дескрипторів (1 – stdin, 2 – stdout, 3 – stderr).

    1. Структура файлової системи.

    В файловій системі Unix це множина символів з послідовним або блоковим доступом. В файлі можуть міститися будь – які дані, які записуються туди користувачем. Файл не має ніякої внутрішньої структури, за виключенням тієї, яку накладає на неї користувач. Дані на вінчестері розміщуються по блоках розміром 512 байт. В загальному випадку диск розбивається на наступні області:

    • невикористовуваний (вільний) блок;

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

    • і – блок, який складається з опису файлів, які називаються і – вузлами;

    • область для зберігання вмісту файлів.

    Рис. 14.1. Організація файлів на диску Unix.

    Кожен і – вузол містить наступну інформацію:

    • ідентифікатор власника файлу;

    • ідентифікатор групи власника файлу;

    • біти захисту;

    • фізичну адресу на диску, де знаходиться вміст цього файлу;

    • розмір файлу;

    • час створення файлу;

    • час останньої модифікації файлу (використання);

    • час останньої зміни атрибутів файлу;

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

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

    Розподіл дискового простору під дані здійснюється блоками фіксованої довжини. Кожен файл однозначно ідентифікується чи визначається старшим номером пристрою, молодшим номером пристрою та і – номером. Файли директорії встановлюються у відповідність між іменами файлів і самими файлами, що розміщені на диску.

    Директорії мають деревовидну структуру. На кожен файл або файл пристрою є вказівники, які можуть міститися в різних вузлах цієї структури (файлової структури) і імена файлів задаються послідовністю імен директорій, в яких міститься даний файл. Ця послідовність починається з символу “/”, що означає кореневий каталог, або машина дерева.

    Звичайний файл, який не є директорією, може зустрічатися в різних директоріях і можливо під різними іменами. Ця властивість називається зв’язувальною. Елемент директорії, який відноситься до одного файлу називається зв’язком.

    В системах Unix такі зв’язки мають однаковий статус чи права. Файли не належать директоріям, а зв’язки в цих директорія вказують на фізичний файл розміщений на диску.

    1. Засоби захисту файлів і даних.

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

    • читання;

    • запис;

    • виконання.

    Ці права доступу надаються трьом класам користувачів:

    • власнику файлу (користувач, який створив файл);

    • групі в яку входить власник;

    • всім іншим користувачам.

    Кожен файл завжди зв’язаний зі своїм власником, а також групою користувачів в яку входить власник, тобто має певні визначені ідентифікатори UID (user ID) та GID (group ID). Права доступу до файлу може міняти тільки власник, змінити власника файлу може тільки супервізор (адміністратор), змінити групу до якої відноситься файл може адміністратор або власник файлу. Задача, яка виконується в ОС Unix завжди завантажується на виконання від імені певного користувача та від імені певної групи.

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

    При створенні файл він отримує UID (номер користувача), який співпадає з номером FSUID і відповідно отримує ідентифікатор GID та FSGID. При створенні файлу модифікується не сам файл, а каталог, в якому розміщуються нові посилання на новий файл. Знищення файлу полягає в знищенні посилання на нього. Таким чином для створення/знищення файлу в користувача повинно бути право на запис в каталог.

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

    1. Сигнали і семафори.

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

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

    • значення семафору;

    • номер процесу, який останній працював з цим семафором;

    • число процесів, які очікують збільшення значення семафору;

    • число процесів, які очікують нульового значення семафору.

    Для роботи з семафорами є три наступні системні виклики:

    • semget, створення і отримання доступу до набору семафорів;

    • semop, для маніпуляції (зміни) значень семафорів;

    • semctl, для виконання різноманітних керуючих операцій над набором семафорів.

    1. Програмні канали та черги повідомлень.

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

    Unix розділяє два типи програмних каналів:

    • іменований канал використовується для взаємодії та синхронізації довільних процесів, які знають ім’я цього програмного каналу і мають відповідні права доступу;

    • неіменованим програмним каналом може користуватися тільки процес, який створив його та процеси, які породжені цим головним процесом.

    Для того, щоб створити іменований програмний канал використовується виклик open, щоб створити неіменований програмний канал використовується спеціальний виклик pipe.

    Операції зчитування/запису в каналах здійснюється за допомогою системних файлових викликів (read, write, close).

    Наступним механізмом міжпроцесорної взаємодії є механізм черг повідомлень, що підтримується наступними системними викликами:

    • msgget (message get) – створює нову чергу повідомлень і отримання дескриптора нової черги;

    • msgsnd (message send) – для відправки повідомлень, тобто для запису повідомлень у відповідну чергу;

    • msgrev (message resive) – служить для прийому повідомлення, тобто для вибору повідомлення з певної черги;

    • msgctl (message control) – системний виклик для здійснення керуючих функцій.

    Ядро ОС зберігає повідомлення у вигляді зв’язаного списку, номер певної черги повідомлень є індексом в певному системному масиві, який містить вказівники на всі черги повіідомлень.

    1. Розділювана пам’ять та виклики віддалених процедур.

    Для роботи з розділювальною пам’яттю використовуються команди:

    • shmget, створює новий сегмент розділюваної пам’яті, або знаходить існуючий сегмент для використання;

    • shmat, під’єднує сегмент з вказаним дескриптором до віртуальної пам’яті процесу, який звертається до неї;

    • shmdt, відключає від віртуальної пам’яті раніше під’єднаний сегмент розділюваної пам’яті;

    • shmctl, використовується для керування різними параметрами які зв’язані з поточним існуючим (зв’язаним) сегментом.

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

    Виклик віддалених процедур RPC використовується для забезпечення функціонування взаємодіючих процесів, які знаходяться на різних комп’ютерах.

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

    Механізм виклику віддаленої процедури складається з:

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

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

    119