Интерфейсы ядра Linux

Обзор и сравнение API и ABI ядра Linux.
Linux API, Linux ABI и встроенные в ядро ​​API и ABI

Ядро Linux предоставляет несколько интерфейсов для пользовательского пространства и кода режима ядра, которые используются для различных целей и имеют различные свойства по замыслу. В ядре Linux есть два типа интерфейса прикладного программирования (API):

  1. API «ядро–пространство пользователя»; и
  2. «внутренний API ядра».

API-интерфейс Linux

Linux API состоит из интерфейса системных вызовов ядра Linux, библиотеки GNU C (от GNU ), libcgroup , [1] libdrm , libalsa и libevdev [2] (от freedesktop.org ).
Linux API против POSIX API

Linux API включает в себя API пространства ядра и пользователя, который позволяет коду в пространстве пользователя получать доступ к системным ресурсам и службам ядра Linux. [3] Он состоит из интерфейса системных вызовов ядра Linux и подпрограмм в стандартной библиотеке C. Основное внимание при разработке Linux API было уделено предоставлению полезных функций спецификаций, определенных в POSIX , способом, который является разумно совместимым, надежным и производительным, а также предоставлению дополнительных полезных функций, не определенных в POSIX, так же как API пространства ядра и пользователя других систем, реализующих API POSIX, также предоставляют дополнительные функции, не определенные в POSIX.

Linux API, по собственному выбору, сохранял стабильность на протяжении десятилетий благодаря политике невнесения критических изменений; эта стабильность гарантирует переносимость исходного кода . [4] В то же время разработчики ядра Linux исторически были консервативны и скрупулезны в отношении внедрения новых системных вызовов. [ требуется ссылка ]

Для POSIX API написано много свободного и открытого программного обеспечения . Поскольку в ядро ​​Linux вкладывается гораздо больше разработок по сравнению с другими POSIX-совместимыми комбинациями ядра и стандартной библиотеки C, [ требуется ссылка ] ядро ​​Linux и его API были дополнены дополнительными функциями. Программирование для полного Linux API, а не только для POSIX API, может обеспечить преимущества в случаях, когда эти дополнительные функции полезны. Известными текущими примерами являются udev , systemd и Weston . [5] Такие люди, как Леннарт Пёттеринг, открыто выступают за предпочтение Linux API перед POSIX API, где это дает преимущества. [6]

На FOSDEM 2016 Майкл Керриск объяснил некоторые из предполагаемых проблем с пользовательским API ядра Linux, описав, что оно содержит множество ошибок проектирования, будучи нерасширяемым, неподдерживаемым, чрезмерно сложным, имеющим ограниченное назначение, нарушающим стандарты и непоследовательным. Большинство этих ошибок не могут быть исправлены, поскольку это нарушит ABI, который ядро ​​представляет пользовательскому пространству. [7]

Интерфейс системных вызовов ядра Linux

Интерфейс системных вызовов ядра — это набор всех реализованных и доступных системных вызовов в ядре. В ядре Linux различные подсистемы, такие как Direct Rendering Manager (DRM), определяют свои собственные системные вызовы, все из которых являются частью интерфейса системных вызовов.

Различные проблемы с организацией системных вызовов ядра Linux обсуждаются публично. На проблемы указывали Энди Лютомирски, Майкл Керриск и другие. [8] [9] [10] [11]

Стандартная библиотека языка Си

Библиотека GNU C представляет собой оболочку вокруг интерфейса системных вызовов ядра Linux.

Стандартная библиотека C для Linux включает оболочки вокруг системных вызовов ядра Linux; сочетание интерфейса системных вызовов ядра Linux и стандартной библиотеки C — это то, что создает API Linux. Некоторые популярные реализации стандартной библиотеки C:

Дополнения к POSIX

