В чем разница между пространством ядра и пространством пользователя? Означают ли пространство ядра, потоки ядра, процессы ядра и стек ядра одно и то же? Кроме того, зачем нам эта дифференциация?
149
В чем разница между пространством ядра и пространством пользователя? Означают ли пространство ядра, потоки ядра, процессы ядра и стек ядра одно и то же? Кроме того, зачем нам эта дифференциация?
Ответы:
Действительно упрощенный ответ , что ядро работает в пространстве ядра, и обычные программы работают в пользовательском пространстве. Пользовательское пространство - это, по сути, форма песочницы: оно ограничивает пользовательские программы, чтобы они не могли связываться с памятью (и другими ресурсами), принадлежащей другим программам или ядру ОС. Это ограничивает (но обычно не исключает полностью) их способность делать плохие вещи, например, ломать машину.
Ядро - это ядро операционной системы. Обычно он имеет полный доступ ко всей памяти и аппаратному обеспечению (и ко всему остальному на машине). Чтобы машина оставалась как можно более стабильной, обычно требуется, чтобы в режиме ядра / пространстве ядра запускался только самый надежный и хорошо протестированный код.
Стек - это просто еще одна часть памяти, поэтому, естественно, он отделен вместе с остальной памятью.
источник
Random Access Memory (RAM) может быть логически разделена на два отдельных региона , а именно -. Пространства ядра и пространства пользователя ( The Физические адреса ОЗУ фактически не разделены только виртуальные адреса , все это осуществляется MMU )
Ядро работает в той части памяти, которой оно принадлежит. Эта часть памяти не может быть доступна напрямую процессам обычных пользователей, в то время как ядро может получить доступ ко всем частям памяти. Чтобы получить доступ к некоторой части ядра, то пользовательские процессы должны использовать предопределенную систему вызовов т.е.
open
,read
, иwrite
т.д. Кроме того ,C
библиотечные функции , такие какprintf
вызов системы вызоваwrite
в очереди.Системные вызовы действуют как интерфейс между пользовательскими процессами и процессами ядра. Права доступа размещаются в пространстве ядра, чтобы пользователи не испортили ядро по незнанию.
Итак, когда происходит системный вызов, ядру отправляется программное прерывание. ЦП может временно передать управление соответствующей программе обработки прерывания. Процесс ядра, который был остановлен прерыванием, возобновляется после того, как подпрограмма обработчика прерывания завершит свою работу.
источник
Пространство ядра и виртуальное пространство - это концепции виртуальной памяти ... это не означает, что RAM (ваша фактическая память) разделена на ядро и пространство пользователя. Каждому процессу предоставляется виртуальная память, которая разделена на ядро и пользовательское пространство.
Так говорится: «Оперативная память (RAM) может быть разделена на две отдельные области, а именно - пространство ядра и пространство пользователя». неправильно.
& относительно "пространства ядра против пространства пользователя"
Когда процесс создается и его виртуальная память делится на пространство пользователя и пространство ядра, где область пространства пользователя содержит данные, код, стек, кучу процесса, а пространство ядра содержит такие вещи, как таблица страниц для процесса , структуры данных ядра и код ядра и т. д. Для запуска кода пространства ядра управление должно перейти в режим ядра (с использованием программного прерывания 0x80 для системных вызовов), а стек ядра в основном используется всеми процессами, выполняющимися в настоящее время в пространстве ядра.
источник
Кольца процессора - самое четкое различие
В защищенном режиме x86 ЦП всегда находится в одном из 4-х колец. Ядро Linux использует только 0 и 3:
Это наиболее четкое и быстрое определение отношения ядра к пользовательской среде.
Почему Linux не использует кольца 1 и 2: Кольца привилегий ЦП: Почему кольца 1 и 2 не используются?
Как определяется текущее кольцо?
Текущее кольцо выбирается комбинацией:
глобальная таблица дескрипторов: таблица записей GDT в памяти, и каждая запись имеет поле,
Privl
которое кодирует кольцо.Инструкция LGDT устанавливает адрес текущей таблицы дескрипторов.
См. Также: http://wiki.osdev.org/Global_Descriptor_Table
сегментные регистры CS, DS и т. д. указывают на индекс записи в GDT.
Например,
CS = 0
означает, что первая запись GDT в настоящее время активна для исполняемого кода.Что может делать каждое кольцо?
Чип ЦП физически построен так, чтобы:
кольцо 0 может все
кольцо 3 не может выполнять несколько инструкций и записывать в несколько регистров, в первую очередь:
не может изменить свое собственное кольцо! В противном случае он мог бы установить для себя 0 звонков, и звонки были бы бесполезны.
Другими словами, нельзя изменить дескриптор текущего сегмента , который определяет текущее кольцо.
Невозможно изменить таблицы страниц: как работает подкачка x86?
Другими словами, невозможно изменить регистр CR3, а сама подкачка предотвращает изменение таблиц страниц.
Это не позволяет одному процессу видеть память других процессов по причинам безопасности / простоты программирования.
не может регистрировать обработчики прерываний. Они настраиваются путем записи в ячейки памяти, что также предотвращается подкачкой.
Обработчики работают в кольце 0 и нарушают модель безопасности.
Другими словами, нельзя использовать инструкции LGDT и LIDT.
не может выполнять инструкции ввода-вывода, такие как
in
иout
, и, следовательно, иметь произвольный доступ к оборудованию.В противном случае, например, права доступа к файлам были бы бесполезны, если бы какая-либо программа могла напрямую читать с диска.
Точнее, спасибо Майклу Петчу : на самом деле ОС может разрешить инструкции ввода-вывода на кольце 3, это фактически контролируется сегментом состояния задачи .
Кольцо 3 не может дать себе на это разрешение, если оно у него изначально не было.
Linux всегда это запрещает. См. Также: Почему Linux не использует аппаратное переключение контекста через TSS?
Как программы и операционные системы переходят между кольцами?
когда ЦП включен, он запускает начальную программу в кольце 0 (ну вроде как, но это хорошее приближение). Вы можете рассматривать эту начальную программу как ядро (но обычно это загрузчик, который затем вызывает ядро, все еще находящееся в кольце 0 ).
когда процесс пользовательского уровня хочет, чтобы ядро что-то сделало для него, например, запись в файл, он использует инструкцию, которая генерирует прерывание, такое как
int 0x80
или,syscall
чтобы сообщить ядру. Пример системного вызова Linux x86-64 hello world:скомпилировать и запустить:
GitHub вверх по течению .
Когда это происходит, ЦП вызывает обработчик обратного вызова прерывания, который ядро зарегистрировало во время загрузки. Вот конкретный пример baremetal, который регистрирует обработчик и использует его .
Этот обработчик работает в кольце 0, которое решает, разрешит ли ядро это действие, выполняет действие и перезапускает программу пользовательского пространства в кольце 3. x86_64
когда используется
exec
системный вызов (или когда ядро запускается/init
), ядро подготавливает регистры и память для нового процесса пользовательского пространства, затем оно переходит к точке входа и переключает ЦП на кольцо 3Если программа пытается сделать что-то непослушное, например запись в запрещенный регистр или адрес памяти (из-за разбиения на страницы), процессор также вызывает некоторый обработчик обратного вызова ядра в кольце 0.
Но поскольку пользовательская среда была непослушной, на этот раз ядро могло убить процесс или выдать ему предупреждение с помощью сигнала.
Когда ядро загружается, оно устанавливает аппаратные часы с некоторой фиксированной частотой, которые периодически генерируют прерывания.
Эти аппаратные часы генерируют прерывания, которые запускают кольцо 0, и позволяют ему планировать, какие процессы пользовательского пространства должны пробудиться.
Таким образом, планирование может выполняться, даже если процессы не выполняют никаких системных вызовов.
Какой смысл иметь несколько колец?
Разделение ядра и пользовательской среды дает два основных преимущества:
Как с этим поиграться?
Я создал "голый металл", который должен быть хорошим способом прямого управления кольцами: https://github.com/cirosantilli/x86-bare-metal-examples
К сожалению, у меня не хватило терпения сделать пример пользовательского пространства, но я дошел до настройки разбиения на страницы, так что пользовательское пространство должно быть возможным. Я бы хотел увидеть запрос на перенос.
В качестве альтернативы модули ядра Linux работают в кольце 0, поэтому вы можете использовать их для опробования привилегированных операций, например, чтения регистров управления: как получить доступ к регистрам управления cr0, cr2, cr3 из программы? Получение ошибки сегментации
Вот удобная настройка QEMU + Buildroot чтобы попробовать ее, не убивая хоста.
Обратной стороной модулей ядра является то, что работают другие потоки kthread, которые могут помешать вашим экспериментам. Но теоретически вы можете взять на себя все обработчики прерываний с вашим модулем ядра и владеть системой, что на самом деле было бы интересным проектом.
Отрицательные кольца
Хотя отрицательные кольца фактически не упоминаются в руководстве Intel, на самом деле существуют режимы ЦП, которые имеют дополнительные возможности, чем само кольцо 0, и поэтому хорошо подходят для названия «отрицательное кольцо».
Одним из примеров является режим гипервизора, используемый в виртуализации.
Подробнее см .:
РУКА
В ARM вместо этого кольца называются уровнями исключений, но основные идеи остаются прежними.
В ARMv8 существует 4 уровня исключений, обычно используемых как:
EL0: пользовательское пространство
EL1: ядро («супервизор» в терминологии ARM).
Вступил с
svc
инструкцией (SuperVisor Call), ранее известной какswi
до унифицированной сборки , которая является инструкцией, используемой для выполнения системных вызовов Linux. Привет, мир, пример ARMv8:привет.
GitHub вверх по течению .
Протестируйте это с помощью QEMU на Ubuntu 16.04:
Вот конкретный пример «голого металла», который регистрирует обработчик SVC и выполняет вызов SVC .
EL2: гипервизоры , например Xen .
Вступил с
hvc
инструкцией (HyperVisor Call).Гипервизор для ОС - то же самое, что ОС для пользователя.
Например, Xen позволяет одновременно запускать несколько операционных систем, таких как Linux или Windows, в одной и той же системе и изолирует операционные системы друг от друга для обеспечения безопасности и простоты отладки, как это делает Linux для программ пользовательского уровня.
Гипервизоры являются ключевой частью сегодняшней облачной инфраструктуры: они позволяют нескольким серверам работать на одном оборудовании, поддерживая использование оборудования почти на 100% и экономя много денег.
AWS, например, использовала Xen до 2017 года, когда о его переходе на KVM стало известно в новостях .
EL3: еще один уровень. Пример TODO.
Вошел с
smc
инструкцией (Secure Mode Call)ARMv8 Architecture Reference Model DDI 0487C.a - Глава D1 - В AArch64 уровневой системы программист Модель - Рисунок D1-1 иллюстрирует это красиво:
Ситуация с ARM немного изменилась с появлением расширений хоста виртуализации ARMv8.1 (VHE) . Это расширение позволяет ядру эффективно работать в EL2:
VHE был создан, потому что решения виртуализации в ядре Linux, такие как KVM, завоевали популярность по сравнению с Xen (см., Например, переход AWS на KVM, упомянутый выше), потому что большинству клиентов нужны только виртуальные машины Linux, и, как вы можете представить, все в одном В проекте KVM проще и потенциально более эффективно, чем Xen. Итак, теперь ядро хоста Linux действует как гипервизор в этих случаях.
Обратите внимание на то, что ARM, возможно, благодаря преимуществу ретроспективного анализа, имеет лучшее соглашение об именах для уровней привилегий, чем x86, без необходимости в отрицательных уровнях: 0 является нижним и 3 высшим. Более высокие уровни создаются чаще, чем более низкие.
Текущий EL можно запросить с помощью
MRS
инструкции: каков текущий режим выполнения / уровень исключения и т. Д.?ARM не требует наличия всех уровней исключений, чтобы позволить реализациям, которым не нужна функция для экономии площади чипа. ARMv8 «Уровни исключения» говорит:
QEMU, например, по умолчанию имеет значение EL1, но EL2 и EL3 можно включить с помощью параметров командной строки: qemu-system-aarch64, ввод el1 при эмуляции включения питания a53
Фрагменты кода протестированы на Ubuntu 18.10.
источник
Пространство ядра и пространство пользователя - это разделение привилегированных функций операционной системы и ограниченных пользовательских приложений. Разделение необходимо, чтобы пользовательские приложения не разграбили ваш компьютер. Было бы плохо, если бы какая-либо старая пользовательская программа могла начать записывать случайные данные на ваш жесткий диск или читать память из пространства памяти другой пользовательской программы.
Программы пользовательского пространства не могут напрямую обращаться к системным ресурсам, поэтому доступ осуществляется от имени программы ядром операционной системы. Программы пользовательского пространства обычно делают такие запросы к операционной системе через системные вызовы.
Потоки ядра, процессы, стек не означают одно и то же. Они являются аналогичными конструкциями для пространства ядра, как и их аналоги в пользовательском пространстве.
источник
Каждый процесс имеет свои собственные 4 ГБ виртуальной памяти, которая отображается в физическую память через таблицы страниц. Виртуальная память в основном разделена на две части: 3 ГБ для использования процесса и 1 ГБ для использования ядра. Большинство создаваемых вами переменных находятся в первой части адресного пространства. Эта часть называется пользовательским пространством. В последней части находится ядро, и она является общей для всех процессов. Это называется пространством ядра, и большая часть этого пространства отображается в начальные местоположения физической памяти, куда образ ядра загружается во время загрузки.
источник
Максимальный размер адресного пространства зависит от длины адресного регистра ЦП.
В системах с 32-битными адресными регистрами максимальный размер адресного пространства составляет 2 32 байта или 4 ГиБ. Точно так же в 64-битных системах можно адресовать 2 64 байта.
Такое адресное пространство называется виртуальной памятью или виртуальным адресным пространством . На самом деле это не связано с размером физического ОЗУ.
На платформах Linux виртуальное адресное пространство делится на пространство ядра и пространство пользователя.
Константа, зависящая от архитектуры, называемая пределом размера задачи , или
TASK_SIZE
, отмечает позицию, в которой происходит разделение:диапазон адресов от 0 до
TASK_SIZE
-1 выделяется пользовательскому пространству;остаток от
TASK_SIZE
2 32 -1 (или 2 64 -1) выделяется пространству ядра.Например, в конкретной 32-битной системе 3 ГиБ может быть занято для пространства пользователя и 1 ГиБ для пространства ядра.
Каждое приложение / программа в Unix-подобной операционной системе - это процесс; каждый из них имеет уникальный идентификатор, называемый идентификатором процесса (или просто идентификатором процесса , то есть PID). Linux предоставляет два механизма для создания процесса: 1.
fork()
системный вызов или 2.exec()
вызов.Поток ядра - это легкий процесс, а также выполняемая программа. Один процесс может состоять из нескольких потоков, использующих одни и те же данные и ресурсы, но идущих разными путями в программном коде. Linux предоставляет
clone()
системный вызов для генерации потоков.Примеры использования потоков ядра: синхронизация данных в ОЗУ, помощь планировщику в распределении процессов между процессорами и т. Д.
источник
Вкратце: ядро работает в пространстве ядра, пространство ядра имеет полный доступ ко всей памяти и ресурсам, можно сказать, что память делится на две части, часть для ядра и часть для собственного процесса пользователя, (пользовательское пространство) запускает обычные программы, пользователь space не может получить прямой доступ к пространству ядра, поэтому он запрашивает у ядра использование ресурсов. по системному вызову (предопределенный системный вызов в glibc)
есть утверждение, которое упрощает различные « Пользовательское пространство - это просто тестовая загрузка для ядра » ...
Чтобы быть предельно ясным: архитектура процессора позволяет ЦП работать в двух режимах, режиме ядра и режиме пользователя , инструкция оборудования позволяет переключаться из одного режима в другой.
память может быть помечена как часть пользовательского пространства или пространства ядра.
Когда ЦП работает в режиме пользователя, ЦП может получить доступ только к памяти, которая находится в пространстве пользователя, в то время как ЦП пытается получить доступ к памяти в пространстве ядра, результатом является «аппаратное исключение», когда ЦП работает в режиме ядра, ЦП может обращаться напрямую. как в пространство ядра, так и в пространство пользователя ...
источник
Пространство ядра означает, что к пространству памяти может обращаться только ядро. В 32-битном Linux это 1 ГБ (от 0xC0000000 до 0xffffffff в качестве адреса виртуальной памяти). Каждый процесс, созданный ядром, также является потоком ядра, поэтому для одного процесса существует два стека: один стек в пользовательском пространстве для этого процесса, а другой в ядре место для нити ядра.
стек ядра занимал 2 страницы (8k в 32-битном Linux), включая task_struct (около 1k) и реальный стек (около 7k). Последний используется для хранения некоторых автоматических переменных или параметров вызова функций или адреса функции в функциях ядра. Вот код (Processor.h (linux \ include \ asm-i386)):
__get_free_pages (GFP_KERNEL, 1)) означает выделение памяти как 2 ^ 1 = 2 страницы.
Но стек процесса - это другое дело, его адрес просто ниже 0xC0000000 (32-битный Linux), его размер может быть намного больше, используется для вызовов функций пользовательского пространства.
Итак, возникает вопрос о системном вызове, он работает в пространстве ядра, но был вызван процессом в пространстве пользователя, как это работает? Будет ли Linux помещать свои параметры и адрес функции в стек ядра или процесса? Решение Linux: все системные вызовы запускаются программным прерыванием INT 0x80. Определено в entry.S (linux \ arch \ i386 \ kernel), вот несколько строк, например:
источник
По Сунил Ядав, на Quora:
источник
Вкратце пространство ядра - это часть памяти, в которой работает ядро Linux (верхнее виртуальное пространство 1 ГБ в случае Linux), а пространство пользователя - это часть памяти, в которой выполняется пользовательское приложение (нижние 3 ГБ виртуальной памяти в случае Linux. хочу узнать больше, см. ссылку ниже :)
http://learnlinuxconcepts.blogspot.in/2014/02/kernel-space-and-user-space.html
источник
Попытка дать очень упрощенное объяснение
Виртуальная память разделена на пространство ядра и пространство пользователя. Пространство ядра - это область виртуальной памяти, в которой будут выполняться процессы ядра, а пространство пользователя - это область виртуальной памяти, в которой будут выполняться пользовательские процессы.
Это разделение требуется для защиты доступа к памяти.
Каждый раз, когда загрузчик запускает ядро после загрузки его в место в ОЗУ (обычно на контроллере на базе ARM), ему необходимо убедиться, что контроллер находится в режиме супервизора с отключенными FIQ и IRQ.
источник
Пространство ядра и пространство пользователя - это логические пространства.
Большинство современных процессоров предназначены для работы в другом привилегированном режиме. Машины x86 могут работать в 4 различных привилегированных режимах.
И конкретная машинная команда может выполняться, когда находится в / выше определенного привилегированного режима.
Благодаря такому дизайну вы обеспечиваете защиту системы или закрываете среду выполнения.
Ядро - это фрагмент кода, который управляет вашим оборудованием и обеспечивает абстракцию системы. Таким образом, он должен иметь доступ ко всем машинным инструкциям. И это самая надежная программа. Так что я должен быть выполнен с высшими привилегиями. А уровень звонка 0 - самый привилегированный режим. Таким образом, уровень кольца 0 также называется режимом ядра. .
Пользовательское приложение - это часть программного обеспечения, поставляемого любым сторонним поставщиком, и вы не можете полностью доверять ему. Кто-то со злым умыслом может написать код для сбоя вашей системы, если у него будет полный доступ ко всем машинным инструкциям. Поэтому приложению должен быть предоставлен доступ к ограниченному набору инструкций. А Ring Level 3 - наименее привилегированный режим. Итак, все ваше приложение работает в этом режиме. Следовательно, уровень звонка 3 также называется пользовательским режимом .
Примечание: я не получаю уровни звонка 1 и 2. В основном это режимы с промежуточными привилегиями. Так что код драйвера устройства может выполняться с этой привилегией. AFAIK, linux использует только Ring Level 0 и 3 для выполнения кода ядра и пользовательского приложения соответственно.
Таким образом, любую операцию, происходящую в режиме ядра, можно рассматривать как пространство ядра. И любую операцию, происходящую в пользовательском режиме, можно рассматривать как пространство пользователя.
источник
Правильный ответ: не существует таких вещей, как пространство ядра и пространство пользователя. Набор команд процессора имеет специальные разрешения для установки деструктивных вещей, таких как корень карты таблицы страниц или доступа к памяти аппаратного устройства и т. Д.
Код ядра имеет самый высокий уровень привилегий, а код пользователя - самый низкий. Это предотвращает сбой системы пользовательским кодом, изменение других программ и т. Д.
Обычно код ядра хранится под другой картой памяти, чем пользовательский код (так же, как пользовательские пространства хранятся в разных картах памяти, чем друг друга). Отсюда и произошли термины «пространство ядра» и «пространство пользователя». Но это не жесткое правило. Например, поскольку x86 косвенно требует, чтобы его обработчики прерываний / прерываний всегда отображались, часть (или все ОС) ядра должна быть отображена в пользовательское пространство. Опять же, это не означает, что такой код имеет права пользователя.
Почему необходимо разделение ядра / пользователя? Некоторые дизайнеры не согласны с тем, что это действительно необходимо. Архитектура микроядра основана на идее, что разделы кода с наивысшими привилегиями должны быть как можно меньше, а все важные операции должны выполняться в коде с привилегиями пользователя. Вам нужно будет изучить, почему это может быть хорошей идеей, это непростая концепция (и известна как своими преимуществами, так и недостатками).
источник
Память делится на две отдельные области:
Процессы, запущенные в пользовательском пространстве, имеют доступ только к ограниченной части памяти, тогда как ядро имеет доступ ко всей памяти. Процессы, запущенные в пространстве пользователя, также не имеют доступа к пространству ядра. Процессы пользовательского пространства могут получить доступ только к небольшой части ядра через интерфейс, предоставляемый ядром - системные вызовы. Если процесс выполняет системный вызов, ядру отправляется программное прерывание, которое затем отправляет соответствующий обработчик прерывания и продолжает работу. его работа после того, как обработчик закончил.
источник
В Linux есть два пространства: первое - это пространство пользователя, а второе - пространство ядра. пространство пользователя состоит только из пользовательского приложения, которое вы хотите запустить. в качестве службы ядра есть управление процессами, управление файлами, обработка сигналов, управление памятью, управление потоками и многие другие службы. если вы запускаете приложение из пользовательского пространства, это приложение взаимодействует только с ядерной службой. и эта служба взаимодействует с драйвером устройства, который присутствует между оборудованием и ядром. Основное преимущество разделения пространства ядра и пространства пользователя заключается в том, что мы можем обеспечить безопасность с помощью virus.bcaz всего пользовательского приложения, присутствующего в пространстве пользователя, и службы, присутствующей в пространстве ядра. Вот почему Linux не действует на вирусы.
источник