# Лекционный материал: Внутреннее устройство операционных систем

---

## Раздел 1. Фундаментальные принципы и архитектура ядер

### 1.1. Режимы работы процессора и системные вызовы
Операционная система выступает посредником между аппаратным обеспечением и пользовательскими программами. Для обеспечения безопасности и надежности современное аппаратное обеспечение поддерживает разделение режимов исполнения:
* **Режим ядра (Kernel Mode / Supervisor Mode)**: режим с полным и неограниченным доступом ко всем инструкциям процессора, регистрам и аппаратному обеспечению. В нем выполняется ядро операционной системы.
* **Режим пользователя (User Mode)**: режим с ограниченным набором инструкций. Программам пользователя запрещено напрямую выполнять управляющие команды и операции ввода-вывода.

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

### 1.2. Классификация архитектур ядер

#### Монолитные системы (Monolithic Kernels)
Вся операционная система скомпонована и работает как единая программа в режиме ядра. Все процедуры ядра могут напрямую вызывать друг друга.
* **Достоинства**: максимальная скорость и эффективность взаимодействия между подсистемами.
* **Недостатки**: отсутствие изоляции — ошибка или сбой в любой процедуре (например, в дефектном драйвере) приводит к падению всей системы.
Для гибкости современные монолитные ядра (например, Linux) поддерживают **динамически загружаемые модули ядра** (драйверы устройств, файловые системы), которые подгружаются в память по мере необходимости.

#### Многоуровневые системы и кольца защиты (Layered Systems & Protection Rings)
Операционная система организуется в виде иерархии слоев (например, система THE) или концентрических колец защиты (MULTICS). Внутренние слои/кольца обладают максимальными привилегиями, а внешние — меньшими. Вызов функций внутренних слоев строго контролируется и проверяется аппаратными и программными шлюзами.

#### Микроядерная архитектура (Microkernels)
Основная идея — минимизация объема кода, работающего в режиме ядра, ради достижения максимальной надежности. В режиме ядра работает только **микроядро**, выполняющее базовое планирование, управление прерываниями и межпроцессное взаимодействие (IPC). Все остальные службы (драйверы устройств, файловые системы, менеджеры процессов) выполняются как обычные изолированные процессы в пользовательском режиме.
* **Достоинства**: высокий уровень изолированности сбоев. Сбой драйвера (например, звуковой карты) не вызовет падения ядра. Соблюдается **принцип наименьших полномочий (POLA — Principle of Least Authority)**.
* **Примеры**: MINIX 3, QNX, L4, Mach.
* **Разделение механизма и политики**: ядро содержит только базовые механизмы (например, переключение процессов), а выбор политики (например, назначение приоритетов) выносится в пользовательское пространство.

#### Экзоядра (Exokernels) и Униядра (Unikernels)
* **Экзоядро**: нижний уровень ядра отвечает только за безопасное разделение и распределение физических ресурсов между виртуальными машинами без создания сложного уровня абстракций.
* **Униядро**: специализированная минимальная система, где библиотеки операционной системы (LibOS) компонуются напрямую с одним единственным приложением в едином адресном пространстве для работы в виртуальной среде.

#### Практический пример: Структура ядра Windows NT
Windows NT использует гибридную структурированную модель:
1. **HAL (Hardware Abstraction Layer — `hal.dll`)**: самый нижний слой, скрывающий специфику конкретной материнской платы, шин и контроллеров прерываний.
2. **Уровень ядра NTOS Kernel**: управляет планированием потоков, прерываниями, ловушками и первичной синхронизацией.
3. **Исполнительный уровень NTOS Executive (`ntoskrnl.exe`)**: содержит менеджеры ресурсов — **Object Manager** (управление объектами ядра и правами), **Process Manager**, **Memory Manager**, **I/O Manager**.

---

## Раздел 2. Управление процессами и потоками

### 2.1. Концепция процесса и его структура
**Процесс** — это программа в стадии выполнения. Процесс объединяет в себе ресурсы и контекст исполнения:
1. **Адресное пространство**:
   * **Сегмент текста (Text segment)**: машинный код программы (read-only).
   * **Сегмент данных (Data segment)**: инициализированные и неинициализированные (BSS) глобальные переменные, куча (heap).
   * **Сегмент стека (Stack segment)**: локальные переменные, параметры функций и адреса возврата.
