- •1.1. Поняття операційної системи, її призначення та функції
- •1.1.1. Поняття операційної системи
- •1.1.2. Призначення операційної системи
- •1.1.3. Операційна система як розширена машина
- •1.1.4. Операційна система як розподілювач ресурсів
- •1.2. Історія розвитку операційних систем
- •1.3. Класифікація сучасних операційних систем
- •1.4. Функціональні компоненти операційних систем
- •1.4.1. Керування процесами й потоками
- •1.4.2. Керування пам'яттю
- •1.4.3. Керування введенням-виведенням
- •1.4.4. Керування файлами та файлові системи
- •1.4.5. Мережна підтримка
- •1.4.6. Безпека даних
- •1.4.7. Інтерфейс користувача
- •2.1. Базові поняття архітектури операційних систем
- •2.1.1. Механізми і політика
- •2.1.2. Ядро системи. Привілейований режим і
- •2.2. Реалізація архітектури операційних систем
- •2.2.1. Монолітні системи
- •2.2.2. Багаторівневі системи
- •2.2.3. Системи з мікроядром
- •2.2.4. Концепція віртуальних машин
- •2.3.1. Взаємодія ос і апаратного забезпечення
- •2.3.2. Взаємодія ос і виконуваного програмного коду
- •2.4.1. Базова архітектура unix
- •2.4.2. Архітектура Linux
- •2.5. Особливості архітектури: Windows хр
- •2.5.1. Компоненти режиму ядра
- •2.5.2. Компоненти режиму користувача
- •2.5.3. Об'єктна архітектура Windows хр
- •3.1. Базові поняття процесів і потоків
- •3.1.1. Процеси і потоки в сучасних ос
- •3.1.2. Моделі процесів і потоків
- •3.1.3. Складові елементи процесів і потоків
- •3.2. Багатопотоковість та її реалізація
- •3.2.1. Поняття паралелізму
- •3.2.2. Види паралелізму
- •3.2.3. Переваги і недоліки багатопотоковості
- •3.2.4. Способи реалізації моделі потоків
- •3.3. Стани процесів і потоків
- •3.4. Опис процесів і потоків
- •3.4.1. Керуючі блоки процесів і потоків
- •3.4.2. Образи процесу і потоку
- •3.5. Перемикання контексту й обробка переривань
- •3.5.1. Організація перемикання контексту
- •3.5.2. Обробка переривань
- •3.6. Створення і завершення процесів і потоків
- •3.6.1.Створення процесів
- •3.6.2.Ієрархія процесів
- •3.6.3.Керування адресним простором під час створення процесів
- •3.6.4. Особливості завершення процесів
- •3.6.5. Синхронне й асинхронне виконання процесів
- •3.6.6. Створення і завершення потоків
- •4.1. Загальні принципи планування
- •4.1.1. Особливості виконання потоків
- •4.1.2. Механізми і політика планування
- •4.1.3. Застосовність принципів планування
- •4.2. Види планування
- •4.2.1. Довготермінове планування
- •4.2.2. Середньотермінове планування
- •4.2.3. Короткотермінове планування
- •4.3. Стратегії планування. Витісняльна і невитісняльна багатозадачність
- •4.4. Алгоритми планування
- •4.4.1. Планування за принципом fifo
- •4.4.2. Кругове планування
- •4.4.3. Планування із пріоритетами
- •4.4.4. Планування на підставі характеристик подальшого виконання
- •4.4.5. Багаторівневі черги зі зворотним зв'язком
- •4.4.6. Лотерейне планування
- •4.5. Реалізація планування в Linux
- •4.5.1. Планування процесів реального часу в ядрі
- •6.1. Види міжпроцесової взаємодії
- •6.1.1.Методи розподілюваної пам'яті
- •6.1.2.Методи передавання повідомлень
- •6.1.3.Технологія відображуваної пам'яті
- •6.1.4.Особливості міжпроцесової взаємодії
- •6.2. Базові механізми міжпроцесової взаємодії
- •6.2.1. Міжпроцесова взаємодія на базі спільної пам'яті
- •6.2.2. Основи передавання повідомлень
- •6.2.3. Технології передавання повідомлень
- •8.1. Основи технології віртуальної пам'яті
- •8.1.1. Поняття віртуальної пам'яті
- •8.1.2. Проблеми реалізації віртуальної пам'яті. Фрагментація пам'яті
- •8.1.4. Підхід базового і межового регістрів
- •8.2. Сегментація пам'яті
- •8.2.1. Особливості сегментації пам'яті
- •8.2.2. Реалізація сегментації в архітектурі іа-32
- •8.3. Сторінкова організація пам'яті
- •8.3.1. Базові принципи сторінкової організації пам'яті
- •8.3.2. Порівняльний аналіз сторінкової організації пам'яті та сегментації
- •8.3.3. Багаторівневі таблиці сторінок
- •8.3.4. Реалізація таблиць сторінок в архітектурі іа-32
- •8.3.5. Асоціативна пам'ять
- •8.4. Сторінково-сегментна організація пам'яті
- •8.5. Реалізація керування основною пам'яттю: Linux
- •8.5.1. Використання сегментації в Linux. Формування логічних адрес
- •8.5.2. Сторінкова адресація в Linux
- •8.5.3. Розташування ядра у фізичній пам'яті
- •8.5.4.Особливості адресації процесів і ядра
- •8.5.5.Використання асоціативної пам'яті
- •8.6. Реалізація керування основною пам'яттю: Windows хр
- •8.6.1.Сегментація у Windows хр
- •8.6.2.Сторінкова адресація у Windows хр
- •8.6.3.Особливості адресації процесів і ядра
- •8.6.4. Структура адресного простору процесів і ядра
- •11.1. Поняття файла і файлової системи
- •11.1.1. Поняття файла
- •11.1.2.Поняття файлової системи
- •11.1.3.Типи файлів
- •11.1.4. Імена файлів
- •11.2. Організація інформації у файловій системі
- •11.2.1. Розділи
- •11.2.2. Каталоги
- •11.2.3. Зв'язок розділів і структури каталогів
- •11.3. Зв'язки
- •11.3.1. Жорсткі зв'язки
- •11.3.2. Символічні зв'язки
- •11.4. Атрибути файлів
- •11.5. Операції над файлами і каталогами
- •11.5.1. Підходи до використання файлів процесами
- •12.1. Базові відомості про дискові пристрої
- •12.1.1. Принцип дії жорсткого диска
- •12.1.2. Ефективність операцій доступу до диска
- •12.2. Розміщення інформації у файлових системах
- •12.2.1. Фізична організація розділів на диску
- •12.2.2. Основні вимоги до фізичної організації файлових систем
- •12.2.3. Неперервне розміщення файлів
- •12.2.4. Розміщення файлів зв'язними списками
- •12.2.5. Індексоване розміщення файлів
- •12.2.6. Організація каталогів
- •15.1. Завдання підсистеми введення-виведення
- •15.1.1. Забезпечення ефективності доступу до пристроїв
- •15.1.2. Забезпечення спільного використання зовнішніх пристроїв
- •15.1.3. Універсальність інтерфейсу прикладного програмування
- •15.1.4. Універсальність інтерфейсу драйверів пристроїв
- •15.2. Організація підсистеми введення-виведення
- •15.2.1. Символьні, блокові та мережні драйвери пристроїв
- •15.2.2. Відокремлення механізму від політики за допомогою
- •15.3. Способи виконання операцій введення-виведення
- •15.3.1. Опитування пристроїв
- •15.3.2. Введення-виведення, кероване перериваннями
- •15.3.3. Прямий доступ до пам'яті
- •15.4. Підсистема введення-виведення ядра
- •15.4.1. Планування операцій введення-виведення
- •15.4.2. Буферизація
- •15.7. Керування введенням-виведенням: unix і Linux
- •15.7.1. Інтерфейс файлової системи
- •15.7.2. Передавання параметрів драйверу
- •15.7.3. Структура драйвера
- •15.7.4. Виконання операції введення-виведення для пристрою
- •15.8. Керування введенням-виведенням: Windows хр
- •15.8.1. Основні компоненти підсистеми введення-виведення
- •15.8.2. Виконання операції введення-виведення для пристрою
- •15.8.3. Передавання параметрів драйверу пристрою
- •17.1. Термінальне введення-виведення
- •17.1.1. Організація термінального введення-виведення
- •17.1.3. Термінальне введення-виведення у Win32 api
- •17.2. Командний інтерфейс користувача 17.2.1.
- •17.2.2. Переспрямування потоків введення-виведення
- •17.2.3. Використання каналів
- •17.3. Графічний інтерфейс користувача
- •17.3.1. Інтерфейс віконної та графічної підсистеми Windows хр
- •17.3.2. Система X Window
- •17.4. Процеси без взаємодії із користувачем
- •17.4.1. Фонові процеси на основі posix
- •17.4.2. Служби Windows хр
- •16.1. Загальні принципи мережної підтримки
- •16.1.1. Рівні мережної архітектури і мережні сервіси
- •16.1.2. Мережні протоколи
- •16.2. Реалізація стека протоколів Інтернету
- •16.2.1. Рівні мережної архітектури tcp/ip
- •16.2.2. Канальний рівень
- •16.2.3. Мережний рівень
- •16.2.4. Транспортний рівень
- •16.2.5. Передавання даних стеком протоколів Інтернету
- •16.3. Система імен dns
- •16.3.1. Загальна характеристика dns
- •16.3.2. Простір імен dns
- •16.3.3. Розподіл відповідальності
- •16.3.4. Отримання ір-адрес
- •16.3.5. Кешування ір-адрес
- •16.3.6. Типи dns-ресурсів
- •16.4. Програмний інтерфейс сокетів Берклі
- •16.4.1. Особливості роботи з адресами
- •16.4.2. Створення сокетів
- •16.4.3. Робота з потоковими сонетами
- •16.4.4. Введення-виведення з повідомленням
- •19.1. Загальні принципи завантаження ос
- •19.1.1. Апаратна ініціалізація комп'ютера
- •19.1.2. Завантажувач ос
- •19.1.3. Двоетапне завантаження
- •19.1.4. Завантаження та ініціалізація ядра
- •19.1.5. Завантаження компонентів системи
- •19.2. Завантаження Linux
- •19.2.1. Особливості завантажувача Linux
- •19.2.2. Ініціалізація ядра
- •19.2.3. Виконання процесу init
- •19.3. Завантаження Windows хр
- •20.1. Багатопроцесорні системи
- •20.1.1. Типи багатопроцесорних систем
- •20.1.2. Підтримка багатопроцесорності в операційних системах
- •20.1.3. Продуктивність багатопроцесорних систем
- •20.1.4. Планування у багатопроцесорних системах
- •20.1.5. Спорідненість процесора
- •20.1.6. Підтримка багатопроцесорності в Linux
- •20.1.7. Підтримка багатопроцесорності у Windows хр
- •20.2. Принципи розробки розподілених систем
- •20.2.1. Віддалені виклики процедур
- •20.2.2. Використання Sun rpc
- •20.2.3. Використання Microsoft rpc
- •20.2.4. Обробка помилок і координація в розподілених системах
- •20.3. Розподілені файлові системи
- •20.3.1. Організація розподілених файлових систем
- •20.3.2. Файлова система nfs
- •20.3.3. Файлова система Microsoft dfs
- •20.4. Сучасні архітектури розподілених систем
- •20.4.1. Кластеры системи
- •20.4.2. Grid-системи
- •18.1. Основні завдання забезпечення безпеки
- •18.2. Базові поняття криптографії
- •18.2.1. Поняття криптографічного алгоритму і протоколу
- •18.2.2. Криптосистеми з секретним ключем
- •18.2.3. Криптосистеми із відкритим ключем
- •18.2.4. Гібридні криптосистеми
- •18.2.5. Цифрові підписи
- •18.2.6. Сертифікати
- •18.3. Принципи аутентифікаціїі керування доступом
- •18.3.1. Основи аутентифікації
- •18.3.2. Основи керування доступом
- •18.4. Аутентифікація та керування доступом в unix
- •18.4.1. Облікові записи користувачів
- •18.4.2. Аутентифікація
- •18.4.3. Керування доступом
- •18.5. Аутентифікація і керування доступом у Windows xp
- •18.5.1. Загальна архітектура безпеки
- •18.5.2. Аутентифікація
- •18.5.3. Керування доступом
- •18.6. Аудит
- •18.6.1. Загальні принципи організації аудиту
- •18.6.2. Робота із системним журналом unix
- •18.6.3. Журнал подій Windows xp
- •18.7. Локальна безпека даних
- •18.7.1. Принципи шифрування даних на файлових системах
- •18.7.2. Підтримка шифрувальних файлових систем у Linux
- •18.7.3. Шифрувальна файлова система Windows xp
- •18.8. Мережна безпека даних
- •18.8.1. Шифрування каналів зв'язку
- •18.8.2. Захист інформації на мережному рівні
- •18.8.3. Захист інформації на транспортному рівні
- •18.9. Атаки і боротьба з ними
- •18.9.1. Переповнення буфера
- •18.9.2. Відмова від обслуговування
- •18.9.3. Квоти дискового простору
- •18.9.4. Зміна кореневого каталогу застосування
16.4. Програмний інтерфейс сокетів Берклі
У розділі 6 наводилися загальні принципи взаємодії між клієнтом і сервером у разі використання сокетів. У цьому розділі опишемо особливості використання інтерфейсу сокетів Берклі (Berkeley Sockets) [38, 47, 75, 106].
Програмний інтерфейс сокетів Берклі - це засіб зв'язку між прикладним рівнем мережної архітектури TCP/IP і транспортним рівнем. Причина такого розташування полягає в тому, що це засіб зв'язку між кодом застосування (який виконують на прикладному рівні) і реалізацією стека протоколу ОС (найвищим рівнем якої є транспортний). Фактично цей інтерфейс є набором системних викликів ОС.
Назва цього АРІ пов'язана з тим, що він уперше був реалізований у 80-х роках XX століття у версії UNIX, розробленій Каліфорнійським університетом у Берклі (BSD UNIX).
16.4.1. Особливості роботи з адресами
Цей розділ буде присвячено особливостям відображення даних про адреси і порти, необхідних для використання сокетів.
Відображення адрес сокетів
Більшість системних викликів роботи із сокетами приймають як параметри покажчики на спеціальні структури даних, що відображають адреси сокетів. У разі використання TCP/IP зі звичайним ІР-протоколом (IPv4) адресу задають структурою sockaddrin. Вона визначена у заголовному файлі <netinet/in.h> і містить, зокрема, такі поля:
♦ sin_family - для TCP/IP має дорівнювати константі AF_INET;
Sin_port - цілочисловий номер порту для TCP або UDP;
♦ sin_addr - відображення IP-адреси (структура і naddr з одним полем saddr).
Реалізуючі системні виклики роботи із сокетами, необхідно враховувати можливість використання різних протоколів, а отже, передавання в них різних структур, що відображають адреси. Під час розробки АРІ сокетів Берклі було ухвалено рішення використати як універсальний тип відображення адрес покажчик на спеціальну структуру sockaddr, визначену у <sys/socket.h>.
Наприклад, прототип системного виклику bindO, що пов'язує сокет з адресою, має такий вигляд:
int bindOnt. struct sockaddr *. socklent):
На практиці адреса задається так: визначають структуру типу sockaddr і п і під час виклику покажчик на неї перетворюють до sockaddr *:
struct sockaddr_in my_addr:
II ... заповнення структури my_addr. див. далі
bind(sockfd. (struct sockaddr *) &my_addr, sizeof(my_addr));
Безпосередньо структуру sockaddr у застосуваннях не використовують. Якщо виклик повернув покажчик на неї, перед використанням у застосуванні його потрібно привести до покажчика на структуру для конкретного протоколу (наприклад, на sockaddr_in).
Порядок байтів
Історично так склалося, що відображення у пам'яті даних, для яких виділяють більш як один байт (наприклад, двобайтового цілого, що відповідає у С типу short), відрізняється для різних комп'ютерних архітектур. У деяких із них старший байт розташовують у пам'яті перед молодшим (такий порядок називають зворотним -big-endian byte order), а в інших - молодший перед старшим (це прямий порядок - little-endian byte order). Наприклад, архітектура ІА-32 використовує прямий порядок байтів, а комп'ютери Sun Sparestation та Power PC - зворотний.
Проблема полягає в тому, що деякі елементи пакетів (керуючі дані), якими обмінюються комп'ютери для організації передавання інформації, займають у пам'яті більш як один байт. Так, відображення порту займає 2 байти, а IP-адреси -4 байти. Якщо такий блок інформації буде передано комп'ютеру з іншим порядком байтів, він не зможе коректно його інтерпретувати.
Для вирішення цієї проблеми реалізації стека протоколів на клієнті та на сервері потрібно під час передавання даних мережею узгоджено використовувати єдиний порядок байтів. Такий порядок, який називають мережним порядком байтів (network byte order), визначає мережний протокол. Фактично, це зворотний порядок. Відповідно, порядок байтів, прийнятий для локального комп'ютера, називають порядком байтів хоста (host byte order). Він може бути як прямим, так і зворотним.
Програміст має перетворювати керуючі дані в мережний порядок байтів перед передаванням інформації із мережі та робити зворотне перетворення після її отримання. Це зокрема стосується IP-адрес і номерів портів. Для реалізації перетворення використовують функції htonK) і htonsO (перетворення до мережного порядку), ntohl () і ntohs() (перетворення до порядку хоста):
#include <netinet/in.h>
uintl6_t htons(uintl6_t hostval): // htonlO - для 32-бітних даних
uintl6_t ntohs(uintl6_t netval): // ntohlO - для 32-бітних даних
Далі наведемо приклади використання цих функцій.
Робота з ІР-адресами
У протоколі IPv4 IP-адреса є цілим значенням розміром 4 байти. Для того щоб перетворити крапково-десяткове подання такої адреси (n. n. п. п) у ціле число, слід використати функцію inet_aton():
#include <arpa/inet.h>
int inet_aton(const char *c_ip. struct in_addr *s_ip);
де: c_ip - рядкове відображення IP-адреси: "192.168.10.28";
s_ip - структура inaddr, що міститиме цілочислове відображення адреси, розташоване в пам'яті відповідно до мережного порядку байтів (поле S addr); цю структуру заповнюють усередині виклику.
У разі успішного перетворення ця функція повертає ненульове значення, у разі помилки — нуль.
Розглянемо приклад заповнення структури, що задає адресу сокета:
struct sockaddrin my_addr = { 0 }: // структура має бути обнулена
my_addr.sin_family = AFINET:
my_addr.sin_port = htons(7500); // задання порту
inet_aton("192.168.10.28". &(my_addr.sin_addr)): // задання адреси
Для обнулення структур часто використовують функцію bzero():
include <strings.h>
bzero(&my_addr. sizeof(my_addr)):
// заповнення my_addr
Зворотне перетворення IP-адреси (із цілого числа у крапково-десяткове подання) здійснюють функцією ine_tntoра():
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr sip):
Ця функція розміщає у статичному буфері рядок із крапково-десятковим поданням IP-адреси, заданої структурою s_ip, і повертає покажчик на цей буфер:
printfС'ІР-адреса: *s\n". inet_ntoa(my_addr.s_addr));
Зазначимо, що наступні спроби виклику функції стиратимуть статичний буфер, тому для подальшого використання його вміст потрібно копіювати в окремий буфер пам'яті.