стек ядра та стек простору користувача


110

Яка різниця між стеком ядра та стеком користувача? Для чого використовується стек ядра? Якщо локальна змінна оголошена в ISR, де вона буде зберігатися? Чи кожен процес має свій стек ядра? Тоді як процес координує обидва ці стеки?

Відповіді:


187
  1. Яка різниця між стеком ядра та стеком користувача?

Коротше кажучи, нічого - крім використання іншого місця в пам'яті (а значить, і іншого значення для реєстру стекпоінтера), і зазвичай різних захистів доступу до пам'яті. Тобто при виконанні в користувальницькому режимі пам’ять ядра (частиною якого є стек ядра) не буде доступною, навіть якщо їх відображено. І навпаки, без явного запиту коду ядра (в Linux через такі функції copy_from_user()), як правило, пам'ять користувача (включаючи стек користувача) зазвичай не доступна безпосередньо.

  1. Чому використовується [окремий] стек ядра?

Поділ пільг та безпеки. Для одного, програми простору користувачів можуть робити свій стек (покажчик) все, що завгодно, і зазвичай немає архітектурних вимог навіть мати дійсну. Тому ядро ​​не може довіряти стек-покажчику простору користувача, щоб воно було дійсним чи корисним, і тому буде потрібно один набір під його власним контролем. Різні архітектури процесора реалізують це по-різному; Процесори x86 автоматично перемикають стек-покажчики, коли трапляються перемикачі режиму привілеїв, і значення, що використовуються для різних рівнів привілеїв, можна налаштувати - за допомогою привілейованого коду (тобто лише ядра).

  1. Якщо локальна змінна оголошена в ISR, де вона буде зберігатися?

На стеку ядра. Ядро (Linux ядро, тобто) не підключає ISR безпосередньо до воріт переривання архітектури x86, а замість цього делегує пересилку переривання загальним механізмом входу / виходу з переривання ядра, який зберігає стан реєстрації попереднього переривання перед викликом зареєстрованого обробника (ів) . Сам процесор при відправленні переривання може виконати привілей та / або стек-комутатор, і це використовується / налаштоване ядром, щоб загальний код запису переривання вже міг покладатися на наявний стек ядра.
Однак, переривання, які виникають під час виконання коду ядра, просто (продовжують) використовувати стек ядра на місці в цій точці. Це може, якщо обробники переривань мають глибоко вкладені шляхи викликів, призвести до переповнення стека (якщо глибокий шлях виклику ядра перерваний і обробник викликає ще один глибокий шлях; в Linux, RAID-код файлової системи та програмного забезпечення переривається мережевим кодом з активним iptables Відомо, що він запускає такі у ненутованих старих ядрах ... рішення полягає в збільшенні розміру стека ядра для таких навантажень).

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

Не тільки кожен процес - кожен потік має власний стек ядра (і, власне, також власний стек користувача). Пам'ятайте, що єдиною відмінністю між процесами та потоками (для Linux) є те, що декілька потоків можуть ділити адресний простір (утворюючи процес).

  1. Як процес координує обидва ці стеки?

Зовсім не - це не потрібно. Планування (як / коли запускаються різні потоки, як зберігається і відновлюється їх стан) - це завдання операційної системи і процесам не потрібно цим займатися. Оскільки нитки створюються (і кожен процес повинен мати принаймні один потік), ядро ​​створює для них стеки ядер, тоді як стеки простору користувачів або явно створюються / надаються залежно від того, який механізм використовується для створення потоку (функції, як makecontext()або pthread_create()дозволяють абоненту вкажіть область пам’яті, яка буде використовуватись для стека «дочірнього» потоку) або успадкована (шляхом клонування пам’яті під час доступу, зазвичай її називають «копіювати при записі» / COW, під час створення нового процесу).
Це сказав:(стан, серед якого є стек-покажчик потоку). Є кілька способів для цього: сигналів UNIX, setcontext(), pthread_yield()/ pthread_cancel(), ... - але це disgressing трохи від початкового питання.


Відмінно відповідає FrankH. Дякую.
кумар

1
@FrankH Відмінна відповідь .. але у мене є невеликі питання, пов’язані з цим, але в архітектурі ARM .. Як цей стек ядра пов'язаний з різним режимом процесора?
Рахул

2
@Rahul: "поле коментаря SO занадто мало, щоб містити таку відповідь". Як працюють регістри стеків / стекпоінтер в різних режимах процесора ARM (які реалізують банківський SP), є хорошим питанням, але для відповіді потрібно більше місця, ніж коментар. Це ж стосується таких речей, як ворота завдань x86 або IST - немає такого поняття, як "єдиний" покажчик стека ядра (так само, як немає "єдиного" вказівника стека користувача), а також для апаратної підтримки / мандату. окремі покажчики стеків у різних режимах роботи ... дуже залежні від обладнання.
Френк.

@FrankH. Я створив нове запитання для того ж… stackoverflow.com/q/22601165/769260 Я сподіваюся, що тепер ви можете мені допомогти, не піклуючись про місце :)
Рахул,

1
@FrankH. Чи можете ви надати схему, що показує, куди належить стек ядра в макеті пам'яті процесу?
Jithin Pavithran

19

Моя відповідь зібрана з інших запитань ТА з моїми матеріалами.

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

Як програміст ядра, ви знаєте, що ядро ​​повинно бути обмежене помилковими програмами користувача. Припустимо, ви зберігаєте однаковий стек як для ядра, так і для користувальницького простору, а потім простий сегмент за замовчуванням в програмі користувача вибиває ядро ​​і потребує перезавантаження.

Існує один "стек ядра" на процесор, як ISR Stack і один "стек ядра" на Process. Існує один "стек користувача" для кожного процесу, хоча кожен потік має свій стек, включаючи і потоки користувача, і ядра.

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 мені прекрасно виглядає.


4
  1. Яка різниця між стеком ядра та стеком користувача

Посилаючись на розробку Linux ядра Роберта Лава, головна відмінність - розмір:

Користувальницький простір може позбутися статичного розподілу багатьох змінних на стеку, включаючи величезні структури та масиви тисяч елементів.
Така поведінка є законною, оскільки у просторі користувача є великий стек, який може динамічно зростати.
Стек ядра не є ні великим, ні динамічним; вона невелика і зафіксована в розмірах.
Точний розмір стека ядра залежить від архітектури.
На x86 розмір стека може бути налаштований під час компіляції і може становити 4 КБ або 8 КБ.
Історично стек ядра становить дві сторінки, що, як правило, означає, що він становить 8 КБ для 32-бітових архітектур і 16 КБ для 64-бітових архітектур - цей розмір є фіксованим і абсолютним.
Кожен процес отримує свій стек.

Також стек ядра містить вказівник на структуру потоку_info, що містить інформацію про потік.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.