Основы операционных систем

Курс охватывает фундаментальные принципы работы современных операционных систем, включая архитектуру ядра, управление ресурсами и взаимодействие с аппаратным обеспечением. Студенты изучат механизмы работы процессов, памяти, файловых систем и основы компьютерной безопасности.

1. Введение в архитектуру ОС: история развития, функции ядра и системные вызовы

Введение в архитектуру ОС: история развития, функции ядра и системные вызовы

Добро пожаловать в курс «Основы операционных систем». Представьте, что вы купили самый современный, мощный и дорогой компьютер. У него лучший процессор, гигабайты оперативной памяти и сверхбыстрый диск. Но если на нём не установлена операционная система (ОС), это «железо» — просто груда дорогого металла и пластика. Оно не умеет ничего: ни показать картинку, ни сохранить файл, ни даже отреагировать на нажатие клавиши.

В этой статье мы разберем, как операционная система оживляет компьютер, какой путь она прошла от перфокарт до смартфонов, и что находится у неё «под капотом».

Что такое операционная система?

Операционная система — это комплекс программ, который управляет аппаратным обеспечением компьютера и предоставляет среду для выполнения пользовательских программ. Это посредник между вами (и вашими приложениями) и «железом».

Лучшая аналогия для ОС — это дирижер оркестра. * Музыканты — это аппаратные ресурсы (процессор, память, диск). * Ноты — это программы, которые нужно исполнить. * Дирижер (ОС) — не играет на инструментах сам, но указывает, кому и когда вступать, следит за темпом и предотвращает какофонию, когда все пытаются играть одновременно.

!Структура компьютерной системы: от пользователя к железу.

История развития: от вакуумных ламп до облаков

Чтобы понять архитектуру современных систем, нужно взглянуть на то, какие проблемы решали инженеры в прошлом.

Первое поколение (1945–1955): Вакуумные лампы и коммутационные панели

В те времена операционных систем не существовало вовсе. Компьютеры были огромными машинами, занимавшими целые залы. Программисты работали непосредственно с аппаратурой, соединяя провода на коммутационных панелях. Это был «чистый» режим работы с железом. Если программа зависала, нужно было физически перезагружать машину.

Второе поколение (1955–1965): Транзисторы и пакетная обработка

С появлением транзисторов компьютеры стали надежнее. Появилась первая концепция ОС — системы пакетной обработки. Чтобы не терять дорогое машинное время, пока оператор меняет ленты, задания собирались в «пакет» (batch) и скармливались компьютеру одно за другим.

Третье поколение (1965–1980): Интегральные схемы и мультипрограммирование

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

Мультипрограммирование решило эту проблему: память разбивалась на части, и в ней находилось сразу несколько программ. Когда одна ждала ввода-вывода, ОС переключала процессор на другую.

Для оценки эффективности мультипрограммирования используется следующая формула загрузки процессора:

Где: * — коэффициент использования процессора (Utilization). * — доля времени, которую процесс проводит в ожидании ввода-вывода (например, 0.5 или 50%). * — количество процессов в памяти. * — единица, представляющая полное время.

Пример: Если процесс тратит 80% времени на ожидание ввода-вывода (), то при одном процессе () процессор занят только 20% времени. Но если запустить 3 таких процесса, загрузка вырастет: , то есть почти 49%.

Четвертое поколение (1980–настоящее время): Персональные компьютеры

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

Архитектура ОС: Ядро и режимы работы

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

Защита: Кольца привилегий

