Подтвердить что ты не робот

Внутренние системные вызовы Linux

Что происходит (подробно), когда поток выполняет системный вызов, поднимая прерывание 80? Какую работу делает Linux для стека потоков и другого состояния? Какие изменения внесены в процессор, чтобы перевести его в режим ядра? После запуска обработчика прерываний, как управление возвращается к вызывающему процессу?

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

4b9b3361

Ответ 1

Курс сбоя в режиме ядра в одном ответе

Хорошие вопросы! (Интервью вопросы?)


  • Что происходит (подробно), когда thread делает системный вызов, поднимая прерывание 80?

Операция int $80 смутно напоминает вызов функции. ЦП "берет ловушку" и перезапускается по известному адресу в режиме ядра, как правило, с другим режимом MMU. Ядро сохранит многие регистры, но не нужно сохранять регистры, которые программа не ожидала бы обычного вызова функции для сохранения.

  • Что делает Linux для стек стека и другое состояние?

Обычно ОС сохраняет регистры, которые ABI promises не изменяется во время вызовов процедур. Стек останется неизменным; ядро будет запускаться в стеке ядра на потоке, а не в стеке каждого потока. Естественно, какое-то состояние изменится, иначе не было бы причин для системного вызова.

  • Какие изменения внесены в процессор, чтобы перевести его в режим ядра?

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

  • После запуска обработчика прерываний, как управление возвращается обратно в вызывающий процесс?

Будет какая-то команда "возврат от прерывания" или "возврат из ловушки", как правило, которая будет немного похожа на сложную инструкцию функции-возврата. Некоторые RISC-процессоры выполняли очень мало и требовали специального кода для возврата, а некоторые процессоры CISC, такие как x86, имели (никогда не использовавшиеся) инструкции, которые выполняли бы десятки операций, задокументированных на страницах псевдо-кода с архитектурой для корректировки возможностей.

  • Что делать, если системный вызов не может быть быстро завершается: например. чтение из диск. Как обработчик прерываний отказаться от контроля, чтобы процессор может делать другие вещи, пока данные загружаются и как это делается затем снова получить контроль?

Ядро само по себе имеет многопоточность, как многопоточная программа пользователя. Он просто переключает стеки (потоки) и некоторое время работает над кем-то другим процессом.

Ответ 2

Чтобы ответить на последнюю часть вопроса - что делает ядро, если системный вызов нужно спать -

После системного вызова ядро ​​по-прежнему логически работает в контексте той же задачи, что и системный вызов - это только в режиме ядра, а не в пользовательском режиме - это НЕ отдельный поток, и большинство системных вызовов не вызывают логики из другой задачи/потока. Случается, что системный вызов вызывает wait_event или wait_event_timeout или какую-либо другую функцию ожидания, которая добавляет задачу в список задач, ожидающих чего-то, затем ставит задачу в спящий режим, который меняет свое состояние, и вызывает расписание(), чтобы отказаться от него текущий процессор.

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

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

Ответ 4

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

https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-2.html