Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

В большинстве систем системные вызовы могут выполняться только из процессов пользовательского пространства , в то время как в некоторых системах, например, OS / 360 и последующих версиях, привилегированный системный код также выдает системные вызовы. [1]

Привилегии [ править ]

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

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

Библиотека как посредник [ править ]

Обычно системы предоставляют библиотеку или API, которые находятся между обычными программами и операционной системой. В Unix-подобных системах этот API обычно является частью реализации библиотеки C (libc), такой как glibc , которая предоставляет функции оболочки для системных вызовов, часто называемых так же, как системные вызовы, которые они вызывают. В Windows NT этот API является частью собственного API в библиотеке ntdll.dll ; это недокументированный API, используемый реализациями обычного Windows API.и напрямую используется некоторыми системными программами в Windows. Функции оболочки библиотеки предоставляют обычное соглашение о вызове функций ( вызов подпрограммы на уровне сборки ) для использования системного вызова, а также для того, чтобы сделать системный вызов более модульным . Здесь основная функция оболочки состоит в том, чтобы поместить все аргументы, передаваемые системному вызову, в соответствующие регистры процессора (а также, возможно, в стек вызовов ), а также установить уникальный номер системного вызова для вызова ядра. . Таким образом, библиотека, которая существует между ОС и приложением, увеличивает переносимость .

Сам вызов библиотечной функции не вызывает переключения в режим ядра и обычно является обычным вызовом подпрограммы (с использованием, например, инструкции сборки "CALL" в некоторых архитектурах набора команд (ISA)). Фактический системный вызов передает управление ядру (и в большей степени зависит от реализации и платформы, чем абстрагирующий его вызов библиотеки). Например, в Unix-подобных системах, forkи execveявляются C библиотечные функции , которые , в свою очередь выполнить инструкции , которые вызывают эти forkи execсистемные вызовы. Выполнение системного вызова непосредственно в коде приложения более сложно и может потребовать использования встроенного ассемблерного кода (в Cи C ++ ), а также знание низкоуровневого двоичного интерфейса для операции системного вызова, который может изменяться со временем и, таким образом, не быть частью двоичного интерфейса приложения ; библиотечные функции предназначены для того, чтобы абстрагироваться от этого.

В системах на основе экзоядра библиотека особенно важна как посредник. На экзоядрах библиотеки защищают пользовательские приложения от API ядра очень низкого уровня и обеспечивают абстракции и управление ресурсами .

OS / 360 и DOS / 360 IBM реализуют большинство системных вызовов через библиотеку макросов языка ассемблера , хотя есть несколько сервисов со связью вызовов. Это отражает их происхождение в то время, когда программирование на языке ассемблера было более распространенным, чем использование языка высокого уровня . Поэтому системные вызовы IBM не могли напрямую выполняться программами на языке высокого уровня, но требовали вызываемой подпрограммы-оболочки на языке ассемблера. С тех пор IBM добавила множество сервисов, которые можно вызывать из языков высокого уровня, например, в z / OS и z / VSE .

Примеры и инструменты [ править ]

На Unix , Unix-подобных и других POSIX - совместимые операционные системы, популярные системные вызовы open, read, write, close, wait, exec, fork, exit, и kill. Многие современные операционные системы имеют сотни системных вызовов. Например, Linux и OpenBSD имеют более 300 различных вызовов, [2] [3] NetBSD - около 500, [4] FreeBSD - более 500, [5] Windows 7 - около 700, [6] в то время как Plan 9 имеет 51. [7]

Такие инструменты, как Трассирование , ftrace и фермы позволяют процесс выполнения от начала и сообщать обо все системных вызовах процесса вызываемой программы , или может подключаться к уже запущенному процессу и перехватывать любой системный вызов , сделанный указанным способом , если операция не нарушает права доступа Пользователь. Эта особая способность программы обычно также реализуется с помощью системного вызова, например, strace реализуется с помощью ptrace или системных вызовов файлов в procfs .

Типичные реализации [ править ]

Реализация системных вызовов требует передачи управления из пользовательского пространства в пространство ядра, что включает в себя какую-то особенность, зависящую от архитектуры. Типичный способ реализации этого - использование программного прерывания или прерывания . Прерывания передают управление ядру операционной системы , поэтому программному обеспечению просто необходимо настроить некоторый регистр с необходимым номером системного вызова и выполнить программное прерывание.

Это единственный метод, предусмотренный для многих процессоров RISC , но архитектуры CISC, такие как x86, поддерживают дополнительные методы. Например, набор инструкций x86 содержит инструкции SYSCALL/ SYSRETи SYSENTER/ SYSEXIT(эти два механизма были независимо созданы AMD и Intel соответственно, но по сути они делают то же самое). Это «быстрые» инструкции передачи управления, которые предназначены для быстрой передачи управления ядру для системного вызова без накладных расходов, связанных с прерыванием. [8] Linux 2.5 начал использовать это на x86 , где это возможно; раньше он использовалINTинструкция, в которой номер системного вызова был помещен в EAX регистр до выполнения прерывания 0x80. [9] [10]

