Системный вызов

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 16:48, 17 июня 2017.

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

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

Привилегии

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

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

Промежуточная библиотека

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

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

Операционные системы IBM, происходящие от OS / 360 и DOS / 360, включая z / OS и z / VSE, реализуют системные вызовы через библиотеку макросов языка ассемблера. Это связано с их происхождение, поскольку в то время программирование на языке ассемблера было более распространено, чем использование языков высокого уровня. Таким образом, системные вызовы IBM не могут напрямую исполняться языковыми программами высокого уровня, но требуют подпрограмму вызываемую ассемблером.

Примеры и инструменты

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

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

Типичные реализации

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

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

Для архитектуры IA-64 используется инструкция EPC (ввод привилегированного кода). Первые восемь аргументов системного вызова передаются в регистрах, а остальные передаются в стек. В семействе мэйнфреймов IBM System / 360 команда Supervisor Call реализует системный вызов устаревших объектов; Инструкция Program Call (PC) используется для новых объектов. В частности, ПК используется, когда вызывающий абонент может находиться в режиме SRB.

Категории системных вызовов

Управление процессами
  • load
  • execute
  • end (exit), abort
  • создание процесса (fork в UNIX-подобных, NtCreateProcess в Windows NT Native API)
  • завершение процесса
  • get/set process attributes
  • wait время, события, signal события
  • allocate, free memory
Работа с файлами
  • create file, delete file
  • open, close
  • read, write, reposition
  • get/set file attributes
Управление устройствами
  • request device, release device
  • read, write, reposition
  • get/set device attributes
  • logically attach or detach devices
Работа с информацией
  • get/set time or date
  • get/set system data
  • get/set process, file, or device attributes
Связь, коммуникация
  • create, delete communication connection
  • send, receive messages
  • transfer status information
  • attach or detach remote devices

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

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

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

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

Источники

  1. IBM (March 1967). "Writing SVC Routines". Третье издание. стр. 32–36. (дата обращения: 08.06.2017).
  2. Linux manual page. Дата обновления: 05.03.2017. URL: http://man7.org/linux/man-pages/man2/syscalls.2.html (дата обращения: 09.06.2017).
  3. Manu Garg (2006). "Sysenter Based System Call Mechanism in Linux 2.6" URL: http://articles.manugarg.com/systemcallinlinux2_6.html (дата обращения: 09.06.2017).
  4. Bach, Maurice J. (1986), The Design of the UNIX Operating System, Prentice Hall, стр. 15-16. (дата обращения: 08.06.2017).

Ссылки