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