стек ядра и стек пользовательского пространства

в чем разница между стеком ядра и стеком пользователя? Почему используется стек ядра? Если локальная переменная объявлена в ISR, где она будет храниться? Каждый процесс имеет свой собственный стек ядра ? Тогда как процесс координируется между этими стеками?

3 ответов


  1. в чем разница между стеком ядра и стеком пользователя ?

короче говоря, ничего-кроме использования другого местоположения в памяти (и, следовательно, другого значения для регистра stackpointer), и обычно разные защиты доступа к памяти. Т. е. при выполнении в пользовательском режиме память ядра (частью которой является стек ядра) будет недоступна, даже если она сопоставлена. Наоборот, без явного запроса со стороны код ядра (в Linux, через такие функции, как copy_from_user()), память пользователя (включая пользовательский стек) обычно не доступна напрямую.

  1. почему используется [отдельный ] стек ядра ?

Разделение привилегий и безопасности. Во-первых, программы userspace могут делать свой стек(указатель) все, что они хотят, и обычно нет архитектурного требования даже иметь действительный. Поэтому ядро не может доверие userspace stackpointer должен быть действительным и не использоваться, и поэтому потребуется один набор под собственным контролем. Различные архитектуры ЦП реализуют это по-разному; процессоры x86 автоматически переключают stackpointers при переключении режима привилегий, а значения, используемые для разных уровней привилегий, настраиваются - привилегированным кодом (т. е. только ядром).

  1. если локальная переменная объявлена в ISR, где она будет хранится ?

в стеке ядра. Ядра (ядро Linux, то есть) делает не hook ISRs непосредственно к архитектуре x86 прерывание ворота но вместо этого делегирует отправку прерывания общему механизму входа/выхода прерывания ядра, который сохраняет состояние регистра перед вызовом зарегистрированных обработчиков. Сам процессор при отправке прерывания может выполнить привилегию и / или переключатель стека, и это используется / настраивается ядром так, чтобы общий код записи прерывания уже мог полагаться на присутствующий стек ядра.
Тем не менее, прерывания, возникающие при выполнении кода ядра, будут просто (продолжать) использовать стек ядра на месте в этот момент. Это может, если обработчики прерываний имеют глубоко вложенные пути вызова, привести к переполнению стека (если глубокий путь вызова ядра прерывается, и обработчик вызывает другой глубокий путь; в Linux файловая система / программный RAID-код прерывается известно, что сетевой код с активными iptables запускает такие в не настроенных старых ядрах ... решение заключается в увеличении размеров стека ядра для таких рабочих нагрузок).

  1. каждый процесс имеет свой собственный стек ядра ?

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

  1. как процесс координируется между обоими этими стеками ?

вовсе нет - в этом нет необходимости. Планирование (как / когда выполняются разные потоки, как сохраняется и восстанавливается их состояние) - это задача операционной системы, и процессам не нужно беспокоиться об этом. По мере создания потоков (и каждый процесс должен иметь хотя бы один поток), ядро создает для них стеки ядра, в то время как стеки пользовательского пространства либо явно создаются/предоставляются любым механизмом, используемым для создания потока (такие функции, как makecontext() или pthread_create() разрешить вызывающему указать область памяти, которая будет использоваться для стека "дочернего" потока) или унаследована (путем клонирования памяти при доступе, обычно называемого "копировать при записи" / COW, при создании нового процесса).
Тем не менее, процесс can планирование влияния своих потоков и / или влиять на контекст (состояние, среди которых есть stackpointer потока). Для этого существует несколько способов: Unix signals,setcontext(), pthread_yield() / pthread_cancel(), ... - но это disgressing немного от изначального вопроса.


мой ответ собран из других вопросов SO с моими материалами.

What's the difference between kernel stack and user stack?

как программист ядра, вы знаете, что ядро должно быть ограничено ошибочными пользовательскими программами. Предположим, вы храните один и тот же стек для ядра и пользовательского пространства, а затем simple segfault в пользовательском приложении аварийно завершает работу ядра и требует перезагрузки.

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

http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html

Why kernel stack is used?

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

http://www.kernel.org/doc/Documentation/x86/kernel-stacks

If a local variable is declared in an ISR, where it will be stored?

он будет храниться в ISR стек (IRQSTACKSIZE). ISR работает на отдельном стеке прерываний, только если аппаратное обеспечение поддерживает его. В противном случае кадры стека ISR будут помещены в стек прерванного потока.

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

 Does each process has its own kernel stack ?

да. Каждый процесс имеет свое ядро стек.

 Then how the process coordinates between both these stacks?

ответ@FrankH выглядит отлично для меня.


  1. в чем разница между стеком ядра и пользовательским стеком

принимая ссылку на разработку ядра Linux Роберта лова, основное различие заключается в размере:

User-space может уйти от статического распределения многих переменных в стеке, включая огромные сооружения и тысяч элементов массивов.
Это поведение является законным, потому что user-space имеет большой стек, который может динамически расти.
Стек ядра не является ни большим, ни динамическим; он мал и фиксирован по размеру.
Точный размер стека ядра зависит от архитектуры.
На x86, размер стека настраивается на время компиляции и может быть 4KB или 8KB.
Исторически стек ядра состоит из двух страниц, что обычно подразумевает, что это 8KB на 32-битных архитектурах и 16KB на 64-битных архитектурах-это размер фиксированный и абсолютный.
Каждый процесс получает свое стек.

также стек ядра содержит указатель на структуру struct thread_info информацией о нити.