2012-01-16 3 views
5

я просто читал до того, как Linux работает в моей ОС-книги, когда я наткнулся на это ..Системный вызов без переключения контекста?

[...] ядро ​​создается как единый, монолитное двоичный. Основная причина - повысить производительность. Поскольку все коды ядра и структуры данных хранятся в одном адресном пространстве, при вызове функции операционной системы или при поставке аппаратного прерывания не требуются переключатели контекста.

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

Оба системных вызова и прерывания, возникающие во время выполнения процесса, будут использовать этот стек.

«этот стек» - это место, где ядро ​​хранит регистры процесса и т. Д.

Разве это не прямое противоречие с первой цитатой? Мне что-то не нравится?

ответ

3

Я думаю, что первая цитата относится к различиям между монолитным ядром и microkernel.

Linux является монолитным, все его компоненты ядра (драйверы устройств, планировщик, диспетчер VM) работают на ring 0. Поэтому при выполнении системных вызовов и обработке прерываний не требуется контекстного переключателя.

Контрастные микроядра, где компоненты, такие как драйверы устройств и провайдеры IPC, работают в user space, вне кольца 0. Поэтому для выполнения этой архитектуры требуется дополнительные переключатели контекста при выполнении системных вызовов (поскольку исполняемый модуль может находиться в пространстве пользователя) и обрабатывать прерывания (для передачи прерываний на драйверы устройства).

+0

Спасибо. Прошло много времени с тех пор, как я изучил это, но у меня создалось впечатление, что аппаратные прерывания фактически _interrupts_ выполнения и сразу переходят к процедуре обработки, а не для опроса для прерываний позже. Я понял, что если бы процесс выполнялся в режиме ядра, ему все равно нужно было сохранить его контекст до этого перехода, но, возможно, это была моя ошибка? Я полагаю, что теперь это ничем не отличается от любого другого вызова метода, если вызываемый метод правильно обрабатывает используемые регистры. Я правильно понял? – user1130005

+0

Мое понимание заключается в том, что процесс выполняется в пользовательском режиме, и есть действительно переход к режиму контекста в режиме ядра до обработки прерывания. Однако * обработка * прерывание не требует дополнительного переключателя контекста в монолитных ядрах, но в микроядрах (поскольку драйверы устройств находятся в пространстве пользователя). –

2

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

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

Так что, по крайней мере, вы говорить 2-3 стека или места для хранения «контекста»: аппаратные прерывания нуждаются в стеке уровня ядра, чтобы сказать, к чему вернуться; пользовательский метод/вызовы подпрограммы используют стандартный стек для этого. И т. Д.

Оригинальные ядра Unix - и модель сейчас не такая уж иная для этой части - выполнялись системные вызовы, такие как заказы на поставку по заказу коротких заказов: переместите это на плиту, чтобы освободить место для заказа из бекона, который только что прибыл, запустите бекон, вернитесь в первый заказ. Все в контексте переключения ядра. Это не было огромное приложение для мониторинга, которое, вероятно, приводило людей в замешательство от программ IBM и DEC.

0

При выполнении системного вызова в Linux контекстный переключатель выполняется из пространства пользователя в пространство ядра (ring3 to ring0). Каждый процесс имеет связанный стек режима ядра, который используется системным вызовом.Перед выполнением системного вызова регистры процессора процесса хранятся в стеке пользовательского режима, этот стек отличается от стека режима ядра и является тем, который процесс использует для выполнения пользователем.

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

Вторая цитата относится к стекю режима ядра, а не стек пользовательского режима.

Сказав это, я должен упомянуть оптимизацию Linux, где переход к ядерному пространству для выполнения системного вызова не требуется, т. Е. Вся обработка, связанная с системным вызовом, выполняется в самом пользовательском пространстве (таким образом, no context switch). vsyscall, и VDSO - такие методы. Идея, стоящая за ними, довольно проста. Это нужно отправить в пространство пользователя, данные, необходимые для выполнения соответствующего системного вызова. Больше информации можно найти в this LWN article.

В дополнение к этому были проведены некоторые исследовательские проекты, в которых все исполнение происходит в одном кольце. Программы пользовательского пространства и код ОС, оба находятся в same ring. Идея состоит в том, чтобы избавиться от накладных расходов на кольцевые коммутаторы. Microsoft's [singularity][2] OS - один из таких проектов.

Смежные вопросы