Главная задача архитектуры — надежность. Если обычная программа (например, игра) зависнет, она не должна «убить» весь компьютер. Для этого процессоры поддерживают как минимум два режима работы:

  • Режим пользователя (User Mode): В этом режиме работают ваши приложения (браузер, Word). У них ограниченные права: они не могут напрямую обращаться к диску или управлять памятью других программ.
  • Режим ядра (Kernel Mode): В этом режиме работает ядро ОС. Ему разрешено всё: доступ к любой ячейке памяти, выполнение любой инструкции процессора.
  • !Переключение между пользовательским режимом и режимом ядра.

    Типы ядер

    Существует два основных подхода к построению ядра:

    * Монолитное ядро: Вся ОС (файловая система, драйверы, управление памятью) работает как одна большая программа в режиме ядра. Это быстро, но если драйвер видеокарты упадет, упадет вся система. (Примеры: Linux, ранние Windows). * Микроядро: В режиме ядра работает только самый минимум (передача сообщений, управление процессами). Драйверы и файловые системы вынесены в режим пользователя. Это надежнее, но медленнее из-за постоянных переключений. (Примеры: Minix, QNX).

    Основные функции ядра

    Чем именно занимается ядро? Можно выделить пять ключевых функций:

  • Управление процессами: Создание, остановка и переключение программ. Ядро решает, кому дать процессорное время (планирование).
  • Управление памятью: Ядро следит за тем, какая часть памяти занята, а какая свободна. Оно предотвращает ситуации, когда одна программа случайно перезаписывает данные другой.
  • Управление файловой системой: Превращение хаоса на магнитном диске или SSD в стройную структуру папок и файлов.
  • Управление вводом-выводом: Общение с клавиатурой, мышью, монитором, принтером через драйверы.
  • Безопасность и защита: Проверка прав доступа пользователей к файлам и ресурсам.
  • Системные вызовы (System Calls)

    Как программа в режиме пользователя может прочитать файл, если доступ к диску разрешен только в режиме ядра? Она должна «попросить» об этом операционную систему.

    Системный вызов — это интерфейс между приложением и ядром. Это специальная команда, которая говорит процессору: «Переключись в режим ядра, выполни эту функцию ОС и верни мне результат».

    Представьте ресторан: * Вы (приложение) сидите за столиком. * Кухня (ядро/железо) готовит еду. * Вы не можете просто зайти на кухню и взять стейк (это небезопасно и нарушает правила). * Вы зовете официанта (системный вызов) и просите его принести заказ.

    Примеры системных вызовов (в мире UNIX/Linux):

    * fork() — создать новый процесс (копию текущего). * read() — прочитать данные из файла. * write() — записать данные в файл или на экран. * open() — открыть файл для работы.

    Когда вы в программе на Python пишете `print(

    2. Управление процессами и потоками: алгоритмы планирования, многозадачность и синхронизация

    Управление процессами и потоками: алгоритмы планирования, многозадачность и синхронизация

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

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

    Процессы и потоки: в чем разница?

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

    Процесс (Process)

    Процесс — это выполняемая программа. Это не просто код на диске, а активная сущность, загруженная в оперативную память. Процесс включает в себя: * Код программы (инструкции). * Выделенную память (адресное пространство), к которой имеет доступ только этот процесс. * Глобальные переменные и данные. * Открытые файлы и сетевые соединения.

    Процессы изолированы друг от друга. Если один процесс «упадет» (зависнет или выдаст ошибку), это не должно повлиять на другие процессы.

    Поток (Thread)

    Поток (или нить) — это наименьшая единица выполнения внутри процесса. Один процесс может содержать один или несколько потоков.

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

    > Аналогия: Представьте, что процесс — это мастерская (помещение, инструменты, чертежи). А потоки — это рабочие в этой мастерской. Если в мастерской один рабочий, он делает всё последовательно. Если рабочих трое, они могут делать разные части детали одновременно, используя одни и те же станки (общую память).

    !Слева: однопоточный процесс. Справа: многопоточный процесс с общей памятью.

    Жизненный цикл процесса

    Процесс не просто «работает» или «не работает». Он проходит через несколько состояний. ОС хранит информацию о состоянии каждого процесса в специальной структуре данных — PCB (Process Control Block).

    Основные состояния процесса:

  • New (Создание): Процесс только создается.
  • Ready (Готовность): Процесс загружен в память и ждет, когда процессор освободится, чтобы начать выполнение.
  • Running (Выполнение): Инструкции процесса выполняются процессором прямо сейчас.
  • Waiting/Blocked (Ожидание): Процесс не может продолжать работу, так как ждет внешнего события (например, нажатия клавиши пользователем или чтения данных с диска).
  • Terminated (Завершение): Процесс закончил работу и освобождает ресурсы.
  • !Диаграмма переходов состояний процесса: от создания до завершения.

    Планирование: искусство тайм-менеджмента

    Так как процессов много, а процессор один (рассмотрим для простоты одноядерную систему), ОС должна решать, кому дать слово следующим. Этим занимается компонент ядра, называемый Планировщик (Scheduler).

    Переключение процессора с одной задачи на другую называется переключением контекста (Context Switch). Это накладные расходы: системе нужно сохранить состояние текущего процесса (регистры, указатели команд) и загрузить состояние следующего. Если переключаться слишком часто, процессор будет тратить всё время на переключения, а не на полезную работу.

    Алгоритмы планирования

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

    #### 1. FCFS (First-Come, First-Served) «Первым пришел — первым обслужен». Самый простой алгоритм, работающий как живая очередь в магазине. * Плюс: Простота реализации. * Минус: Проблема «конвоя». Если первым пришел «тяжелый» процесс, который считается 10 минут, все остальные (даже те, которым нужно 0.1 секунды) будут ждать.

    #### 2. SJF (Shortest Job First) «Самая короткая работа — первая». Планировщик выбирает процесс, которому нужно меньше всего времени для завершения. * Плюс: Минимальное среднее время ожидания. * Минус: Невозможно точно знать заранее, сколько времени займет процесс. Длинные задачи могут голодать (никогда не запуститься), если постоянно приходят короткие.

    #### 3. Round Robin (Карусельное планирование) Каждому процессу дается фиксированный квант времени (например, 20 миллисекунд). Если процесс не успел завершиться, он принудительно прерывается и отправляется в конец очереди, а управление передается следующему.

    Это основа современных многозадачных систем (Windows, Linux, macOS используют усложненные версии этого подхода).

    Для оценки эффективности алгоритмов часто используют метрику Turnaround Time (время оборота) — время с момента появления процесса до его завершения. Формула для среднего времени оборота:

    Где: * — среднее время оборота (Average Turnaround Time). * — общее количество процессов. * — знак суммы (суммирование показателей для всех процессов от 1 до n). * — время завершения -го процесса. * — время прибытия -го процесса в систему.

    Синхронизация и проблема гонки

    Когда мы используем многопоточность (несколько потоков в одной памяти), возникает серьезная проблема: Состояние гонки (Race Condition). Это ошибка, возникающая, когда результат работы программы зависит от того, в каком случайном порядке выполнятся потоки.

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

    Логика программы (упрощенно):

  • Прочитать баланс.
  • Если баланс >= 1000, то:
  • Выдать деньги.
  • Записать новый баланс (старый - 1000).
  • Что происходит при гонке:

  • Поток А читает баланс: 1000.
  • Поток Б читает баланс: 1000 (Поток А еще не успел изменить его!).
  • Поток А видит, что денег хватает, выдает 1000.
  • Поток Б видит, что денег хватает, выдает 1000.
  • Поток А записывает остаток: 0.
  • Поток Б записывает остаток: 0.
  • Итог: Снято 2000 рублей, хотя на счете была только 1000. Банк разорен.

    Инструменты синхронизации

    Чтобы избежать хаоса, программисты используют специальные механизмы защиты, предоставляемые ОС.

    #### Мьютекс (Mutex / Lock) Сокращение от Mutual Exclusion (взаимное исключение). Это как ключ от туалетной комнаты в поезде. Если ключ у одного человека (потока), другие ждут снаружи, пока он не выйдет и не вернет ключ.

    В примере с банком: перед проверкой баланса поток «захватывает мьютекс». Второй поток пытается захватить его, но видит, что он занят, и ждет. Когда первый закончит и обновит баланс, он «освобождает мьютекс», и второй поток сможет войти (и увидит, что денег уже нет).

    #### Семафор (Semaphore) Это более сложный инструмент. Представьте парковку на 5 мест. На въезде стоит табло (счетчик). Когда машина заезжает, счетчик уменьшается. Когда выезжает — увеличивается. Если счетчик равен 0, шлагбаум не открывается.

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

    Тупики (Deadlocks)

    Использование блокировок может привести к другой проблеме — взаимной блокировке или Deadlock.

    Представьте перекресток, на котором с четырех сторон одновременно подъехали машины. По правилам «помеха справа» каждая должна пропустить ту, что справа. В итоге все стоят вечно.

    В мире ОС это выглядит так: * Поток 1 захватил Ресурс А и ждет Ресурс Б. * Поток 2 захватил Ресурс Б и ждет Ресурс А.

    Никто не может продолжить работу. Для борьбы с тупиками ОС используют алгоритмы обнаружения циклов в графе ожидания ресурсов или принудительно завершают один из процессов.

    !Визуализация взаимной блокировки (Deadlock) на примере перекрестка.

    Заключение

    Управление процессами и потоками — это баланс между эффективностью (чтобы процессор не простаивал) и надежностью (чтобы данные не портились). Мы узнали, что: * Процессы изолированы, а потоки делят память. * Планировщик использует алгоритмы вроде Round Robin для создания иллюзии многозадачности. * Синхронизация (мьютексы, семафоры) необходима для защиты общих данных, но неправильное ее использование ведет к тупикам.

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

    3. Управление памятью: организация физической и виртуальной памяти, свопинг и страничная адресация

    Управление памятью: организация физической и виртуальной памяти, свопинг и страничная адресация

    В предыдущих лекциях мы разобрали, как процессор выполняет инструкции и как операционная система (ОС) управляет процессами, создавая иллюзию одновременной работы множества программ. Однако для работы любого процесса требуется не только процессорное время, но и место для хранения кода, переменных и данных. Это место — оперативная память (RAM).

    Сегодня мы поговорим о том, как ОС управляет этим критически важным ресурсом. Как удается запустить игру, требующую 8 ГБ памяти, браузер и фотошоп одновременно, если в компьютере всего 8 ГБ физической памяти? Ответ кроется в магии виртуализации памяти.

    Проблема прямой адресации

    На заре компьютерной эры (и в простейших микроконтроллерах сегодня) программы работали с физической памятью напрямую. Если у компьютера было 64 КБ памяти, адреса ячеек шли от 0 до 65535.

    Такой подход создает три огромные проблемы для многозадачных систем:

  • Защита: Если программа А знает физический адрес данных программы Б, она может их прочитать или, что хуже, перезаписать. Ошибка в одной программе может обрушить всю систему.
  • Адресация: Программист должен заранее знать, в какую часть памяти будет загружена его программа, чтобы правильно настроить ссылки на переменные. Это практически невозможно в динамической системе.
  • Ограниченность: Вы не можете запустить программу, которая больше, чем объем установленной оперативной памяти.
  • Чтобы решить эти проблемы, инженеры придумали абстракцию — виртуальную память.

    Виртуальная память: Великая иллюзия

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

    Каждый процесс при запуске получает в свое распоряжение огромное, непрерывное адресное пространство (например, 4 ГБ в 32-битных системах). Процесс «думает», что он единственный владелец памяти и она начинается с адреса 0. На самом деле, его данные могут быть разбросаны по физической памяти хаотично, а часть вообще может находиться на жестком диске.

    MMU: Аппаратный переводчик

    Преобразованием виртуального адреса в физический занимается специальное устройство внутри процессора — MMU (Memory Management Unit). Это происходит «на лету» при каждом обращении к памяти.

    !Схема преобразования виртуального адреса в физический через устройство управления памятью.

    Организация памяти: Свопинг и Страничная адресация

    Как именно ОС распределяет память между процессами? Существует несколько подходов.

    Свопинг (Swapping)

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

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

    Страничная адресация (Paging)

    Современные системы (Windows, Linux, macOS, Android) используют более продвинутый метод — страничную организацию памяти.

    Виртуальная память разбивается на блоки фиксированного размера, которые называются страницами (pages). Физическая память разбивается на блоки такого же размера, называемые фреймами (frames) или кадрами. Обычно размер страницы составляет 4 КБ.

    Суть метода: * Любая страница виртуальной памяти может быть помещена в любой свободный фрейм физической памяти. * Не обязательно загружать весь процесс в память целиком. Можно загрузить только те страницы, которые нужны прямо сейчас.

    Для учета соответствия «Страница -> Фрейм» операционная система ведет Таблицу страниц (Page Table) для каждого процесса.

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

    Обработка ошибок страниц (Page Fault)

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

    Происходит прерывание, называемое Page Fault (Ошибка страницы). Это не фатальная ошибка, а штатная ситуация:

  • MMU видит, что страницы нет в RAM, и подает сигнал процессору.
  • Процессор прерывает выполнение текущей программы и передает управление ядру ОС.
  • ОС находит нужные данные на жестком диске.
  • ОС загружает их в свободный фрейм оперативной памяти.
  • ОС обновляет таблицу страниц.
  • Процессор возвращается к выполнению инструкции, которая вызвала сбой, но теперь данные уже в памяти.
  • Эффективность доступа к памяти

    Частые ошибки страниц могут сильно замедлить компьютер. Это состояние называется thrashing (пробуксовка), когда система тратит больше времени на перекладывание страниц с диска в память и обратно, чем на полезную работу.

    Для оценки производительности системы памяти используется формула эффективного времени доступа ():

    Где: * — эффективное время доступа (Effective Access Time). * — вероятность возникновения ошибки страницы (Page Fault Rate), число от 0 до 1. * — время доступа к оперативной памяти (обычно наносекунды). * — время обслуживания ошибки страницы (чтение с диска, обычно миллисекунды).

    Даже если очень мало (например, 0.001), огромное значение (диск медленный) может увеличить в сотни раз. Именно поэтому установка SSD вместо HDD так сильно ускоряет отзывчивость системы — параметр уменьшается.

    Алгоритмы замещения страниц

    Если оперативная память заполнена, а нам нужно загрузить новую страницу с диска, ОС должна решить: какую страницу выбросить (выгрузить), чтобы освободить место? Эту задачу решают алгоритмы замещения.

    1. FIFO (First-In, First-Out)

    «Первым пришел — первым ушел». ОС выбрасывает самую старую страницу, которая была загружена раньше всех. * Проблема: Старая страница может содержать важную часть ядра или часто используемую переменную. Выбрасывать её — плохая идея.

    2. LRU (Least Recently Used)

    «Наименее недавно использовавшаяся». ОС выбрасывает ту страницу, к которой не обращались дольше всего. * Логика: Если программа не использовала эти данные последние 5 минут, скорее всего, они не понадобятся и в ближайшем будущем. * Это один из самых эффективных и популярных алгоритмов, хотя его полная реализация требует аппаратной поддержки.

    Сегментация: альтернативный взгляд

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

    * Плюс: Логически понятнее для программиста и компилятора. * Минус: Приводит к внешней фрагментации (появлению дыр в памяти разного размера, куда не влезают новые сегменты).

    В современных ОС часто используется гибридный подход: сегментно-страничная организация, где сегменты состоят из страниц.

    Заключение

    Управление памятью — это сложный баланс между скоростью и объемом. Благодаря виртуальной памяти, страничной адресации и умным алгоритмам замещения (LRU), мы можем запускать тяжелые приложения на скромном оборудовании.

    Мы узнали, что: * Виртуальная память изолирует процессы и расширяет доступное пространство. * MMU транслирует адреса на лету. * Страничная адресация позволяет эффективно использовать RAM, избегая фрагментации. * Свопинг и Page Faults позволяют использовать диск как расширение памяти, но ценой производительности.

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

    4. Файловые системы и подсистема ввода-вывода: структура хранения данных и драйверы устройств

    Файловые системы и подсистема ввода-вывода: структура хранения данных и драйверы устройств

    В предыдущей статье мы обсуждали оперативную память (RAM) — быстрое, но «забывчивое» хранилище. Как только вы выключаете компьютер, все данные из RAM исчезают. Но операционная система и ваши файлы остаются на месте. За это отвечает долговременная память (жесткие диски, SSD) и файловая система.

    Кроме того, компьютер — это не только процессор и память. Это еще и клавиатура, мышь, монитор, принтер, сетевая карта и видеокамера. Как операционная система умудряется управлять таким зоопарком устройств, не сходя с ума? Сегодня мы разберем архитектуру подсистемы ввода-вывода и узнаем, как именно хранятся ваши данные на диске.

    Подсистема ввода-вывода: Как ОС общается с миром

    Главная проблема взаимодействия с оборудованием — его разнообразие. Существуют тысячи моделей принтеров, и у каждого свой набор команд. Если бы разработчики операционной системы (например, Windows или Linux) писали код для поддержки каждого устройства напрямую в ядре, ОС занимала бы терабайты, а новые устройства не работали бы до обновления системы.

    Драйверы устройств: Универсальные переводчики

    Решение этой проблемы — абстракция. Операционная система определяет общий интерфейс для типов устройств (например, «все диски должны уметь читать и писать блоки» или «все принтеры должны уметь печатать страницу»).

    Производитель устройства пишет специальную программу — драйвер устройства. Драйвер работает как переводчик:

  • ОС посылает стандартную команду: «Напечатать текст».
  • Драйвер переводит её на язык конкретного железа: «Подать напряжение на мотор А, сдвинуть головку на 10 шагов, впрыснуть чернила».
  • Устройство выполняет действие.
  • Драйверы работают в режиме ядра (Kernel Mode), поэтому ошибка в драйвере видеокарты часто приводит к «синему экрану смерти» (BSOD) и падению всей системы.

    !Схема работы драйвера как переводчика между ОС и железом

    Контроллеры и порты

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

    DMA: Прямой доступ к памяти

    В старых компьютерах процессор сам занимался перекачкой данных с диска в память. Это называлось PIO (Programmed Input/Output). Процессор был занят рутинной работой: «считать байт с диска -> записать байт в память». В это время компьютер «тормозил».

    Современные системы используют DMA (Direct Memory Access). Это специальный контроллер, который берет на себя задачу копирования данных.

    Как это работает:

  • Процессор говорит DMA-контроллеру: «Перенеси 100 МБ с диска по адресу X в оперативную память по адресу Y».
  • Процессор переключается на выполнение других программ (например, отрисовку интерфейса).
  • DMA-контроллер копирует данные.
  • Когда копирование завершено, DMA посылает процессору сигнал прерывания: «Готово!».
  • Файловые системы: Организация хаоса

    Жесткий диск или SSD — это просто огромное поле для записи битов. С точки зрения физики, диск разбит на сектора (обычно по 512 байт или 4 КБ). Если бы мы писали данные просто подряд, то найти нужный файл было бы невозможно.

    Файловая система (ФС) — это способ организации данных на носителе. Она решает, где начинается и заканчивается файл, как называются папки и кто имеет право их открывать.

    Файл как абстракция

    Для пользователя файл — это документ, картинка или песня. Для операционной системы файл — это просто именованная последовательность байтов. ОС не важно, что внутри файла, ей важно знать его атрибуты: имя, размер, дату создания и расположение на диске.

    Блоки и кластеры

    Адресовать каждый байт на диске объемом 1 ТБ слишком накладно (таблица адресов была бы гигантской). Поэтому файловые системы группируют сектора в логические блоки, называемые кластерами.

    Кластер — это минимальная единица выделения места на диске. Даже если ваш файл весит 1 байт, на диске он займет целый кластер (например, 4 КБ).

    Это приводит к явлению внутренней фрагментации (потери места). Рассчитаем потерянное пространство () для файла размером при размере кластера :

    Где: * — потерянное место (Wasted space). * — размер кластера (Cluster size). * — размер файла (File size). * — операция взятия остатка от деления. Примечание: Если остаток равен 0, то потерь нет (W=0).*

    Если у вас миллион мелких файлов по 1 КБ, а кластер равен 4 КБ, вы потеряете около 3 ГБ дискового пространства просто так.

    Методы хранения файлов

    Главная задача ФС — запомнить, какие кластеры принадлежат какому файлу. Существует три основных подхода.

    1. Непрерывное выделение (Contiguous Allocation)

    Файл занимает ряд идущих подряд блоков. Как запись на магнитной ленте. * Плюсы: Очень быстрое чтение (головке диска не нужно прыгать). * Минусы: Трудно найти место для нового файла. Если файл растет, его нужно переносить целиком. Возникает внешняя фрагментация (дыры между файлами).

    2. Связный список (Linked Allocation)

    Каждый блок содержит данные и ссылку (адрес) на следующий блок. Файл может быть разбросан по всему диску. * Плюсы: Нет фрагментации, файл может расти бесконечно, пока есть место. * Минусы: Очень медленный произвольный доступ. Чтобы прочитать конец файла, нужно пройти по всей цепочке с начала. Если один блок повредится, весь остаток файла потерян. (Используется в FAT32).

    3. Индексное выделение (Indexed Allocation)

    Для каждого файла создается специальный блок — индексный блок (или i-node в Linux). В нем хранится список всех адресов блоков данных этого файла. * Плюсы: Быстрый прямой доступ к любой части файла. Легко расширять файл. * Минусы: Расходы памяти на хранение индексов.

    Это самый популярный метод в современных системах (NTFS, ext4, APFS).

    !Три метода хранения файлов: непрерывный, связный и индексный

    Структура i-node (Linux/Unix)

    В системах Unix/Linux концепция i-node (index node) является ключевой. I-node — это структура данных, описывающая файл. Она содержит: * Права доступа (чтение/запись). * Владельца файла. * Размер и временные метки. * Указатели на блоки данных.

    Интересно, что имя файла не хранится в i-node. Имя хранится в директории (каталоге). Директория — это просто специальный файл, который содержит таблицу: «Имя файла» -> «Номер i-node».

    Это позволяет создавать жесткие ссылки (Hard Links): два разных имени файла в разных папках могут указывать на один и тот же i-node (и одни и те же данные).

    Производительность диска

    Скорость работы файловой системы зависит не только от софта, но и от физики. Для классических жестких дисков (HDD) время доступа складывается из трех компонентов:

    Где: * — полное время доступа к данным. * — время поиска (время перемещения считывающей головки на нужную дорожку). * — время вращения (ожидание, пока нужный сектор подъедет под головку). * — время передачи данных (собственно чтение).

    В SSD нет движущихся частей, поэтому и практически равны нулю, что делает их в разы быстрее.

    Журналирование: Защита от сбоев

    Представьте, что вы копируете файл. Система должна сделать два действия:

  • Выделить место в таблице файлов.
  • Записать сами данные.
  • Если электричество отключается ровно посередине (шаг 1 выполнен, шаг 2 — нет), файловая система оказывается в рассогласованном состоянии. Файл вроде бы есть, но он указывает на мусор.

    Для защиты от этого современные ФС (NTFS, ext4, HFS+) используют журналирование.

    Как это работает:

  • Запись намерения: Перед изменением данных ОС пишет в специальный журнал: «Я собираюсь записать файл X».
  • Выполнение: ОС выполняет запись файла.
  • Фиксация: После успеха ОС вычеркивает запись из журнала.
  • Если сбой произойдет посередине, при следующей загрузке ОС прочитает журнал, увидит незавершенную операцию и либо закончит её, либо отменит, сохранив целостность структуры диска.

    Заключение

    Файловая система и подсистема ввода-вывода — это фундамент, на котором строятся пользовательские данные. Мы узнали, что: * Драйверы скрывают сложность железа. * DMA разгружает процессор при работе с диском. * Файловые системы борются с фрагментацией и используют кластеры. * Журналирование спасает данные при сбоях питания.

    Теперь, когда мы понимаем, как работают процессы, память и файлы, у нас есть полная картина работы одного компьютера. Но современные компьютеры редко работают в одиночку. В следующих курсах мы могли бы рассмотреть, как они объединяются в компьютерные сети.

    5. Безопасность и администрирование: управление доступом, защита информации и виртуализация

    Безопасность и администрирование: управление доступом, защита информации и виртуализация

    Мы прошли долгий путь, изучая, как операционная система управляет процессором, памятью и файлами. Теперь представьте, что наш компьютер — это не просто инструмент для вычислений, а огромный офисный центр. В нём работают сотни сотрудников (процессов), хранятся секретные документы (файлы) и постоянно приходят посетители (сетевые пакеты).

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

    Триада информационной безопасности

    Прежде чем говорить о технических деталях, нужно понять, что именно мы защищаем. В мире кибербезопасности существует «золотой стандарт» — модель CIA:

  • Конфиденциальность (Confidentiality): Доступ к информации имеют только те, кому это положено. (Пример: никто не может прочитать ваш пароль).
  • Целостность (Integrity): Информация не может быть изменена неавторизованным способом. (Пример: вирус не должен дописать свой код в системный файл).
  • Доступность (Availability): Система должна работать и предоставлять ресурсы пользователям, когда это необходимо. (Пример: защита от DDoS-атак, чтобы сервер не «упал»).
  • Операционная система обязана обеспечивать все три аспекта на уровне ядра.

    Идентификация, Аутентификация и Авторизация

    Эти три понятия часто путают, но в ОС они имеют четкие различия. Давайте разберем их на примере прохода в секретную лабораторию.

    * Идентификация: Вы подходите к двери и говорите: «Я — сотрудник Иванов». Вы называете свое имя (логин). Система находит вашу учетную запись. * Аутентификация: Охранник спрашивает: «Чем докажешь?». Вы прикладываете палец к сканеру или вводите пароль. Система проверяет, действительно ли вы тот, за кого себя выдаете. * Авторизация: Вы вошли внутрь. Но можете ли вы зайти в серверную? Или только в столовую? Система проверяет ваши права доступа к конкретным объектам.

    Как ОС хранит пароли?

    В ранних системах пароли хранились в открытом виде в текстовом файле. Это была катастрофа: любой, кто получал доступ к файлу, узнавал пароли всех пользователей.

    Современные ОС (Linux, Windows, macOS) никогда не хранят пароли. Они хранят их хеши. Хеш-функция — это математический алгоритм, который превращает строку любой длины в набор символов фиксированной длины. Это односторонняя операция: из пароля легко получить хеш, но из хеша невозможно восстановить пароль.

    Чтобы защититься от хакеров, использующих заранее вычисленные таблицы хешей (радужные таблицы), ОС добавляет к паролю соль (salt) — случайный набор данных.

    Формула вычисления хеша выглядит так:

    Где: * — итоговый хеш, который сохраняется на диске. * — криптографическая хеш-функция (например, SHA-256). * — пароль пользователя. * — соль (случайная строка, уникальная для каждого пользователя).

    Когда вы вводите пароль при входе, система берет вашу соль, добавляет её к введенному паролю, хеширует результат и сравнивает с тем, что хранится на диске. Если совпало — вы проходите.

    Управление доступом (Access Control)

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

    1. Дискреционное управление доступом (DAC)

    Это классическая модель, используемая в UNIX, Linux и Windows (для домашних пользователей). Идея проста: у каждого объекта (файла) есть владелец, и владелец сам решает, кому дать права.

    В Linux права записываются в виде строки, например: rwxr-xr--. Это три группы прав:

  • Владелец (User): rwx (Read, Write, Execute) — может читать, писать и запускать.
  • Группа (Group): r-x — коллеги владельца могут читать и запускать, но не изменять.
  • Остальные (Others): r-- — все остальные могут только читать.
  • !Визуализация структуры прав доступа rwx в системах типа UNIX.

    2. Мандатное управление доступом (MAC)

    Используется в военных системах и системах повышенной безопасности (например, SElinux). Здесь пользователь не может сам изменить права доступа к файлу, даже если он его создал.

    Все данные имеют метку секретности (например, «Секретно», «Совершенно секретно»), а пользователи — уровень допуска. ОС следит за правилами: * No Read Up: Пользователь с низким допуском не может читать секретные документы. * No Write Down: Генерал не может скопировать секретный документ на общедоступную флешку (чтобы случайно не слить данные).

    3. Ролевое управление доступом (RBAC)

    Популярно в корпоративных системах (Windows Server, базы данных). Права назначаются не конкретному пользователю Васе, а Роли (например, «Бухгалтер»). Если Вася уволился, и пришел Петя, администратору достаточно просто назначить Пете роль «Бухгалтер», и он сразу получит доступ ко всем нужным папкам.

    Защита памяти и противодействие атакам

    Злоумышленники часто пытаются атаковать не пароли, а саму работающую программу, чтобы заставить её выполнить вредоносный код. Одной из самых известных атак является переполнение буфера (Buffer Overflow).

    Представьте, что программа выделила в памяти место под имя пользователя (10 байт). Хакер вводит имя длиной 100 байт. Лишние данные «вылезают» за границы буфера и перезаписывают соседние ячейки памяти, где может храниться адрес возврата функции. В итоге процессор прыгает не обратно в программу, а в код хакера.

    Современные ОС имеют встроенные механизмы защиты:

  • ASLR (Address Space Layout Randomization): При каждом запуске программы ОС случайным образом меняет адреса библиотек и стека в памяти. Хакер не знает, по какому адресу находится нужная ему функция, и его эксплойт не срабатывает.
  • DEP / NX Bit (Data Execution Prevention): ОС помечает области памяти с данными (например, стек) как «неисполняемые». Даже если хакер запишет туда свой вирус, процессор откажется выполнять этот код, так как он находится в зоне «только для данных».
  • Виртуализация: Машины внутри машин

    С ростом мощности компьютеров возникла проблема: один сервер слишком мощен для одной задачи. Если запустить на нем только почтовый сервер, 90% ресурсов будут простаивать. Запустить все сервисы на одной ОС опасно: если один зависнет или будет взломан, пострадают все.

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

    Гипервизор (Hypervisor)

    Ключевой компонент виртуализации — гипервизор. Это программное обеспечение, которое создает и запускает виртуальные машины (VM). Гипервизор обманывает гостевую ОС, заставляя её верить, что она владеет реальным процессором и памятью.

    Существует два типа гипервизоров:

    #### Тип 1: Нативный (Bare-Metal) Гипервизор устанавливается прямо на «голое железо» вместо обычной ОС. Он очень быстрый и надежный. Используется в дата-центрах. Примеры:* VMware ESXi, Microsoft Hyper-V, Xen.

    #### Тип 2: Хостовый (Hosted) Гипервизор устанавливается как обычная программа поверх вашей основной ОС (Windows или macOS). Это удобно для разработчиков, чтобы протестировать Linux внутри Windows. Примеры:* Oracle VirtualBox, VMware Workstation.

    !Архитектурные различия между нативным и хостовым гипервизорами.

    Контейнеризация (Docker)

    Виртуальные машины тяжелые: каждая VM несет в себе полное ядро ОС, занимая гигабайты места и минуты на загрузку. Индустрия пришла к более легкому решению — контейнерам.

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

    > «Если Виртуальная машина — это отдельный частный дом со своим фундаментом и коммуникациями, то Контейнер — это квартира в многоквартирном доме. Стены общие, фундамент общий, но жильцы друг друга не видят».

    Это позволяет запускать тысячи контейнеров на одном сервере за доли секунды.

    Администрирование: Роль Суперпользователя

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

    * В Windows: Администратор (Administrator). * В Linux/Unix: Рут (root).

    Работа под рутом опасна. Любая ошибка (например, команда rm -rf / — удалить все файлы) будет выполнена без вопросов. Поэтому современные практики администрирования требуют работать под обычным пользователем и временно повышать права только для конкретной команды (механизм sudo в Linux или UAC в Windows).

    Заключение курса

    Мы завершаем курс «Основы операционных систем». Мы разобрали, как из «груды железа» получается умная машина.

  • Ядро управляет ресурсами.
  • Процессы позволяют делать много дел одновременно.
  • Виртуальная память дает каждому процессу свое пространство.
  • Файловая система организует хранение данных.
  • Система безопасности защищает всё это от угроз.
  • Операционная система — это, возможно, самое сложное программное обеспечение, созданное человеком. Понимание её принципов делает вас не просто пользователем, а инженером, понимающим суть происходящего на экране.