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

Попробуйте следующее:

query-auth-system | grep "^5\\>"
  • ^:означает "совпадение в начале строки
  • \\>:соответствует границе слова -. Таким образом, он будет соответствовать 5, но не 50.
1
02.02.2021, 18:04
2 ответа

Я не изучал исторический контекст использования одного прерывания (0x80 )для системных вызовов на i386, есть несколько причин не использовать отдельные программные прерывания для отдельные системные вызовы.

  • Количество программных прерываний ограничено, что ограничивает количество системных вызовов (, а на x86 ряд записей в таблице дескрипторов прерываний необходимо использовать для других целей ). В настоящее время существует больше системных вызовов, чем может поддерживаться на большинстве архитектур, использующих программные прерывания.
  • Довольно много архитектур имеют специальные инструкции системных вызовов, которые не используют программные прерывания (или их эквиваленты ). Сюда входят x86 -64, , где выделенная инструкция SYSCALLобеспечивает более быстрый доступ к системным вызовам, чем программные прерывания .man 2 syscallподробно описывает соглашения о системных вызовах для каждой архитектуры.

Если вы посмотрите на детали архитектуры ARM/OABI, у вас может сложиться впечатление, что там использовалась таблица прерываний, поскольку номер системного вызова закодирован в инструкции;но соответствующая инструкция выполняет фиксированное программное прерывание, игнорируя закодированное число, и обработчик системного вызова извлекает число из самой инструкции. От этого подхода отказались для EABI, потому что он приводил к загрязнению кеша (. Более поздние процессоры ARM имеют отдельные кеши инструкций и данных ).

3
18.03.2021, 22:32

Во-первых, x86 (-64 )поддерживает таблицу прерываний из 256 записей , некоторые из которых используются для реальных аппаратных прерываний. Если считать из справочной страницы syscalls(2)здесь , в Linux существует более 400 различных системных вызовов. Вероятно, не все существуют на всех архитектурах, но также, согласно другому списку , существует 314 различных системных вызовов на x86 -64 (от 0 до 313 ). Таким образом, по крайней мере для Linux на x86, похоже, нет возможности зарезервировать отдельный номер прерывания для каждого системного вызова.

Конечно, x86 — не единственная существующая архитектура. Возможно, у других программных прерываний еще меньше или они имеют совершенно другой путь для системных вызовов, отдельный от аппаратных прерываний. На самом деле современные x86 (-64 )уже имеют такой отдельный путь, посредством инструкций SYSCALL и SYSENTER:

The SYSENTER/SYSEXIT instructions (and equivalent SYSCALL/SYSRET on AMD) enable fast entry to the kernel, avoiding interrupt overhead.

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


Обратите внимание, что большая часть вышеизложенного в значительной степени просто предположение, я совсем не знаком ни с одной архитектурой, отличной от -x86 (, за исключением, возможно, некоторых, которые не работают с ОС общего -назначения ). ] и не рассматривал реализацию системных вызовов Linux так внимательно, не говоря уже о других операционных системах. Если вам нужны более низкие детали уровня -, я надеюсь, что кто-то другой сможет их предоставить.

1
18.03.2021, 22:32

Теги

Похожие вопросы