Как и в других Unix-подобных системах, существуют дополнительные возможности ядра Linux, которые не являются частью POSIX:

  • Подсистема cgroups , системные названия ее вводят и libcgroup [1]
  • Системные вызовы Direct Rendering Manager , особенно ioctl-вызовы драйвера для отправки команд, не являются частью спецификаций POSIX.
  • Advanced Linux Sound Architecture может устанавливать системные вызовы, которые не являются частью спецификаций POSIX
  • Системные вызовы futex(быстрый мьютекс пользовательского пространства), epoll, splice, dnotify, fanotifyи inotifyдо сих пор были доступны только ядру Linux.
  • Системный вызов getrandomбыл представлен в версии 3.17 основной ветки ядра Linux [12]
  • memfdбыл предложен разработчиками kdbus [ 13]
    • memfd_createбыл объединен с основной веткой ядра Linux в версии ядра 3.17
  • readaheadинициирует «упреждающее чтение» файла в кэш страниц

DRM имел первостепенное значение для разработки и внедрения хорошо определенных и производительных бесплатных и открытых драйверов графических устройств, без которых ускорение рендеринга было бы вообще недоступно, только 2D-драйверы были бы доступны на сервере X.Org . DRM был разработан для Linux, и с тех пор был перенесен и на другие операционные системы. [14]

Дополнительные библиотеки

Linux-интерфейс

Linux API и Linux ABI

Термин Linux ABI относится к ABI пространства ядра–пользователя. Двоичный интерфейс приложения относится к скомпилированным двоичным файлам в машинном коде . Таким образом, любой такой ABI привязан к набору инструкций . Определение полезного ABI и поддержание его стабильности — это не столько обязанность разработчиков ядра Linux или разработчиков библиотеки GNU C, сколько задача дистрибутивов Linux и независимых поставщиков программного обеспечения (ISV), которые хотят продавать и предоставлять поддержку своего фирменного программного обеспечения в виде двоичных файлов только для такого одного Linux ABI, в отличие от поддержки нескольких Linux ABI.

ABI должен быть определен для каждого набора инструкций, например, x86 , x86-64 , MIPS , ARMv7-A (32-бит), ARMv8-A (64-бит) и т. д. с указанием порядка байтов , если поддерживаются оба.

Он должен иметь возможность компилировать программное обеспечение с помощью различных компиляторов в соответствии с определениями, указанными в ABI, и достигать полной двоичной совместимости. Компиляторы, которые являются бесплатными и имеют открытый исходный код , например, GNU Compiler Collection , LLVM / Clang .

API-интерфейсы ядра

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

Ядро Linux является монолитным ядром, поэтому драйверы устройств являются компонентами ядра. Чтобы облегчить бремя компаний, поддерживающих свои (фирменные) драйверы устройств вне основного дерева ядра, неоднократно запрашивались стабильные API для драйверов устройств. Разработчики ядра Linux неоднократно отказывались гарантировать стабильные внутриядерные API для драйверов устройств. Гарантирование этого остановило бы разработку ядра Linux в прошлом и все еще будет останавливать в будущем, и из-за природы свободного и открытого программного обеспечения, не является необходимым. Следовательно, по собственному выбору ядро ​​Linux не имеет стабильного внутриядерного API. [15]

Встроенные в ядро ​​ABI

Поскольку стабильных внутриядерных API нет, не может быть и стабильных внутриядерных ABI. [16]

API абстракции

OpenGL — это действительно абстрактный API, позволяющий использовать различные графические процессоры разных производителей без необходимости программирования для каждого из них.
Но реализация спецификации OpenGL выполняется на CPU в контексте работающей операционной системы. Одной из целей разработки Vulkan было заставить «графический драйвер», т. е. реализацию графического API, делать меньше.

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

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

  • Интерфейс программирования Linux Майкла Керриска
  • Семафор (программирование)
  • системный вызов  – это функция, позволяющая программам запрашивать службы у ядра
    • eventfd()
    • netlink  – семейство сокетов, используемое для IPC между процессами ядра и пользовательского пространства, разработанное как преемник ioctl ; Netlink был добавлен Аланом Коксом во время разработки ядра Linux 1.3 в качестве интерфейса символьного драйвера для предоставления множественных двунаправленных каналов связи ядра и пользовательского пространства. Затем Алексей Кузнецов расширил его во время разработки ядра Linux 2.1, чтобы предоставить гибкий и расширяемый интерфейс обмена сообщениями для новой расширенной инфраструктуры маршрутизации. С тех пор сокеты Netlink стали одним из основных интерфейсов, которые подсистемы ядра предоставляют приложениям пользовательского пространства в Linux. Современные драйверы WNIC используют его для связи с пользовательским пространством.
  • Windows API  – статья о различных API, доступных в операционных системах Microsoft Windows.
  • Wine  — уровень совместимости между Linux и программами, написанными для Microsoft Windows
  • libhybris – слой совместимости между Linux и программами, написанными для Android

