stringtranslate.com

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

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

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

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

Для встраиваемых систем системные вызовы обычно не изменяют режим привилегий ЦП.

Привилегии

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

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

Библиотека как посредник

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

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

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

IBM OS/360 , DOS/360 и TSS/360 реализуют большинство системных вызовов через библиотеку макросов языка ассемблера , [b] хотя есть несколько служб с вызовом связи. Это отражает их происхождение в то время, когда программирование на языке ассемблера было более распространено, чем использование языков высокого уровня . Поэтому системные вызовы IBM не были напрямую выполнены программами на языке высокого уровня, но требовали вызываемой подпрограммы-оболочки языка ассемблера. С тех пор IBM добавила много служб, которые могут быть вызваны из языков высокого уровня, например, z/OS и z/VSE . В более позднем выпуске MVS/SP и во всех более поздних версиях MVS некоторые макросы системных вызовов генерируют Program Call (PC).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Смотрите также

Примечания

  1. ^ В UNIX-подобных операционных системах системные вызовы используются только для ядра
  2. ^ Во многих, но не во всех случаях IBM документировала, например, номер SVC, регистры параметров.
  3. ^ Компоненты CP CP-67 и VM используют инструкцию Diagnose (DIAG) как вызов гипервизора (HVC) от виртуальной машины к CP.

Ссылки

  1. ^ IBM (март 1967 г.). «Написание процедур SVC». IBM System/360 Operating System System Programmer's Guide (PDF) . Третье издание. С. 32–36. C28-6550-2.
  2. ^ "syscalls(2) - страница руководства Linux".
  3. ^ OpenBSD (14 сентября 2013 г.). "Имена системных вызовов (kern/syscalls.c)". BSD Cross Reference .
  4. ^ NetBSD (17 октября 2013 г.). "Имена системных вызовов (kern/syscalls.c)". BSD Cross Reference .
  5. ^ "FreeBSD syscalls.c, список имен и идентификаторов системных вызовов".
  6. Матеуш "j00ru" Юрчик (5 ноября 2017 г.). «Таблица системных вызовов Windows WIN32K.SYS (NT/2000/XP/2003/Vista/2008/7/8/10)».{{cite web}}: CS1 maint: числовые имена: список авторов ( ссылка )
  7. ^ "sys.h". Plan 9 от Bell Labs . Архивировано из оригинала 8 сентября 2023 г.,список имен и идентификаторов системных вызовов.
  8. ^ "SYSENTER". OSDev wiki . Архивировано из оригинала 8 ноября 2023 г.
  9. Аноним (19 декабря 2002 г.). "Linux 2.5 получает поддержку vsyscalls и sysenter". KernelTrap . Получено 1 января 2008 г.
  10. ^ Ману Гарг (2006). «Механизм системных вызовов на основе Sysenter в Linux 2.6».
  11. ^ "Liberation: x86 Instruction Set Reference". renejeschke.de . Получено 4 июля 2015 г. .
  12. ^ Зильбершатц, Абрахам (2018). Концепции операционных систем . Питер Б. Гэлвин; Грег Ганье (10-е изд.). Хобокен, Нью-Джерси: Wiley. стр. 67. ISBN 9781119320913. OCLC  1004849022.
  13. ^ Бах, Морис Дж. (1986), Проектирование операционной системы UNIX , Prentice Hall, стр. 15–16.
  14. ^ Эллиот, Джон (2011). «Обсуждение реализации системных вызовов на ProgClub, включая цитату из Баха 1986».
  15. ^ "Нити".
  16. ^ «Модели потоков» (PDF) .

Внешние ссылки