2013-04-10 2 views
4

У меня возник вопрос относительно глубокой работы Linux.Последовательность потока системного вызова Linux

Допустим, в CPU выполняется многопоточный процесс. В этом случае у нас будет поток, который выполняется на CPU. На более широкой картинке у нас будет соответствующая страница, принадлежащая Процессу, загружаемому в ОЗУ для выполнения.

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

Допустим, что система имеет поток потока пользовательского уровня m: n для сопоставления потоков уровня ядра, я предполагаю, что соответствующий поток уровня ядра ответит на этот вызов.

Таким образом, ядро ​​будет искать векторную таблицу прерываний и получить процедуру, которая должна быть выполнена. Мой следующий вопрос: какой стек будет использоваться при выполнении прерывания? Будет ли это стек ядра или стек уровня Thread? (Я предполагаю, что это будет стек ячеек ядра.)

Возвращаясь к потоку программы, можно сказать, что операция открывает файл с использованием fopen. Следующий вопрос, который у меня есть, - как произойдет переход от ISR к System Call? Или наш ISR отображается на системный вызов?

Также при более широком изображении, когда выполняется поток ядра, я предполагаю, что «область ОС» в ОЗУ будет использоваться для размещения страниц, выполняющих системный вызов.

Опять глядя на него под другим углом (надеюсь, что вы все еще со мной), наконец, я предполагаю, что соответствующий поток ядра обрабатывается Планировщиком CPU, где в контекстном переключателе произошло бы из потока пользовательского уровня соответствующая нить уровня ядра при ответе на системный вызов fopen.

Я сделал много предположений, и было бы абсолютно фантастично, если бы кто-нибудь мог устранить сомнения или хотя бы направить меня в правильном направлении.

+2

Не могли бы вы переформатировать стену текста, чтобы ее было немного легче читать? Благодарю. – NPE

+0

Также прочитайте несколько книг по программированию Linux. Сначала вам нужно понять сторону приложения, например. http://advancedlinuxprogramming.com/, тогда вам нужно понять точку зрения ядра, и многие книги также существуют ... –

+0

Привет Базиле, я прочитал несколько книг по Linux, и они почти дают мне ту же информацию. Однако я не могу сшить все вместе. Как работает вся процедура в режиме реального времени. –

ответ

7

Примечание: Я работаю преимущественно с машинами ARM, поэтому некоторые из этих вещей могут быть специфическими для ARM. Кроме того, я собираюсь попытаться упростить его, насколько смогу. Не стесняйтесь исправить все, что может быть неправильным или упрощенным.

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

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

Таким образом, ядро ​​будет искать векторную таблицу прерываний и получить процедуру, которая должна быть выполнена. Мой следующий вопрос: какой стек будет использоваться при выполнении прерывания? Будет ли это стек ядра или стек уровня Thread? (Я предполагаю, что это будет стек ячеек ядра.)

Я уверен, что он переключится на стек ядра.Там были бы довольно серьезные проблемы с безопасностью утечки информации, если они использовали стек пользовательского пространства.

Возвращаясь к потоку программы, можно сказать, что операция открывает файл с использованием fopen. Следующий вопрос, который у меня есть, - как произойдет переход от ISR к System Call? Или наш ISR отображается на системный вызов?

fopen() - фактически функция libc, а не системный вызов. Он может (и в большинстве случаев будет) вызывать open() syscall в его реализации.

Таким образом, процесс (примерно) составляет:

  1. называет пространство пользователя fopen()
  2. fopen выполняет системный вызов open()
  3. Это вызывает какое-то исключение или прерывание. В ответ процессор переходит в более привилегированный режим и начинает выполнение в определенном месте в ядре.
  4. Ядро определяет, какое прерывание и исключение оно есть, и обрабатывает его соответствующим образом. В нашем случае это будет системный вызов.
  5. Kernel определяет, какой системный вызов запрашивается, считывая регистры пользовательского пространства и извлекает любые аргументы и передает его соответствующему обработчику.
  6. Обработчик работает.
  7. Kernel помещает любой код возврата в регистры пользовательского пространства.
  8. Ядро переносит выполнение обратно туда, где произошло исключение.

Кроме того, на более широкую картину, когда нить ядра выполняется Я предполагаю, что «OS область» на RAM будет использоваться для размещения страниц, которые исполняющих системный вызов.

Страницы не выполняют ничего :) Обычно в Linux любой адрес, отображаемый выше 0xC0000000, принадлежит ядру.

Опять же, глядя на него с другого угла (Надеюсь, ты еще со мной), наконец, я предполагаю, что соответствующий поток ядра обрабатывается с помощью планировщика CPU, где переключение контекста произошло бы с уровня пользователя Thread к соответствующему потоку уровня ядра, на который ответили системный вызов fopen.

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

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

Это немного сложно объяснить, поэтому я надеюсь, что все правильно.

+0

У меня есть небольшой вопрос. В последнем абзаце вы упомянули, что поток будет в двух режимах, которые являются режимом пользователя и ядра. Итак, в соответствии с моим пониманием при выполнении системного вызова Thread переходит из режима пользователя в режим ядра. Мой вопрос в том, как это вписывается в модели Threading, поддерживаемые Linux, такие как 1; 1, 1: n и m: n потоков. Итак, если у нас есть 1: n, и у нас есть 2 потока, когда оба они производят системный вызов, в то же время другой будет заблокирован до тех пор, пока обслуживание этого потока не будет выполнено? –

+1

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