Ссылки

  1. ^ ab "ControlGroupInterface". freedesktop.org .
  2. ^ "libevdev". freedesktop.org .
  3. ^ Алессандро Рубини (2006-11-02). "Системные вызовы ядра". linux.it . Получено 2014-11-11 .
  4. ^ Линус Торвальдс (2012-12-23). ​​"Re: [Regression w/ patch] Media commit causes user space to misbahave (было: Re: Linux 3.8-rc1)". Список рассылки ядра Linux . Получено 2014-08-26 . Если изменение приводит к поломке пользовательских программ, это ошибка в ядре. Мы НИКОГДА не виним пользовательские программы.
  5. ^ «Выбор между портативностью и инновациями». LWN.net . 2011-03-02.
  6. ^ "Интервью: Леннарт Пёттеринг - Леннарт Пёттеринг выступит с докладом о "Systemd: beyond init" на FOSDEM 2011". fosdem.org. 2011 . Получено 16.06.2014 . На самом деле, как я вижу, Linux API берет на себя роль POSIX API , а Linux является центром всей разработки свободного ПО. В связи с этим я могу только порекомендовать разработчикам попытаться заниматься хакингом, имея в виду только Linux, и ощутить свободу и возможности, которые он вам предлагает. Так что приобретите себе копию Linux Programming Interface , проигнорируйте все, что там говорится о совместимости с POSIX, и взломайте свое замечательное Linux-ПО. Это довольно приятно!
  7. ^ Майкл Керриск (2016-01-31). "Как разработать API ядра Linux" . Получено 2016-02-04 .
  8. ^ «Организация системных вызовов».
  9. ^ "Создание универсального списка системных вызовов?". LKML . 2014-02-27.
  10. ^ "Флаги как шаблон проектирования API системных вызовов". LWN.net . 2014-02-12.
  11. ^ "О vsyscalls и vDSO". LWN.net . 2011-06-08.
  12. ^ "[PATCH, RFC] random: введение системного вызова getrandom(2)". LKML . 2014-07-17.
  13. ^ "memfd.c". GitHub . Архивировано из оригинала 2014-04-22.
  14. ^ "NetBSD 7.0 наконец-то получит драйверы DRM/KMS". Phoronix . 2014-03-19.
  15. ^ «Интерфейс драйвера ядра Linux».
  16. ^ "Анализ изменений ABI в ядре Linux". Лаборатория ABI Андрея Пономаренко. 2016-03-15.
  • Linux Kernel API 5.0, API управления памятью 5.0 (новый формат sphinx )
  • API ядра Linux 2.6.20 и 4.12 (в устаревшем формате htmldocs)
  • Обзор изменений API/ABI для Linux
  • Книга «Программный интерфейс Linux», Linux и изменения API glibc с момента выхода книги «Программный интерфейс Linux» в 2010 году
  • Интерактивная карта ядра Linux с основными функциями и структурами API, версия PDF
  • Драйверы устройств Linux Джонатана Корбета, Грега Кроа-Хартмана и Алессандро Рубини, 3-е издание
  • Объяснение связанного списка ядра Linux Архивировано 25.09.2009 на Wayback Machine
Взято с "https://en.wikipedia.org/w/index.php?title=Интерфейсы_ядра_Linux&oldid=1250593013"