Более старый механизм - это шлюз вызова ; первоначально использовался в Multics, а затем, например, см. шлюз вызова на Intel x86 . Это позволяет программе вызывать функцию ядра напрямую, используя безопасный механизм передачи управления, который операционная система настраивает заранее. Этот подход был непопулярным на x86, предположительно из-за требования дальнего вызова (вызов процедуры, расположенной в другом сегменте, чем текущий сегмент кода [11] ), который использует сегментацию памяти x86 и, как следствие, отсутствие переносимости, которое вызывает , и наличие более быстрых инструкций, упомянутых выше.

Для архитектуры IA-64EPC используется инструкция (Enter Privileged Code). Первые восемь аргументов системного вызова передаются в регистры, а остальные передаются в стек.

В IBM System / 360 мэйнфреймов семьи, и его наследников, в инструкции супервизора вызовов ( SVC ), с номером в инструкции , а не в реестре, реализующий системный вызов для устаревших объектов в большинстве из [а] собственных операционных систем IBM, , и для всех системных вызовов в Linux. В собственных операционных системах IBM инструкция Program Call (PC) используется для более новых возможностей. В частности, ПК используется, когда вызывающий абонент может находиться в режиме блокировки запроса на обслуживание (SRB).

PDP-11 миникомпьютер использовали EMT и IOT инструкции, которые, подобно IBM System / 360 SVC и x86 INT , поставить код в инструкции; они генерируют прерывания по определенным адресам, передавая управление операционной системе. VAX 32-битный преемник PDP-11 серии использовал ЧКИ , ЧМЭ и CHMS инструкцию, чтобы системные вызовы в привилегированную коду на различных уровнях; код является аргументом инструкции.

Категории системных вызовов [ править ]

Системные вызовы можно условно разделить на шесть основных категорий: [12]

  1. Контроль над процессом
    • создать процесс (например, forkв Unix-подобных системах или NtCreateProcessв Windows NT Native API )
    • прекратить процесс
    • загрузить , выполнить
    • получить / установить атрибуты процесса
    • ждать в течение времени, ожидание события, сигнал события
    • выделить и освободить память
  2. Управление файлами
    • создать файл, удалить файл
    • открыто закрыто
    • читать, писать, менять положение
    • получить / установить атрибуты файла
  3. Управление устройством
    • устройство запроса, устройство выпуска
    • читать, писать, менять положение
    • получить / установить атрибуты устройства
    • логически присоединять или отсоединять устройства
  4. Информационное обслуживание
    • получить / установить общую информацию о системе (включая время, дату, имя компьютера, предприятие и т. д.)
    • получить / установить метаданные процесса, файла или устройства (включая автора, средство открытия, время и дату создания и т. д.)
  5. Коммуникация
    • создать, удалить коммуникационное соединение
    • отправлять, получать сообщения
    • информация о статусе передачи
    • подключать или отключать удаленные устройства
  6. Защита
    • получить / установить права доступа к файлам

Режим процессора и переключение контекста [ править ]

Системные вызовы в большинстве Unix-подобных систем обрабатываются в режиме ядра , что достигается изменением режима выполнения процессора на более привилегированный, но переключение контекста процесса не требуется - хотя переключение контекста привилегий действительно происходит. Аппаратное обеспечение видит мир с точки зрения режима выполнения в соответствии с регистром состояния процессора , а процессы - это абстракция, предоставляемая операционной системой. Системный вызов обычно не требует переключения контекста на другой процесс; вместо этого он обрабатывается в контексте того, какой процесс его вызвал. [13] [14]

В многопоточном процессе системные вызовы могут выполняться из нескольких потоков . Обработка таких вызовов зависит от конструкции конкретного ядра операционной системы и среды выполнения приложения. В следующем списке показаны типичные модели, за которыми следуют операционные системы: [15] [16]

  • Модель « многие к одному» : все системные вызовы из любого пользовательского потока в процессе обрабатываются одним потоком уровня ядра. У этой модели есть серьезный недостаток - любой системный вызов блокировки (например, ожидание ввода от пользователя) может заморозить все другие потоки. Кроме того, поскольку только один поток может получить доступ к ядру одновременно, эта модель не может использовать несколько ядер процессора.
  • Модель « один к одному» : каждый пользовательский поток присоединяется к отдельному потоку уровня ядра во время системного вызова. Эта модель решает указанную выше проблему блокировки системных вызовов. Он присутствует во всех основных дистрибутивах Linux , macOS , iOS , последних версиях Windows и Solaris .
  • Модель « многие ко многим» : в этой модели пул пользовательских потоков сопоставляется с пулом потоков ядра. Все системные вызовы из пула пользовательских потоков обрабатываются потоками в соответствующем пуле потоков ядра .
  • Гибридная модель: эта модель реализует как модель «многие ко многим», так и модель «один к одному» в зависимости от выбора, сделанного ядром. Это можно найти в старых версиях IRIX , HP-UX и Solaris .