2. **Блок управления процессом (PCB — Process Control Block / Process Table Entry)**: структура данных в памяти ядра, содержащая:
   * Состояние процесса, счетчик команд (PC), регистры процессора.
   * Указатели на сегменты памяти и таблицы страниц.
   * Таблицу открытых дескрипторов файлов.
   * Учетную информацию, приоритеты и сигналы.

### 2.2. Реализация потоков (Threads)
Поток является единицей планирования CPU в рамках процесса. Все потоки одного процесса разделяют единое адресное пространство и открытые файлы, но имеют собственные стеки и регистры.

#### Модели реализации:
* **Потоки пользовательского уровня (User-Level Threads)**: управление потоками осуществляется библиотекой времени выполнения в пространстве пользователя. Переключение между потоками происходит очень быстро (без инструкций `TRAP` и смены контекста ядра), но если один поток блокируется на системном вызове, блокируется весь процесс.
* **Потоки уровня ядра (Kernel-Level Threads)**: ядро осведомлено о каждом потоке и планирует их напрямую. Блокировка одного потока не останавливает остальные потоки процесса.

### 2.3. Специфика реализации в Linux и Windows

#### Linux: Концепция Задач (Tasks) и вызов `clone`
В Linux нет жесткого структурного разделения между процессами и потоками на уровне ядра — любые контексты исполнения представлены единой структурой `task_struct`.
* **Системный вызов `clone`**: создание новых процессов и потоков осуществляется через `clone` с передачей битовой маски флагов совместного использования ресурсов (`sharing_flags`):
  * `CLONE_VM`: совместное использование виртуальной памяти (создание потока).
  * `CLONE_FILES`: совместное использование таблицы дескрипторов файлов.
  * `CLONE_FS`: совместное использование информации о файловой системе (корневой и рабочий каталоги).
  * `CLONE_SIGHAND`: совместная таблица обработчиков сигналов.
* **Механизм Copy-On-Write (COW)**: при вызове `fork` дублируются только таблицы страниц, а сами физические страницы помещаются как read-only. Реальное копирование страницы происходит только тогда, когда один из процессов пытается в нее записать.

#### Windows: Структуры PEB и TEB
В Windows процессы служат контейнерами ресурсов, а потоки — объектами планирования.
* **PEB (Process Environment Block)**: структура данных процесса в пользовательском пространстве (список загруженных DLL, переменные окружения, параметры кучи).
* **TEB (Thread Environment Block)**: структура данных потока в пользовательском пространстве (Thread Local Storage — TLS, данные локализации).

---

## Раздел 3. Подсистема управления памятью

### 3.1. Виртуальная память и MMU
Для защиты процессов друг от друга и обеспечения работы с памятью, превышающей физический объем RAM, используется **виртуальная память**.
* **Блок управления памятью (MMU — Memory Management Unit)**: аппаратный блок процессора, который транслирует виртуальные адреса процесса в физические адреса на основе таблиц страниц, поддерживаемых ядром.
* **Страницы и Страничные фреймы (Pages & Page Frames)**: виртуальное адресное пространство разбивается на фиксированные блоки — страницы (обычно 4 КБ), а физическая память — на фреймы аналогичного размера.

При обращении к странице, отсутствующей в RAM, MMU генерирует прерывание **Page Fault (страничный сбой)**. Ядро перехватывает его, считывает нужную страницу с диска в свободный фрейм и обновляет таблицу страниц. Для ускорения трансляции адресов применяется аппаратный кэш **TLB (Translation Lookaside Buffer)**.

### 3.2. Распределение физической памяти в ядре (на примере Linux)

#### Страничный распределитель и «Приятельский» алгоритм (Buddy Algorithm)
Для распределения непрерывных блоков физических страниц ядро использует **Buddy Algorithm**:
1. Все запросы памяти округляются до степени 2 (например, 1, 2, 4, 8, 16 страниц).
2. Если в списке нужного размера нет свободного блока, более крупный блок делится пополам («приятели») до тех пор, пока не получим блок требуемого размера.
3. При освобождении блока ядро проверяет, свободен ли его «приятель», и если да — объединяет их обратно в единый крупный блок.

