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

       

Linux поддерживает стандарт, именуемый Intel


Linux поддерживает стандарт, именуемый Intel Binary Compatibility Specification, версия2 (iBCS2, Спецификация двоичной совместимости Intel). (To, что в названии стандарта 1BCS2 буква i является строчной, а не прописной, сделано явно умышленно, однако никаких официальных объяснений сему факту не имеется; скорее всего, это объясняется попыткой согласовать название стандарта с принятой практикой именования процессоров Intel: i386, i486 и т.д.) Спецификация iBCS2 распределяет стандартный интерфейс ядра для приложений по всем базирующимся на Unix системам, куда относятся не только Linux, но и ряд бесплатных Unix-подобных систем для процессоров х86 (таких как FreeBSD), Solaris/x86, SCO Unix и т.п. Стандартный интерфейс делает возможным запуск двоичного представления коммерческого программного обеспечения, которое разрабатывалось для других Unix-подобных систем, на компьютере с установленным Linux и наоборот (причем в последнее время это «наоборот» случается все чаще и чаще). Например, двоичное представление Corel WordPerfect для SCO Unix, за счет соответствия стандарту iBCS2, отлично работает под Linux, даже не имея специальной версии для Linux.

Стандарт iBCS2 имеет несколько компонентов, одна из которых представляет особый интерес для нас: каким образом достигается непротиворечивая обработка системных вызовов в различных модификациях Unix. Это становится возможным благодаря наличию шлюза вызовов lcall7. lcall7 представляет собой достаточно простую (особенно по сравнению с system_call) ассемблерную функцию, которая всего лишь отыскивает С-функцию, занимающуюся соответствующей обработкой, и передает ей все полномочия по совершению требуемых действий. Шлюз вызовов (call gate) — это возможность, заложенная в процессоры х86, позволяющая пользовательским задачам обращаться к коду ядра безопасным и управляемым способом. Шлюз вызовов устанавливается в строке .



В нескольких первых строках выполняется настройка стека ЦП, чтобы он выглядел так, как того ожидает system_call.

Опять-таки подобно system_call, lcall7 получает указатель на текущую задачу в регистре ЕВХ. Что несколько удивляет, так это то, что способ реализации не такой, как в system_call. Три строки кода, начиная с , эквивалентны следующим двум строкам:

pushl %esp GET_CURRENT(%ebx)

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

Получение указателя на поле exec_domain текущей задачи, использование этого поля для поиска указателя на соответствующий обработчик lcall7 и вызов найденного обработчика.

Области выполнения детально в книге не рассматриваются, однако следует знать что они используются ядром для реализации части стандарта iBCS2. В строке находится определение struct exec_domain. Область выполнения по умолчанию default_exec_domam (строка ) содержит стандартный обработчик lcall7 — no_lcall7 (см. строку ), который ведет себя подобно разновидности Unix под названием SVR4, отправляя вызываемому процессу сигнал нарушения сегментации.

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


Содержание раздела