Ядро Linux в комментариях



System_call - часть 5


Возврат их вызова системы трассировки; управление передается ret_from_sys_call (строка ), как и в случае, когда трассировка отсутствует.

Метка badsys достигается, когда передаваемый номер системного вызова выходит за пределы допустимых значений. В таком случае system_call должен вернуть -ENOSYS (значение ENOSYS устанавливается равным 38 в строке ). Как упоминалось ранее, вызывающая функция воспринимает это как ошибку, поскольку значение возврата попадает в диапазон между –1 и –4095.

Метка ret_from_exception достигается, когда имеют место прерывания в исключительных ситуациях ЦП, такие как ошибка деления на ноль (см. строку ); эта метка никогда не достигается из кода system_call. В случае активности «нижней половины» обеспечивается ее обслуживание.

Метка ret_from_intr достигается после обработки «нижней половины» либо когда имеет место случай возникновения исключительной ситуации ЦП. К данной метке имеется глобальный доступ из многих мест в ядре.

Сохраненные регистры ЦП EFLAGS и CS комбинируются в ЕАХ таким образом, что старших 24 разряда (в том числе и одно интересное значение VM_MASK, определенное в строке ) представляют EFLAGS, а младших 8 разрядов — из CS. Эта строка скрыто проверяет части обоих регистров одновременно, чтобы выяснить, вернулся ли процесс в виртуальный режим 8086 (часть VM_MASK) или в пользовательский режим (часть с константой 3 — пользовательский режим имеет уровень привилегий 3). Эквивалентный код на С выглядит следующим образом:

/* Скомпоновать в еах значения eflags и cs. */ еах = eflags & ~0xff; еах |= cs & 0xff; /* Проверить одновременно 2 младших разряда и разряд VM_MASK. */ if (еах & (VM_MASK | 3)) goto ret_with_reschedule; goto restore_all;

Если одно из двух условий оказывается истинным, управление передается на метку ret_with_reschedule (строка ) для выяснения того, следует ли выполнить повторное планирование для процесса перед возвратом из system_call. В противном случае system_call пропускает часть, относящаяся к повторному планированию, и переходит на метку restore_all (строка ), поскольку вызов был произведен задачей ядра.

Метка handle_bottom_half достигается всякий раз, когда в system_call имеется «нижняя половина». Все сводится к вызову функции С с именем do_bottom_half (строка ; см. ) и переходу на метку ret_from_intr (строка ).

Последний компонент system_call находится под меткой reschedule. Эта метка достигается, когда процесс, выполнивший системный вызов, помечен как такой, для которого необходимо выполнить повторное планирование; как правило, подобное происходит в случае, если выделенный для процесса квант времени исчерпан и ЦП следует отдать для других процессов. За подобного рода обработку отвечает функция С с именем schedule (строка ). Далее управление переходит на строку . Планированию процессов посвящена вся .




Содержание  Назад  Вперед