Узнав больше о том, как операционные системы и оборудование, на котором они работают, работают и взаимодействуют друг с другом, вы можете быть удивлены, увидев странности или недостаточное использование «ресурсов». Это почему? В сегодняшнем посте SuperUser Q&A есть ответ на любопытный вопрос читателя.
Сегодняшняя сессия вопросов и ответов проходит благодаря SuperUser - подразделению Stack Exchange, группы веб-сайтов вопросов и ответов, управляемой сообществом.
Фото любезно предоставлено Лемсипматт (Flickr) .
Вопрос
Читатель SuperUser AdHominem хочет знать, почему процессоры x86 используют только два кольца из четырех:
Системы x86 на базе Linux и Windows используют только Кольцо 0 для режима ядра и Кольцо 3 для пользовательского режима. Почему процессоры даже различают четыре разных кольца, если все они в конечном итоге используют только два из них? Изменилось ли это с архитектурой AMD64?
Почему процессоры x86 используют только два кольца из четырех?
Ответ
У участника SuperUser Джейми Ханрахана есть для нас ответ:
Есть две основные причины.
Во-первых, несмотря на то, что процессоры x86 предлагают четыре кольца защиты памяти, степень детализации защиты, предлагаемой ими, находится только на уровне сегментов. То есть каждый сегмент может быть установлен на определенное кольцо (уровень привилегий) вместе с другими средствами защиты, такими как отключение записи. Но доступных дескрипторов сегментов не так уж и много. Большинство операционных систем хотели бы иметь более детализированную защиту памяти, например… для отдельных страниц.
Итак, введите защиту на основе таблицы страниц. Большинство, если не все, современные операционные системы x86 более или менее игнорируют механизм сегментации (в любом случае, насколько это возможно) и полагаются на защиту, доступную с помощью младших битов в записях таблицы страниц. Один из них называется «привилегированным» битом. Этот бит определяет, должен ли процессор находиться на одном из «привилегированных» уровней для доступа к странице. «Привилегированные» уровни: PL 0, 1 и 2 . Но это всего лишь один бит, поэтому на уровне постраничной защиты количество доступных «режимов» с точки зрения защиты памяти составляет всего два: страница может быть доступна из непривилегированного режима или нет. Значит, всего два кольца. Чтобы иметь четыре возможных кольца для каждой страницы, они должны иметь два защитных бита в каждой записи таблицы страниц для кодирования одного из четырех возможных номеров кольца (как и дескрипторы сегментов). Однако это не так.
Другая причина - стремление к переносимости операционной системы. Дело не только в x86; Unix научил нас, что операционная система может быть относительно переносимой на несколько процессорных архитектур, и что это хорошо. А некоторые процессоры поддерживают только два кольца. Не зависящие от нескольких колец в архитектуре, разработчики операционной системы сделали операционные системы более переносимыми.
Существует третья причина, специфичная для разработки под Windows NT. Дизайнеры NT (Дэвид Катлер и его команда, которых Microsoft наняла из DEC Western Region Labs) имели большой опыт работы с VMS; Фактически, Катлер и некоторые другие были одними из первых дизайнеров VMS. А процессор VAX, для которого была разработана VMS, имеет четыре кольца (VMS использует четыре кольца).
Но компоненты, работающие в VMS Кольца 1 и 2 (Службы управления записями и интерфейс командной строки, соответственно) были исключены из конструкции NT. Кольцо 2 в VMS на самом деле речь шла не о безопасности операционной системы, а о сохранении среды интерфейса командной строки пользователя от одной программы к другой, а в Windows такой концепции не было; CLI работает как обычный процесс. Что касается VMS Кольцо 1 , код RMS в Кольцо 1 пришлось позвонить в Кольцо 0 довольно часто, а кольцевые переходы дороги. Оказалось, что гораздо эффективнее просто пойти в Кольцо 0 и покончить с этим, а не иметь много Кольцо 0 переходы в Кольцо 1 код (опять же, в NT нет ничего похожего на RMS).
Что касается того, почему x86 реализовал четыре кольца, в то время как операционные системы их не использовали, вы говорите об операционных системах гораздо более позднего дизайна, чем x86. Многие функции системного программирования x86 были разработаны задолго до того, как на нем были реализованы NT или настоящие ядра Unix, и они действительно не знали, что будет использовать операционная система. Только когда мы получили пейджинг на x86, мы смогли реализовать истинные Unix-подобные или VMS-подобные ядра.
Мало того, что современные операционные системы x86 в значительной степени игнорируют сегментирование (они просто настраивают сегменты C, D и S с базовым адресом 0 и размером 4 ГБ; сегменты F и G иногда используются для указания на ключевые структуры данных операционной системы. ), они также в значительной степени игнорируют такие вещи, как «сегменты состояния задачи». Механизм TSS был явно разработан для переключения контекста потока, но, как оказалось, он имеет слишком много побочных эффектов, поэтому современные операционные системы x86 делают это «вручную». Единственный раз, когда x86 NT изменяет аппаратные задачи, - это действительно исключительные условия, такие как исключение двойной ошибки.
Что касается архитектуры x64, многие из этих неиспользуемых функций были упущены. К их чести, AMD на самом деле поговорила с командами разработчиков ядра операционной системы и спросила, что им нужно от x86, что им не нужно или не нужно и что они хотели бы добавить. Сегменты на x64 существуют только в так называемой рудиментарной форме, переключения состояний задач не существует и т. Д., А операционные системы продолжают использовать только два кольца.
Есть что добавить к объяснению? Отключить звук в комментариях. Хотите узнать больше ответов от других технически подкованных пользователей Stack Exchange? Ознакомьтесь с полной веткой обсуждения здесь .