#### Слаб-распределитель (Slab Allocator)
Поскольку «приятельский» алгоритм приводит к внутренней фрагментации при запросах мелких объектов, поверх него работает **Slab Allocator**. Он запрашивает у Buddy-распределителя крупные страницы и нарезает их на фиксированные объекты ядра определенного типа (например, кэши для структур `task_struct`, `vm_area_struct` и дескрипторов файлов).

```
+-------------------------------------------------------------+
|                     Физическая Память                       |
+-------------------------------------------------------------+
                              |
                     [ Page Allocator ]
                  (Buddy Algorithm: 1..2^N)
                              |
                     [ Slab Allocator ]
               (Object Caches: task_struct и др.)
```

### 3.3. Подкачка (Swapping/Paging) и замещение страниц
Если система испытывает нехватку физической памяти, вступает в действие подсистема выгрузки страниц в область подкачки (**Swap Area**).
* **Алгоритм PFRA (Page Frame Reclaiming Algorithm)**: сканирует списки активных и неактивных страниц (используя модифицированный алгоритм часов) и освобождает память.
* **Демоны памяти**: фоновые процессы ядра (`kswapd` / `page daemon` и потоки `pdflush`) регулярно просыпаются для сброса «грязных» страниц (измененных данных) на диск и поддержания пула свободных фреймов.

### 3.4. Отображение файлов в память (Memory-Mapped Files)
Системный вызов `mmap` позволяет отобразить файл непосредственно в виртуальное адресное пространство процесса. Чтение и запись выполняются через работу с указателями в памяти без явных вызовов `read`/`write`. Это также эффективный механизм создания разделяемой памяти между несколькими процессами.

---

## Раздел 4. Подсистема ввода-вывода и файловые системы

### 4.1. Архитектура ввода-вывода
Операционная система классифицирует драйверы устройств на две основные группы:
1. **Символьные устройства (Character Devices)**: передают данные последовательно, байт за байтом без произвольного позиционирования (терминалы, клавиатуры, последовательные порты).
2. **Блочные устройства (Block Devices)**: хранят данные в блоках фиксированного размера с поддержкой произвольного доступа и поиска (жесткие диски, SSD).

### 4.2. Виртуальная файловая система (VFS)
Для того чтобы пользовательские программы могли прозрачно работать с самыми разными файловыми системами (ext4, NTFS, NFS, procfs), ядро предоставляет слой абстракции — **Virtual File System (VFS)**. VFS предоставляет единый интерфейс системных вызовов (`open`, `read`, `write`, `close`).

```
+-------------------------------------------------------------+
|                Пользовательские Процессы                    |
+-------------------------------------------------------------+
                              | (Системные вызовы: read, write)
+-------------------------------------------------------------+
|             Virtual File System (VFS) Level                 |
+-------------------------------------------------------------+
        |                     |                     |
   [ ext4 FS ]           [ NTFS FS ]           [ procfs ]
        |                     |                     |
+-------------------------------------------------------------+
|                   Драйверы Устройств                        |
+-------------------------------------------------------------+
```

### 4.3. Индексные дескрипторы (i-node) и структура файлов
В UNIX-подобных системах метаданные файла отделены от его имени:
* **Индексный дескриптор (i-node)**: структура на диске и в памяти, хранящая тип файла, права доступа, UID/GID владельца, размер, время модификации и указатели на дисковые блоки с данными файла.
* **Каталог**: специальный файл, содержащий список пар `(имя файла, номер i-node)`.
* **Таблица описания открытых файлов**: системная таблица в ядре, хранящая текущее смещение (указатель позиции чтения/записи) и флаги открытого файла, на которую ссылаются индивидуальные дескрипторы процессов.

### 4.4. Специальные (псевдо) файловые системы в Linux
Linux предоставляет доступ к внутренним структурам ядра через механизмы виртуальных файловых систем:
* **`/proc`**: содержит информацию о запущенных процессах (каталоги `/proc/[PID]`) и динамическую статистику ядра/оборудования (например, `/proc/cpuinfo`, `/proc/meminfo`).
* **`/sys` (sysfs)**: иерархическое отражение топологии устройств, шин и драйверов системы.
* **`tmpfs`**: временная файловая система, размещаемая непосредственно в оперативную память и swap.