См. Также [ править ]

  • API ядра Linux
  • VDSO

Заметки [ править ]

  1. ^ Компонент CP CP-67 и VM использует инструкцию диагностики (DIAG) как ВЫЗОВ гипервизора (HVC) от виртуальной машины к CP.

Ссылки [ править ]

  1. ^ IBM (март 1967). «Написание подпрограмм SVC». Руководство программиста операционной системы IBM System / 360 (PDF) . Третье издание. С. 32–36. C28-6550-2.
  2. ^ "syscalls (2) - страница руководства Linux" .
  3. ^ OpenBSD (14 сентября 2013 г.). «Имена системных вызовов (kern / syscalls.c)» . Перекрестная ссылка BSD .
  4. ^ NetBSD (17 октября 2013 г.). «Имена системных вызовов (kern / syscalls.c)» . Перекрестная ссылка BSD .
  5. ^ "FreeBSD syscalls.c, список имен и идентификаторов системных вызовов" .
  6. ^ Автор: Матеуш "j00ru" Юрчик (5 ноября 2017 г.). "Таблица системных вызовов Windows WIN32K.SYS (NT / 2000 / XP / 2003 / Vista / 2008/7/8/10)" .
  7. ^ «План 9 sys.h, список имен и идентификаторов системных вызовов» .
  8. ^ "SYSENTER (OSDev wiki)" .
  9. Анонимный (19 декабря 2002 г.). «Linux 2.5 получает vsyscalls, поддержку sysenter» . KernelTrap . Проверено 1 января 2008 года .
  10. ^ Мана Garg (2006). «Механизм системного вызова на основе Sysenter в Linux 2.6» .
  11. ^ «Освобождение: Справочник по набору команд x86» . renejeschke.de . Проверено 4 июля 2015 года .
  12. ^ Silberschatz, Abraham (2018). Понятия операционной системы . Питер Б. Гэлвин; Грег Гэйн (10-е изд.). Хобокен, Нью-Джерси: Уайли. п. 67. ISBN 9781119320913. OCLC  1004849022 .
  13. Перейти ↑ Bach, Maurice J. (1986), The Design of the UNIX Operating System , Prentice Hall, pp. 15-16.
  14. ^ Эллиот, Джон (2011). «Обсуждение реализации системных вызовов в ProgClub, включая цитату из Баха 1986 года» .
  15. ^ «Нитки» .
  16. ^ «Модели потоков» (PDF) .

Внешние ссылки [ править ]

  • Справочник / список системных вызовов Linux до версии 4.20
  • Справочник по системным вызовам Linux Обновлен справочник по системным вызовам для ядра Linux 2.6.35.4, включая ссылки на регистры и структуры данных. Также для ядра Linux 4.14 64 бит и 32 бит .
  • Список современных Unix-подобных системных вызовов
  • Интерактивная карта ядра Linux с основными функциями и структурами API, версия PDF
  • Системные вызовы Linux  - системные вызовы для ядра Linux 2.2 с соглашениями о вызовах IA-32
  • Как системные вызовы работают в Linux / i86 (1996, на основе ядра 1993 0.99.2)
  • Механизм системного вызова на основе Sysenter в Linux 2.6 (2006)
  • Команда ядра с использованием системных вызовов Linux , IBM developerWorks
  • Чоудхари, Амит; HOWTO по реализации системного вызова в Linux 2.6
  • Йоррит Н. Гердер, Герберт Бос, Бен Гра, Филип Хомбург и Эндрю С. Таненбаум, Модульное системное программирование на Minix 3 , логин: 31, № 2 (апрель 2006 г.); 19-28, по состоянию на 5 марта 2018 г.
  • Простая открытая оболочка Unix на языке C  - примеры системных вызовов в Unix
  • Внутри Native API  - Windows NT Native API , в том числе системных вызовов
  • Гулбрандсен, Джон; Оптимизация системных вызовов с помощью инструкции SYSENTER , CodeGuru.com, 8 октября 2004 г.

Эта статья основана на материалах, взятых из Free On-line Dictionary of Computing до 1 ноября 2008 г. и включенных в соответствии с условиями «перелицензирования» GFDL версии 1.3 или новее.