Системный вызов
В вычислительной технике системный вызов (обычно сокращенно syscall ) — это программный способ, которым компьютерная программа запрашивает услугу у операционной системы. [ а ] на котором оно выполняется. Сюда могут входить службы, связанные с оборудованием (например, доступ к жесткому диску или доступ к камере устройства), создание и выполнение новых процессов , а также связь со встроенными службами ядра, такими как планирование процессов . Системные вызовы обеспечивают необходимый интерфейс между процессом и операционной системой.
В большинстве систем системные вызовы могут выполняться только из процессов пользовательского пространства , тогда как в некоторых системах, OS/360 и последующих версиях , привилегированный системный код также выполняет системные вызовы. например [ 1 ]
Для встроенных систем системные вызовы обычно не меняют привилегированный режим ЦП.
Привилегии
[ редактировать ]Архитектура большинства современных процессоров , за исключением некоторых встраиваемых систем, предполагает модель безопасности . Например, модель колец определяет несколько уровней привилегий, с которыми может выполняться программное обеспечение: программа обычно ограничена своим собственным адресным пространством , так что она не может получить доступ или изменить другие запущенные программы или саму операционную систему, и обычно ей не разрешается напрямую манипулировать аппаратные устройства (например, буфер кадров или сетевые устройства).
Однако многим приложениям необходим доступ к этим компонентам, поэтому операционная система предоставляет системные вызовы для обеспечения четко определенных и безопасных реализаций таких операций. Операционная система работает на самом высоком уровне привилегий и позволяет приложениям запрашивать службы посредством системных вызовов, которые часто инициируются посредством прерываний . Прерывание автоматически переводит процессор на некоторый повышенный уровень привилегий, а затем передает управление ядру, которое определяет, следует ли предоставить вызывающей программе запрошенную услугу. Если услуга предоставлена, ядро выполняет определенный набор инструкций, над которыми вызывающая программа не имеет прямого контроля, возвращает уровень привилегий вызывающей программе, а затем возвращает управление вызывающей программе.
Библиотека как посредник
[ редактировать ]Как правило, системы предоставляют библиотеку или API , который находится между обычными программами и операционной системой. В Unix-подобных системах этот API обычно является частью реализации библиотеки C (libc), такой как glibc , которая предоставляет функции-оболочки для системных вызовов, часто называемых так же, как системные вызовы, которые они вызывают. В Windows NT этот API является частью Native API . ntdll.dll библиотека ; это недокументированный API, используемый реализациями обычного API Windows и напрямую используемый некоторыми системными программами в Windows. Функции-оболочки библиотеки предоставляют обычное соглашение о вызове функций ( вызов подпрограммы на уровне сборки ) для использования системного вызова, а также делают системный вызов более модульным . Здесь основная функция оболочки — поместить все аргументы, которые будут переданы системному вызову, в соответствующие регистры процессора (а, возможно, и в стек вызовов ), а также установить уникальный номер системного вызова для вызова ядра. . Таким образом, библиотека, существующая между ОС и приложением, повышает переносимость .
Вызов библиотечной функции сам по себе не вызывает переключения в режим ядра и обычно представляет собой обычный вызов подпрограммы (с использованием, например, ассемблерной инструкции «CALL» в некоторых архитектурах набора инструкций (ISA)). Фактический системный вызов передает управление ядру (и в большей степени зависит от реализации и платформы, чем абстрагирующий его библиотечный вызов). Например, в Unix-подобных системах fork
и execve
— это функции библиотеки C, которые, в свою очередь, выполняют инструкции, вызывающие fork
и exec
системные вызовы. Выполнение системного вызова непосредственно в коде приложения более сложно и может потребовать использования встроенного ассемблерного кода (в C и C++ ), а также знания низкоуровневого двоичного интерфейса для операции системного вызова, что может быть предметом изменяться со временем и, таким образом, не быть частью двоичного интерфейса приложения ; библиотечные функции предназначены для абстрагирования этого.
В системах на основе экзоядра библиотека особенно важна как посредник. В экзоядрах библиотеки защищают пользовательские приложения от API ядра очень низкого уровня и обеспечивают абстракции и ресурсами управление .
IBM OS/360 , DOS/360 и TSS/360 реализуют большинство системных вызовов через библиотеку макросов языка ассемблера . [ б ] хотя есть несколько сервисов с привязкой звонков. Это отражает их происхождение в то время, когда программирование на языке ассемблера было более распространенным, чем использование языка высокого уровня . Таким образом, системные вызовы IBM не могли напрямую выполняться программами на языке высокого уровня, но требовали вызываемой подпрограммы-оболочки языка ассемблера. С тех пор IBM добавила множество сервисов, которые можно вызывать из языков высокого уровня, например, в z/OS и z/VSE . В более позднем выпуске MVS/SP и во всех более поздних версиях MVS некоторые макросы системных вызовов генерируют вызов программы (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 ] в то время как в Плане 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 ]
Более старый механизм — это шлюз вызова ; первоначально использовался в Multics и позже, например, см. шлюз вызова на Intel x86 . Это позволяет программе напрямую вызывать функцию ядра, используя безопасный механизм передачи управления, который операционная система устанавливает заранее. Этот подход был непопулярен на x86, предположительно из-за требования дальнего вызова (вызов процедуры, расположенной в сегменте, отличном от текущего сегмента кода). [ 11 ] ), который использует сегментацию памяти x86 и, как следствие, отсутствие переносимости , а также существование более быстрых инструкций, упомянутых выше.
Для IA-64 архитектуры EPC
Используется команда (Введите привилегированный код). Первые восемь аргументов системного вызова передаются в регистрах, а остальные — в стеке.
В семействе мэйнфреймов IBM System/360 и его преемниках инструкция вызова супервизора ( SVC ), с номером в инструкции, а не в регистре, реализует системный вызов для устаревших средств в большинстве случаев. [ с ] Собственные операционные системы IBM и все системные вызовы в Linux. В более поздних версиях MVS IBM использует инструкцию Program Call (PC) для многих новых средств. В частности, ПК используется, когда вызывающий абонент может находиться в режиме блокировки запроса на обслуживание (SRB).
PDP -11 Миникомпьютер использовал ЕМТ , ЛОВУШКА и Инструкции IOT , которые, как и IBM System/360 SVC и x86 INT , поместите код в инструкцию; они генерируют прерывания по определенным адресам, передавая управление операционной системе. VAX использовал 32 - битный преемник серии PDP-11 ЧМК , ЧМЕ и Инструкции CHMS для выполнения системных вызовов привилегированного кода на различных уровнях; код является аргументом инструкции.
Категории системных вызовов
[ редактировать ]Системные вызовы можно условно сгруппировать в шесть основных категорий: [ 12 ]
- Управление процессом
- создать процесс (например,
fork
в Unix-подобных системах илиNtCreateProcess
в Windows NT собственном API ) - завершить процесс
- загрузить , выполнить
- получить/установить атрибуты процесса
- время ожидания , событие ожидания, сигнала событие
- выделить и освободить память
- создать процесс (например,
- Управление файлами
- создать файл, удалить файл
- открыть, закрыть
- читать, писать, перемещать
- получить/установить атрибуты файла
- Управление устройствами
- запросить устройство, освободить устройство
- читать, писать, перемещать
- получить/установить атрибуты устройства
- логически подключать или отключать устройства
- Информационное обслуживание
- получить/установить общую информацию о системе (включая время, дату, имя компьютера, предприятие и т. д.)
- получить/установить метаданные процесса, файла или устройства (включая автора, начало, время и дату создания и т. д.)
- Коммуникация
- создать, удалить соединение связи
- отправлять, получать сообщения
- информация о статусе передачи
- подключать или отключать удаленные устройства
- Защита
- получить/установить права доступа к файлу
Режим процессора и переключение контекста
[ редактировать ]Системные вызовы в большинстве Unix-подобных систем обрабатываются в режиме ядра , что достигается путем изменения режима выполнения процессора на более привилегированный, но процесса переключение контекста не требуется – хотя переключение контекста привилегий все же происходит. Аппаратное обеспечение видит мир с точки зрения режима выполнения в соответствии с регистром состояния процессора , а процессы — это абстракция, предоставляемая операционной системой. Системный вызов обычно не требует переключения контекста на другой процесс; вместо этого он обрабатывается в контексте того процесса, который его вызвал. [ 13 ] [ 14 ]
В многопоточном процессе системные вызовы могут выполняться из нескольких потоков . Обработка таких вызовов зависит от конструкции конкретного ядра операционной системы и среды выполнения приложения. В следующем списке показаны типичные модели, за которыми следуют операционные системы: [ 15 ] [ 16 ]
- Модель «многие к одному» . Все системные вызовы из любого пользовательского потока в процессе обрабатываются одним потоком уровня ядра. У этой модели есть серьезный недостаток — любой блокирующий системный вызов (например, ожидание ввода от пользователя) может заморозить все остальные потоки. Кроме того, поскольку одновременно к ядру может обращаться только один поток, эта модель не может использовать несколько ядер процессоров.
- Модель «один к одному» : каждый пользовательский поток присоединяется к отдельному потоку уровня ядра во время системного вызова. Эта модель решает описанную выше проблему блокировки системных вызовов. Он встречается во всех основных дистрибутивах Linux , macOS , iOS , последних версиях Windows и Solaris .
- Модель «многие ко многим» . В этой модели пул пользовательских потоков сопоставляется с пулом потоков ядра. Все системные вызовы из пула пользовательских потоков обрабатываются потоками из соответствующего пула потоков ядра .
- Гибридная модель. Эта модель реализует модели «многие ко многим» и «один к одному» в зависимости от выбора, сделанного ядром. Это встречается в старых версиях IRIX , HP-UX и Solaris .
См. также
[ редактировать ]Примечания
[ редактировать ]- ^ В UNIX-подобных операционных системах системные вызовы используются только для ядра.
- ^ Во многих, но не во всех случаях, IBM документировала, например, номер SVC, регистрируемый параметр.
- ^ Компоненты 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)» .
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка ) - ^ "sys.h" . План 9 от Bell Labs . Архивировано из оригинала 8 сентября 2023 года. Список имен и идентификаторов системных вызовов.
- ^ «СИСЭНТЕР» . OSDev вики . Архивировано из оригинала 8 ноября 2023 года.
- ^ Анонимно (19 декабря 2002 г.). «Linux 2.5 получает vsyscalls и поддержку sysenter» . Ядерная ловушка . Проверено 1 января 2008 г.
- ^ Ману Гарг (2006). «Механизм системных вызовов на основе Sysenter в Linux 2.6» .
- ^ «Освобождение: Справочник по набору инструкций x86» . renejeschke.de . Проверено 4 июля 2015 г.
- ^ Зильбершац, Авраам (2018). Концепции операционной системы . Питер Б. Гэлвин; Грег Ганье (10-е изд.). Хобокен, Нью-Джерси: Уайли. п. 67. ИСБН 9781119320913 . OCLC 1004849022 .
- ^ Бах, Морис Дж. (1986), Проект операционной системы UNIX , Prentice Hall, стр. 15–16.
- ^ Эллиот, Джон (2011). «Обсуждение реализации системных вызовов в ProgClub, включая цитату Баха 1986» .
- ^ «Нити» .
- ^ «Модели резьбы» (PDF) .
Внешние ссылки
[ редактировать ]- Список современных Unix-подобных системных вызовов
- Интерактивная карта ядра Linux с основными функциями и структурами API, PDF версия
- Системные вызовы Linux — системные вызовы для ядра Linux 2.2 с IA-32. соглашениями о вызовах
- Как работают системные вызовы в Linux/i86 (1996 г., на основе ядра 0.99.2 1993 г.)
- Механизм системных вызовов на основе Sysenter в Linux 2.6 (2006 г.)
- Команда ядра с использованием системных вызовов Linux , IBM DeveloperWorks
- Чоудхари, Амит; HOWTO по реализации системного вызова в Linux 2.6
- Йоррит Н. Гердер, Герберт Бос, Бен Грас, Филип Хомбург и Эндрю С. Таненбаум, Программирование модульных систем на Minix 3 , ;логин: 31, вып. 2 (апрель 2006 г.); 19–28, по состоянию на 5 марта 2018 г.
- Простая открытая оболочка Unix на языке C – примеры системных вызовов в Unix
- Внутри собственного API — Windows NT Native API , включая системные вызовы.
- Гулбрандсен, Джон; Оптимизация системных вызовов с помощью инструкции SYSENTER , CodeGuru.com, 8 октября 2004 г.