Ядро и пользовательский режим

Почему обычная программа не может взять и стереть диск напрямую — и кто ей это запрещает.

Режим ядра (kernel mode) — привилегированный режим работы процессора, в котором разрешены любые инструкции и доступ ко всему железу; пользовательский режим (user mode) — ограниченный режим, в котором работают обычные программы.

Зачем процессору два режима

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

  • Режим ядра. Полный доступ. Здесь работает ядро ОС и драйверы. Можно всё.
  • Пользовательский режим. Ограниченный доступ. Здесь работают браузеры, игры, ваш код. Привилегированные инструкции запрещены.

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

Кольца защиты

На процессорах x86 уровней привилегий формально четыре — их называют «кольцами» (rings), от ring 0 до ring 3. На практике почти все ОС используют только два:

КольцоКто работаетПрава
ring 0ядро ОСмаксимальные
ring 3приложенияограниченные

Аналогия: банк

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

Как программа переходит в режим ядра

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

Важно понять последовательность переключений за обычное чтение файла:

программа (user mode)
   -> системный вызов read()
        -> процессор переключается в kernel mode
             -> ядро читает данные с диска
        -> процессор возвращается в user mode
   -> программа продолжает работу

Почему это важно для производительности

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

Итог

  • Процессор поддерживает два режима: привилегированный режим ядра и ограниченный пользовательский режим.
  • Приложения работают в пользовательском режиме и не могут трогать железо напрямую.
  • На x86 это кольца ring 0 (ядро) и ring 3 (программы).
  • Единственная легальная дверь в ядро — системный вызов.
  • Переключение режимов стоит дорого, поэтому частые мелкие вызовы вредят производительности.
Проверьте себя
1. В каком режиме работают обычные приложения (браузер, игра)?
AВ режиме ядра
BВ пользовательском режиме
CВ режиме прерываний
DВ режиме гипервизора
2. Что произойдёт, если программа в пользовательском режиме попытается выполнить привилегированную инструкцию?
AИнструкция выполнится с задержкой
BПроцессор сгенерирует исключение и управление перехватит ядро
CПрограмма автоматически перейдёт в ring 0
DНичего, такие инструкции просто игнорируются
3. Как программа легально получает доступ к привилегированным действиям ОС?
AПереключает кольцо защиты сама
BЧерез системный вызов к ядру
CОтключает пользовательский режим
DНапрямую обращается к драйверу
Поддержать проект