Эта статья написана как личное размышление, личное эссе или аргументативное эссе , в котором излагаются личные чувства редактора Википедии или излагается оригинальный аргумент по теме. ( Июль 2014 ) |
Ядро Linux предоставляет несколько интерфейсов для пользовательского пространства и кода режима ядра, которые используются для различных целей и имеют различные свойства по замыслу. В ядре Linux есть два типа интерфейса прикладного программирования (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 различные подсистемы, такие как Direct Rendering Manager (DRM), определяют свои собственные системные вызовы, все из которых являются частью интерфейса системных вызовов.
Различные проблемы с организацией системных вызовов ядра Linux обсуждаются публично. На проблемы указывали Энди Лютомирски, Майкл Керриск и другие. [8] [9] [10] [11]
Стандартная библиотека C для Linux включает оболочки вокруг системных вызовов ядра Linux; сочетание интерфейса системных вызовов ядра Linux и стандартной библиотеки C — это то, что создает API Linux. Некоторые популярные реализации стандартной библиотеки C:
Как и в других Unix-подобных системах, существуют дополнительные возможности ядра Linux, которые не являются частью POSIX:
futex
(быстрый мьютекс пользовательского пространства), epoll
, splice
, dnotify
, fanotify
и inotify
до сих пор были доступны только ядру Linux.getrandom
был представлен в версии 3.17 основной ветки ядра Linux [12]memfd
был предложен разработчиками kdbus [ 13]memfd_create
был объединен с основной веткой ядра Linux в версии ядра 3.17readahead
инициирует «упреждающее чтение» файла в кэш страницDRM имел первостепенное значение для разработки и внедрения хорошо определенных и производительных бесплатных и открытых драйверов графических устройств, без которых ускорение рендеринга было бы вообще недоступно, только 2D-драйверы были бы доступны на сервере X.Org . DRM был разработан для Linux, и с тех пор был перенесен и на другие операционные системы. [14]
Эта статья требует внимания эксперта по бесплатному и открытому программному обеспечению, программному обеспечению или вычислениям . Конкретная проблема заключается в следующем: этот раздел в основном игнорирует ABI ядра-пользователя (что очень реально и важно) и переходит к API пользовательского пространства-пользователя. ( Февраль 2018 ) |
Термин 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 ядра может быть изменен, когда такая необходимость указывается новыми исследованиями или идеями; все необходимые изменения и тестирование должны быть выполнены автором.
Ядро Linux является монолитным ядром, поэтому драйверы устройств являются компонентами ядра. Чтобы облегчить бремя компаний, поддерживающих свои (фирменные) драйверы устройств вне основного дерева ядра, неоднократно запрашивались стабильные API для драйверов устройств. Разработчики ядра Linux неоднократно отказывались гарантировать стабильные внутриядерные API для драйверов устройств. Гарантирование этого остановило бы разработку ядра Linux в прошлом и все еще будет останавливать в будущем, и из-за природы свободного и открытого программного обеспечения, не является необходимым. Следовательно, по собственному выбору ядро Linux не имеет стабильного внутриядерного API. [15]
Поскольку стабильных внутриядерных API нет, не может быть и стабильных внутриядерных ABI. [16]
Для многих вариантов использования Linux API считается слишком низкоуровневым, поэтому необходимо использовать API более высокой абстракции. API более высокого уровня должны быть реализованы поверх API более низкого уровня. Примеры:
Если изменение приводит к поломке пользовательских программ, это ошибка в ядре. Мы НИКОГДА не виним пользовательские программы.
На самом деле, как я вижу,
Linux API
берет на себя роль
POSIX API
, а Linux является центром всей разработки свободного ПО. В связи с этим я могу только порекомендовать разработчикам попытаться заниматься хакингом, имея в виду только Linux, и ощутить свободу и возможности, которые он вам предлагает. Так что приобретите себе копию
Linux Programming Interface
, проигнорируйте все, что там говорится о совместимости
с POSIX,
и взломайте свое замечательное Linux-ПО. Это довольно приятно!