Ядро Linux — это бесплатное ядро с открытым исходным кодом [12] : 4 , монолитное , модульное , многозадачное , Unix-подобное ядро операционной системы . Первоначально оно было написано в 1991 году Линусом Торвальдсом для его ПК на базе i386 , и вскоре оно было принято в качестве ядра для операционной системы GNU , которая была написана как бесплатная (свободная) замена Unix .
Linux предоставляется только под лицензией GNU General Public License версии 2 , но он содержит файлы под другими совместимыми лицензиями . [11] С конца 1990-х годов он был включен в состав большого количества дистрибутивов операционных систем , многие из которых обычно также называются Linux .
Linux развертывается на самых разных вычислительных системах, таких как встроенные устройства , мобильные устройства (включая его использование в операционной системе Android ), персональные компьютеры , серверы , мейнфреймы и суперкомпьютеры . [13] Его можно адаптировать для конкретных архитектур и нескольких сценариев использования с помощью семейства простых команд (то есть без необходимости ручного редактирования исходного кода перед компиляцией); [14] [15] [16] привилегированные пользователи также могут точно настраивать параметры ядра во время выполнения. [17] [18] [19] Большая часть кода ядра Linux написана с использованием расширений GNU GCC [12] : 18 [20] к стандартному языку программирования C и с использованием специфичных для архитектуры инструкций ( ISA ) в ограниченные части ядра. В результате получается высокооптимизированный исполняемый файл ( vmlinux ) с точки зрения использования пространства памяти и времени выполнения задач. [12] : 379–380.
Ежедневные обсуждения разработки происходят в списке рассылки ядра Linux (LKML). Изменения отслеживаются с помощью системы контроля версий git , автором которой изначально был Торвальдс как бесплатная программная замена BitKeeper .
В апреле 1991 года Линус Торвальдс , в то время 21-летний студент информатики Хельсинкского университета , Финляндия , начал работать над некоторыми простыми идеями операционной системы, вдохновленной UNIX, для персонального компьютера. [21] Он начал с переключателя задач на языке ассемблера Intel 80386 и драйвера терминала . [21] 25 августа 1991 года Торвальдс опубликовал следующее в группе новостей comp.os.minix в Usenet : [22]
Я делаю (бесплатную) операционную систему (просто хобби, не будет большой и профессиональной, как GNU) для клонов 386(486) AT . Это назревало с апреля и начинает готовиться. Я хотел бы получить любые отзывы о том, что людям нравится/не нравится в minix, поскольку моя ОС чем-то напоминает ее (среди прочего, такое же физическое расположение файловой системы (по практическим соображениям).
В настоящее время я портировал bash (1.08) и gcc (1.40), и, похоже, все работает. Это означает, что я получу что-то практичное в течение нескольких месяцев [...]
Да, он не содержит никакого кода minix и имеет многопоточную файловую систему. Он НЕ является переносимым [ sic ] (использует переключение задач 386 и т. д.) и, вероятно, никогда не будет поддерживать ничего, кроме AT-жестких дисков, поскольку это все, что у меня есть :-(.
17 сентября 1991 года Торвальдс подготовил версию Linux 0.01 и разместил ее на «ftp.funet.fi» — FTP-сервере Финской университетской и исследовательской сети ( FUNET ). Он даже не был исполняемым, поскольку его код все еще нуждался в Minix для компиляции и тестирования. [23]
5 октября 1991 года Торвальдс анонсировал первую «официальную» версию Linux — 0.02. [24] На этом этапе Linux мог запускать Bash, GCC и некоторые другие утилиты GNU: [24] [23]
[Как] я уже говорил месяц назад, я работаю над бесплатной версией Minix-аналога для компьютеров AT-386. Наконец-то он достиг той стадии, когда его можно даже использовать (хотя это может быть и не в зависимости от того, что вы хотите), и я готов выложить исходники для более широкого распространения. Это всего лишь версия 0.02... но я успешно запускал под ней bash, gcc, gnu-make, gnu-sed, compress и т. д.
После этого, несмотря на ограниченную функциональность ранних версий, Linux быстро завоевал разработчиков и пользователей. Многие люди внесли свой код в проект, в том числе некоторые разработчики из сообщества MINIX . [ нужна цитация ] В то время проект GNU Project создал множество компонентов, необходимых для его бесплатной замены UNIX, операционной системы GNU , но его собственное ядро, GNU Hurd , было неполным. По этой причине вскоре было принято и ядро Linux. [25] Распространение программного обеспечения Беркли еще не освободилось от юридических обременений и не конкурировало в сфере свободного ядра ОС. [26]
Торвальдс присвоил ядру версию 0, чтобы указать, что оно предназначено в основном для тестирования и не предназначено для продуктивного использования. [27] Версия 0.11, выпущенная в декабре 1991 года, была первым Linux с самостоятельным размещением , поскольку ее можно было скомпилировать на компьютере с тем же ядром.
Когда Торвальдс выпустил версию 0.12 в феврале 1992 года, он принял Стандартную общественную лицензию GNU версии 2 (GPLv2) вместо своей предыдущей лицензии, разработанной им самим, которая не допускала коммерческого распространения. [28] В отличие от Unix , все исходные файлы Linux находятся в свободном доступе, включая драйверы устройств . [29] Первоначальный успех Linux был обусловлен программистами и тестировщиками по всему миру. Благодаря поддержке POSIX API через libC, которая при необходимости действует как точка входа в адресное пространство ядра, Linux может запускать программное обеспечение и приложения, разработанные для Unix. [30]
19 января 1992 года было отправлено первое сообщение в новую группу новостей alt.os.linux . [31] 31 марта 1992 года группа новостей была переименована в comp.os.linux . [32] Тот факт, что Linux представляет собой монолитное ядро , а не микроядро , был темой дебатов между Эндрю С. Таненбаумом , создателем MINIX, и Торвальдсом. [33] Дебаты Таненбаума и Торвальдса начались в 1992 году в группе Usenet comp.os.minix как общая дискуссия об архитектуре ядра. [34] [35]
Linux версии 0.95 был первым, поддерживающим систему X Window . [36] В марте 1994 года был выпущен Linux 1.0.0 с 176 250 строками кода. [37] Это была первая версия, подходящая для использования в производственных средах . [27]
Он запустил систему управления версиями ядра с тремя или четырьмя числами, разделенными точками, где первое представляло основной выпуск , второе — второстепенный выпуск , а третье — ревизию. [12] : 9 В то время второстепенные выпуски с нечетными номерами предназначались для разработки и тестирования, а второстепенные выпуски с четными номерами предназначались для производства. Необязательная четвертая цифра указывает набор исправлений для версии. [27] Разрабатываемые версии обозначались суффиксом -rc («кандидат на выпуск»).
Текущая нумерация версий немного отличается от приведенной выше. Нумерация четных и нечетных чисел была удалена, и конкретная основная версия теперь обозначается первыми двумя цифрами, взятыми в целом. Хотя временные рамки для разработки следующей основной версии открыты , суффикс -rcN используется для обозначения n-го кандидата на выпуск следующей версии. [38] Например, выпуску версии 4.16 предшествовали семь 4.16-rcN (от -rc1 до -rc7). После выпуска стабильной версии ее обслуживание передается «команде стабильной версии». Периодические обновления стабильных выпусков обозначаются тремя схемами нумерации (например, 4.13.1, 4.13.2, ..., 4.13.16). [38]
После версии ядра 1.3 Торвальдс решил, что Linux достаточно развился, чтобы гарантировать новый основной номер, поэтому в июне 1996 года он выпустил версию 2.0.0. [39] [40] В серию вошёл 41 выпуск. Основной особенностью версии 2.0 была поддержка симметричной многопроцессорной обработки (SMP) и большего количества типов процессоров.
Начиная с версии 2.0, Linux можно настроить для выбора конкретного аппаратного обеспечения, а также для включения функций и оптимизации, зависящих от архитектуры. [30] Семейство команд make *config команды kbuild используется для включения и настройки тысяч опций для создания специальных исполняемых файлов ядра ( vmlinux ) и загружаемых модулей. [14] [15]
Версия 2.2, выпущенная 20 января 1999 года, [41] улучшила степень детализации блокировок и управление SMP, добавила поддержку m68k , PowerPC , Sparc64 , Alpha и других 64-битных платформ. [42] Кроме того, были добавлены новые файловые системы , включая возможность чтения только для чтения NTFS от Microsoft . [42] В 1999 году IBM опубликовала свои исправления для кода Linux 2.2.13 для поддержки архитектуры S/390 . [43]
Версия 2.4.0, выпущенная 4 января 2001 года, [44] содержала поддержку ISA Plug and Play , USB и PC Cards . В Linux 2.4 добавлена поддержка Pentium 4 и Itanium (последний представил ia64 ISA, который был совместно разработан Intel и Hewlett-Packard для замены старого PA-RISC ), а также нового 64-битного процессора MIPS. [45] Разработка для 2.4. x немного изменился: на протяжении всей серии стало доступно больше функций, включая поддержку Bluetooth , диспетчера логических томов (LVM) версии 1, поддержку RAID , файловых систем InterMezzo и ext3 .
Версия 2.6.0 была выпущена 17 декабря 2003 года. [46] Разработка версии 2.6. x были внесены дальнейшие изменения в сторону включения новых функций во всю серию. Среди изменений, внесенных в серию 2.6, можно отметить: интеграцию µClinux в основные исходные коды ядра, поддержку PAE , поддержку нескольких новых линеек процессоров , интеграцию Advanced Linux Sound Architecture (ALSA) в основные исходные коды ядра, поддержку до 2 32 пользователей (вместо 2 16 ), поддержка до 2 29 идентификаторов процессов (только 64-битные, 32-битные архитектуры по-прежнему ограничены 2 15 ), [47] существенно увеличено количество типов устройств и количество устройств каждого типа, улучшенная поддержка 64-бит , поддержка файловых систем , поддерживающих размер файлов до 16 терабайт , вытеснение в ядре , поддержка Native POSIX Thread Library (NPTL), интеграция пользовательского режима Linux в основную ветку исходные коды ядра, интеграция SELinux с основными исходными кодами ядра, поддержка InfiniBand и многое другое.
Также следует отметить добавление широкого выбора файловых систем, начиная с версии 2.6. x : теперь ядро поддерживает большое количество файловых систем, некоторые из которых были разработаны для Linux, например ext3 , ext4 , FUSE , Btrfs , [48] и другие, которые являются собственными для других операционных систем, таких как JFS , XFS , Minix . , Xenix , Irix , Solaris , System V , Windows и MS-DOS . [49]
В 2005 году группа стабильных версий была сформирована в ответ на отсутствие дерева ядра, где люди могли бы работать над исправлением ошибок , и она продолжала обновлять стабильные версии. [50] В феврале 2008 года было создано дерево linux-next , которое служило местом сбора патчей, предназначенных для объединения во время следующего цикла разработки. [51] [52] Некоторые сопровождающие подсистем также приняли суффикс -next для деревьев, содержащих код, который они собираются отправить для включения в следующий цикл выпуска. По состоянию на январь 2014 года [обновлять]находящаяся в разработке версия Linux находится в нестабильной ветке под названием linux-next . [53]
Раньше Linux обслуживался без помощи автоматизированной системы управления исходным кодом , пока в 2002 году разработка не перешла на BitKeeper . Оно было свободно доступно разработчикам Linux, но не было свободным программным обеспечением . В 2005 году из-за попыток реконструировать его компания, владевшая этим программным обеспечением, прекратила поддержку сообщества Linux. В ответ Торвальдс и другие написали Git . Новая система была написана за несколько недель, а через два месяца было выпущено первое официальное ядро, созданное с ее использованием. [54]
Подробности об истории серии ядер 2.6 можно найти в файлах ChangeLog в области выпуска исходного кода серии ядра 2.6 на сайте kernel.org . [55]
20-летие Linux Торвальдс отметил в июле 2011 года выпуском версии ядра 3.0.0. [39] Поскольку номер версии 2.6 был номером версии в течение 8 лет, в ядро пришлось добавить новую личность uname26 , которая сообщает 3.x как 2.6.40+x, чтобы старые программы работали. [56]
Версия 3.0 была выпущена 22 июля 2011 года. [57] 30 мая 2011 года Торвальдс объявил, что большим изменением является «НИЧЕГО. Абсолютно ничего». и спросил: «...давайте убедимся, что мы действительно сделаем следующий выпуск не просто новым блестящим номером, но и хорошим ядром». [58] После ожидаемых 6–7 недель процесса разработки он будет выпущен ближе к 20-летию Linux.
11 декабря 2012 года Торвальдс решил снизить сложность ядра, удалив поддержку процессоров i386 , в результате чего серия ядер 3.7 стала последней, которая все еще поддерживает исходный процессор. [59] [60] Та же серия унифицированной поддержки процессора ARM . [61]
Версия 3.11, выпущенная 2 сентября 2013 года, [62] добавляет множество новых функций, таких как новый флаг O_TMPFILE для уменьшения уязвимостей временных файлов, экспериментальное динамическое управление питанием AMD Radeon , опрос сети с малой задержкой и zswap (сжатый кэш подкачки). [63]
Изменение нумерации с 2.6.39 на 3.0 и с 3.19 на 4.0 не повлекло за собой значимой технической дифференциации. Основной номер версии был увеличен, чтобы избежать больших второстепенных номеров. [57] [64] Стабильные ядра 3.xy выпускались до версии 3.19 в феврале 2015 года.
В апреле 2015 года Торвальдс выпустил версию ядра 4.0. [39] К февралю 2015 года Linux получил вклад почти от 12 000 программистов из более чем 1200 компаний, включая некоторых крупнейших мировых поставщиков программного и аппаратного обеспечения. [65] Версия Linux 4.1, выпущенная в июне 2015 года, содержит более 19,5 миллионов строк кода, написанного почти 14 000 программистами. [66]
В общей сложности 1991 разработчик, из которых 334 работали впервые, добавили более 553 000 строк кода в версию 5.8, побив рекорд, ранее установленный версией 4.9. [67]
Согласно ежегодному опросу разработчиков Stack Overflow за 2019 год, более 53% всех респондентов разработали программное обеспечение для Linux и около 27% для Android , [68] хотя только около 25% разрабатывают программное обеспечение для операционных систем на базе Linux. [69]
Большинство веб-сайтов работают на операционных системах на базе Linux , [70] [71] , и все 500 самых мощных суперкомпьютеров в мире используют ту или иную ОС на базе Linux. [72]
Дистрибутивы Linux включают ядро с системным программным обеспечением (например, библиотекой GNU C , systemd и другими утилитами и демонами Unix ) и широким выбором прикладного программного обеспечения , но доля их использования на настольных компьютерах невелика по сравнению с другими операционными системами.
Android , на долю которого приходится большая часть установленной базы всех операционных систем для мобильных устройств, [73] [74] [75] отвечает за растущее использование ядра Linux [30] вместе с его широким использованием в больших масштабах. разнообразие встраиваемых устройств .
Linux представляет собой монолитное ядро с модульной конструкцией (т. е. оно может вставлять и удалять загружаемые модули ядра во время выполнения), [12] : 338 [76] , поддерживающее большинство функций, которые раньше были доступны только в ядрах с закрытым исходным кодом несвободных операционных систем. В оставшейся части статьи используются соглашения UNIX и Unix-подобных операционных систем, изложенные на официальных страницах руководства . Числа, следующие за названиями команд, интерфейсов и других функций, предназначены для указания раздела (т. е. типа компонента или функции ОС), к которому они принадлежат (например, execve(2) относится к системному вызову , а exec(3) относится к оболочке библиотеки пользовательского пространства). В следующем списке и последующих разделах дается неполный обзор архитектурного проектирования Linux и некоторых его примечательных особенностей.
Большинство драйверов устройств и расширений ядра работают в пространстве ядра ( кольцо 0 во многих архитектурах ЦП ) с полным доступом к оборудованию. Некоторые исключения выполняются в пространстве пользователя ; Яркими примерами являются файловые системы, основанные на FUSE /CUSE и части UIO. [95] [96] Более того, X Window System и Wayland , оконная система и протоколы серверов отображения, которые большинство людей используют в Linux, не работают в ядре. Иными словами, фактическое взаимодействие с графическими процессорами видеокарт представляет собой внутриядерную подсистему, называемую Direct Rendering Manager (DRM).
В отличие от стандартных монолитных ядер, драйверы устройств легко настраиваются как модули и загружаются или выгружаются во время работы системы, а также могут быть вытеснены при определенных условиях, чтобы правильно обрабатывать аппаратные прерывания и лучше поддерживать симметричную многопроцессорную обработку . [79] По выбору Linux не имеет стабильного двоичного интерфейса приложения драйвера устройства . [97]
Linux обычно использует защиту памяти и виртуальную память , а также может обрабатывать неравномерный доступ к памяти , [98] однако проект включил в себя программу uClinux , которая также позволяет запускать Linux на микроконтроллерах без виртуальной памяти. [99]
Аппаратное обеспечение представлено в файловой иерархии. Пользовательские приложения взаимодействуют с драйверами устройств через записи в каталогах /dev или /sys . [100] Информация о процессах также отображается в файловой системе через каталог /proc . [100]
Linux является клоном UNIX и нацелен на соответствие POSIX и единой спецификации UNIX . [102] Ядро также предоставляет системные вызовы и другие интерфейсы, специфичные для Linux. Чтобы быть включенным в официальное ядро, код должен соответствовать набору правил лицензирования. [6] [11]
Двоичный интерфейс приложения Linux (ABI) между ядром и пользовательским пространством имеет четыре степени стабильности (стабильный, тестируемый, устаревший, удаленный); [103] однако ожидается, что системные вызовы никогда не будут меняться, чтобы не нарушать работу программ пользовательского пространства , которые на них полагаются. [104]
Загружаемые модули ядра (LKM) по своей конструкции не могут полагаться на стабильный ABI. [97] Поэтому их необходимо всегда перекомпилировать всякий раз, когда в системе устанавливается новый исполняемый файл ядра, иначе они не будут загружены. Драйверы в дереве, которые настроены стать неотъемлемой частью исполняемого файла ядра ( vmlinux ), статически связываются в процессе сборки.
Также нет никакой гарантии стабильности API внутри ядра на уровне исходного кода [97] , и по этой причине код драйверов устройств , как и код любой другой подсистемы ядра, должен постоянно обновляться по мере развития ядра. Любой разработчик, вносящий изменения в API, обязан исправить любой код, который выходит из строя в результате их изменения. [105]
Набор API ядра Linux , который касается интерфейсов, предоставляемых пользовательским приложениям, в основном состоит из системных вызовов UNIX и Linux . [106] Системный вызов — это точка входа в ядро Linux. [107] Например, среди специфичных для Linux есть семейство системных вызовов clone(2) . [108] Большинство расширений необходимо включить путем определения макроса в заголовочном файле или при компиляции пользовательского кода. [109]_GNU_SOURCE
Системные вызовы могут быть вызваны только с помощью инструкций ассемблера, которые позволяют перейти из непривилегированного пользовательского пространства в привилегированное пространство ядра в кольце 0 . По этой причине стандартная библиотека C (libC) действует как оболочка для большинства системных вызовов Linux, предоставляя функции C, которые, только если это необходимо, [110] могут прозрачно войти в ядро, которое будет выполняться от имени вызывающего. процесс. [106] Для системных вызовов, не предоставляемых libC, например, быстрого мьютекса пользовательского пространства ( futex ), [111] библиотека предоставляет функцию под названием syscall(2) , которую можно использовать для их явного вызова. [112]
Псевдофайловые системы (например, файловые системы sysfs и procfs ) и специальные файлы (например, /dev/random
, /dev/sda
, /dev/tty
, и многие другие) составляют еще один уровень интерфейса для структур данных ядра, представляющих аппаратные или логические (программные) устройства. [113] [114]
Из-за различий, существующих между сотнями различных реализаций ОС Linux, исполняемые объекты, даже если они скомпилированы, собраны и скомпонованы для работы на конкретной аппаратной архитектуре (то есть используют ISA целевого оборудования), часто не может работать в разных дистрибутивах Linux. Эта проблема в основном связана с конфигурациями, специфичными для дистрибутива, и набором исправлений, примененных к коду ядра Linux, различиями в системных библиотеках, службах (демонах), иерархиях файловой системы и переменных среды.
Основным стандартом, касающимся совместимости приложений и двоичной совместимости дистрибутивов Linux, является Linux Standard Base (LSB). [115] [116] Однако LSB выходит за рамки того, что касается ядра Linux, поскольку он также определяет спецификации рабочего стола, библиотеки X и Qt, которые имеют мало общего с ним. [117] LSB версии 5 построена на основе нескольких стандартов и проектов (POSIX, SUS, X/Open, File System Hierarchy (FHS) и других). [118]
Частями LSB, наиболее важными для ядра, являются общий ABI (gABI), [119] особенно System V ABI [120] [121] и формат исполняемых файлов и компоновки (ELF), [122] [123] и ABI, специфичный для процессора (psABI), например базовая спецификация для X86-64. [124] [125]
Стандартный ABI для того, как пользовательские программы x86_64 вызывают системные вызовы, заключается в загрузке номера системного вызова в регистр rax , а других параметров в rdi , rsi , rdx , r10 , r8 и r9 и, наконец, помещения инструкции сборки системного вызова в код. [126] [127] [128]
Между различными подсистемами используется несколько внутренних API ядра. Некоторые из них доступны только в подсистемах ядра, в то время как несколько ограниченный набор внутриядерных символов (т. е. переменных, структур данных и функций) доступен также динамически загружаемым модулям (например, драйверам устройств, загружаемым по требованию), вне зависимости от того, являются ли они экспортируются с помощью макросов EXPORT_SYMBOL() и EXPORT_SYMBOL_GPL() [130] [131] (последний зарезервирован для модулей, выпущенных под лицензией, совместимой с GPL). [132]
Linux предоставляет встроенные в ядро API, которые манипулируют структурами данных (например, связанными списками , базовыми деревьями , [133] красно-черными деревьями , [134] очередями ) или выполняют общие процедуры (например, копирование данных из и в пользовательское пространство, выделение памяти, печатать строки в системный журнал и т. д.), которые остаются стабильными, по крайней мере, начиная с версии Linux 2.6. [135] [136] [137]
Внутриядерные API включают библиотеки общих служб низкого уровня, используемых драйверами устройств:
Разработчики Linux решили не поддерживать стабильный встроенный ABI. Модули, скомпилированные для определенной версии ядра, не могут быть загружены в другую версию без перекомпиляции, при условии, что внутриядерный API остался прежним на уровне исходного кода; в противном случае код модуля также необходимо соответствующим образом изменить. [97]
Linux создает процессы с помощью системных вызовов clone(2) или более новой версии clone3(2) [147] . В зависимости от заданных параметров новый объект может использовать большую часть ресурсов вызывающего абонента или не использовать их вообще. Эти системные вызовы могут создавать новые объекты, начиная от новых независимых процессов (каждый из которых имеет специальный идентификатор TGID в структуре данных Task_struct в пространстве ядра, хотя в пространстве пользователя этот же идентификатор называется PID ) до новых потоков выполнения внутри вызывающего процесса (посредством с помощью параметра CLONE_THREAD ). В последнем случае новый объект владеет тем же TGID вызывающего процесса и, следовательно, имеет тот же PID в пользовательском пространстве. [148] [149]
Если исполняемый файл динамически связан с общими библиотеками, динамический компоновщик (для объектов ELF обычно это /lib/ld-linux.so.2 ) используется для поиска и загрузки необходимых объектов, подготовки программы к запуску и последующего запуска. это. [150]
Собственная библиотека потоков POSIX , известная просто как NPTL, [151] предоставляет стандартный интерфейс потоков POSIX ( pthreads ) для пользовательского пространства. [152] Всякий раз, когда новый поток создается с использованием POSIX-интерфейса pthread_create(3), [153] семейству системных вызовов clone (2) также должен быть присвоен адрес функции, к которой должен перейти новый поток. Ядро Linux предоставляет механизмы futex(7) (аббревиатура от «Быстрые мьютексы в пользовательском пространстве») для быстрой блокировки и синхронизации пользовательского пространства; [154] Большинство операций выполняются в пользовательском пространстве, но может потребоваться связь с ядром с помощью системного вызова futex(2) . [111]
Особой категорией потоков являются так называемые потоки ядра . Их не следует путать с упомянутыми выше потоками исполнения пользовательских процессов. Потоки ядра существуют только в пространстве ядра, и их единственная цель — одновременное выполнение задач ядра. [155]
Иными словами, всякий раз, когда создается независимый процесс, системные вызовы возвращаются точно к следующей инструкции той же программы, одновременно в родительском процессе и в дочернем (т.е. одна программа, два процесса). Различные возвращаемые значения (по одному на каждый процесс) позволяют программе узнать, в каком из двух процессов она выполняется в данный момент. Программам нужна эта информация, потому что дочерний процесс через несколько шагов после дублирования процесса обычно вызывает системный вызов execve(2) (возможно, через семейство функций-оболочек exec(3) в glibC) и заменяет программу, которая в данный момент выполняется вызывающий процесс с новой программой, с вновь инициализированным стеком, кучей и (инициализированными и неинициализированными) сегментами данных. [156] Когда это будет сделано, в результате появятся два процесса, которые запускают две разные программы.
В зависимости от эффективного идентификатора пользователя ( euid ) и эффективного идентификатора группы ( egid ), процесс, работающий с нулевыми привилегиями пользователя ( root , системный администратор, имеет идентификатор 0), может выполнять все (например, уничтожать все остальные процессы). или рекурсивно уничтожить целые файловые системы), вместо этого ненулевые пользовательские процессы не могут. возможности(7) разделяет привилегии, традиционно связанные с суперпользователем, на отдельные блоки, которые могут быть независимо включены и отключены родительским процессом или удалены самим дочерним процессом. [157]
Планировщик процессов Linux является модульным в том смысле, что он позволяет использовать различные классы и политики планирования. [158] [159] Классы планировщика представляют собой подключаемые алгоритмы планировщика, которые можно зарегистрировать с помощью базового кода планировщика. Каждый класс планирует различные типы процессов. Основной код планировщика перебирает каждый класс в порядке приоритета и выбирает планировщик с наивысшим приоритетом, у которого есть планируемый объект типа struct sched_entity, готовый к запуску. [12] : 46–47 Сущностями могут быть потоки, группы потоков и даже все процессы конкретного пользователя.
Linux обеспечивает как приоритетное вытеснение пользователя , так и полное вытеснение ядра . [12] : 62–63 Вытеснение уменьшает задержку , увеличивает скорость реагирования, [160] и делает Linux более подходящим для настольных компьютеров и приложений реального времени .
Для обычных задач ядро по умолчанию использует класс Completely Fair Scheduler (CFS), представленный в версии ядра 2.6.23. [80] Внутренне этот класс планировщика по умолчанию определен в макросе заголовка C как SCHED_NORMAL
. В других ядрах POSIX аналогичная политика, известная как SCHED_OTHER
распределение временных интервалов ЦП (т. е. она назначает абсолютные фрагменты процессорного времени в зависимости от заранее определенного или динамически вычисленного приоритета каждого процесса). Linux CFS отказывается от абсолютных временных интервалов и распределяет значительную долю процессорного времени в зависимости от таких параметров, как общее количество запущенных процессов и время, в течение которого они уже выполнялись; эта функция также учитывает своего рода вес, который зависит от их относительных приоритетов (приятных значений). [12] : 46–50
Благодаря приоритету пользователя планировщик ядра может заменить текущий процесс выполнением переключения контекста на другой, который, таким образом, получает вычислительные ресурсы для работы (ЦП, память и т. д.). Он делает это в соответствии с алгоритмом CFS (в частности, он использует переменную, называемую vruntime , для сортировки сущностей, а затем выбирает тот, который имеет меньшее время vruntime, т. е. планируемый объект, на который была наименьшая доля процессорного времени), чтобы активную политику планировщика и относительные приоритеты. [161] При использовании вытеснения ядра ядро может вытеснять себя, когда возвращается обработчик прерывания, когда задачи ядра блокируются, а также всякий раз, когда подсистема явно вызывает функцию Schedule().
Ядро также содержит два POSIX-совместимых [162] класса планирования реального времени с именами SCHED_FIFO
(realtime first-in-first-out ) и SCHED_RR
(realtime round-robin ), оба из которых имеют приоритет над классом по умолчанию. [158] Дополнительная политика планирования, известная как SCHED DEADLINE
, реализующая алгоритм «сначала самый ранний срок» (EDF), была добавлена в версию ядра 3.14, выпущенную 30 марта 2014 года. [163] [164] SCHED_DEADLINE
имеет приоритет над всеми другими классами планирования.
Патчи реального времени PREEMPT_RT
, включенные в основную версию Linux начиная с версии 2.6, обеспечивают детерминированный планировщик , удаление вытеснения и отключение прерываний (где это возможно), PI Mutexes (т.е. блокировку примитивов, которые позволяют избежать инверсии приоритетов), [165] [166] поддержка таймеров событий высокой точности (HPET), упреждающего чтения-копирования-обновления (RCU), (принудительных) потоков IRQ и других второстепенных функций. [167] [168] [169]
В 2023 году Питер Зийлстра предложил заменить CFS самым ранним подходящим планировщиком виртуального крайнего срока первого планирования (EEVDF), [170] [171] , чтобы избежать необходимости в патчах CFS с «оптимальной задержкой». [172] Планировщик EEVDF заменил CFS в версии 6.6 ядра Linux. [173]
Ядро имеет разные причины параллелизма (например, прерывания, нижние половины, вытеснение задач ядра и пользователей, симметричная многопроцессорная обработка). [12] : 167 Для защиты критических областей (разделов кода, которые должны выполняться атомарно), областей общей памяти (например, глобальных переменных и других структур данных с глобальной областью действия) и областей памяти, которые асинхронно модифицируются аппаратным обеспечением (например, имея квалификатор типа C ), Linux предоставляет большой набор инструментов. Они состоят из атомарных типов (манипулировать которыми можно только с помощью набора определенных операторов), спин-блокировок , семафоров , мьютексов , [174] [12] : 176–198 [175] и безблокировочных алгоритмов (например, RCU ). [176] [177] [178] Большинство алгоритмов без блокировок построены поверх барьеров памяти с целью обеспечения порядка в памяти и предотвращения нежелательных побочных эффектов из-за оптимизации компилятора . [179] [180] [181] [182]volatile
PREEMPT_RT
код, включенный в основную версию Linux, предоставляет RT-мьютексы , особый вид мьютексов, которые не отключают вытеснение и поддерживают наследование приоритетов. [183] [184] Почти все блокировки переводятся в спящие блокировки при использовании конфигурации для работы в реальном времени. [185] [169] [184] Наследование приоритета позволяет избежать инверсии приоритета, предоставляя задаче с низким приоритетом, которая удерживает конкурирующую блокировку, приоритет ожидающего с более высоким приоритетом, пока эта блокировка не будет снята. [186] [187]
Linux включает в себя валидатор блокировки ядра под названием Lockdep . [188] [189]
Управление прерываниями , хотя его можно рассматривать как одну задачу, разделено на две отдельные части. Такое разделение на две части обусловлено различными временными ограничениями и необходимостью синхронизации задач, из которых состоит управление. Первая часть состоит из асинхронной процедуры обслуживания прерываний , которая в Linux известна как верхняя половина , тогда как вторая часть выполняется одним из трех типов так называемых нижних половин ( softirq , тасклеты и рабочие очереди ) . . [12] : 133–137 Подпрограммы обслуживания прерываний Linux могут быть вложенными (т. е. новый IRQ может попасть в ISR с высоким приоритетом, который вытесняет любые другие ISR с более низким приоритетом).
Управление памятью в Linux — сложная тема. Прежде всего, ядро не является страничным (т. е. оно всегда находится в физической памяти и не может быть перенесено на диск). В ядре нет защиты памяти (нет сигналов SIGSEGV , в отличие от пользовательского пространства), поэтому нарушения памяти приводят к нестабильности и сбоям системы. [12] : 20
Linux реализует виртуальную память с 4- и 5-уровневыми таблицами страниц . Как уже было сказано, только пространство пользовательской памяти всегда доступно для страниц . Он хранит информацию о каждом страничном кадре ОЗУ в соответствующих структурах данных (типа struct page ) , которые заполняются сразу после загрузки и сохраняются до завершения работы, независимо от того, связаны они с виртуальными страницами или нет. Более того, он классифицирует все страничные фреймы по зонам в соответствии с ограничениями, зависящими от их архитектуры, и предполагаемым использованием. Например, страницы, зарезервированные для операций DMA, находятся в ZONE_DMA, страницы, которые не сопоставлены постоянно с виртуальными адресами, находятся в ZONE_HIGHMEM (в архитектуре x86_32 эта зона предназначена для физических адресов размером более 896 МБ, тогда как x86_64 в ней не нуждается, поскольку x86_64 может постоянно отображать физические адреса). страницы, находящиеся по более высоким адресам), и все, что остается (за исключением других, менее используемых классификаций), находится в ZONE_NORMAL.
Небольшие фрагменты памяти можно динамически выделять с помощью семейства kmalloc()
API и освобождать с помощью соответствующего варианта kfree()
. vmalloc()
и kvfree()
используются для больших, практически смежных фрагментов. alloc_pages()
выделяет желаемое количество целых страниц.
Ядро включает в себя распределители SLAB, SLUB и SLOB в качестве настраиваемых альтернатив. [191] [192] SLUB — новейший вариант, а также распределитель по умолчанию. Он нацелен на простоту и эффективность [192] и PREEMPT_RT
совместим. [193] Распределитель SLOB был позже удален в Linux 6.4, [194] Распределитель SLAB планировалось удалить в Linux 6.5, оставив единственным оставшимся распределителем SLUB, который доступен начиная с Linux 2.6. [195]
Хотя Linux изначально не был предназначен для переносимости , [22] [196] Linux в настоящее время является одним из наиболее широко портируемых ядер операционных систем, работающим на самых разных системах, от архитектуры ARM до мейнфреймов IBM z/Architecture . Первый порт был выполнен на платформе Motorola 68000 . Модификации ядра были настолько фундаментальными, что Торвальдс рассматривал версию Motorola как ответвление и «Linux-подобную операционную систему». [196] Однако это побудило Торвальдса провести серьезную реструктуризацию кода, чтобы облегчить портирование на большее количество вычислительных архитектур. Первый Linux, который в одном дереве исходного кода содержал код более чем для i386, поддерживал 64-битную платформу DEC Alpha AXP . [197] [198] [196]
Linux работает в качестве основной операционной системы на IBM Summit ; По состоянию на октябрь 2019 года все 500 самых быстрых суперкомпьютеров в мире работают под управлением той или иной операционной системы на основе ядра Linux, [13] что является большим изменением по сравнению с 1998 годом, когда в список был добавлен первый суперкомпьютер Linux. [199][update]
Linux также был портирован на различные портативные устройства, такие как Apple iPhone 3G и iPod . [200]
В 2007 году был начат проект LKDDb по созданию комплексной базы данных оборудования и протоколов, известных ядрам Linux. [201] База данных создается автоматически путем статического анализа исходников ядра. Позже в 2014 году был запущен проект Linux Hardware для автоматического сбора базы данных всех протестированных конфигураций оборудования с помощью пользователей различных дистрибутивов Linux. [202]
Обновления без перезагрузки можно даже применять к ядру с помощью технологий оперативного исправления, таких как Ksplice , kpatch и kGraft . Минималистичные основы для оперативного исправления ядра были объединены с основной веткой ядра Linux в версии ядра 4.0, выпущенной 12 апреля 2015 года. Эти основы, известные как livepatch и основанные главным образом на функциональности ядра ftrace , образуют общее ядро, способное поддерживать горячее исправление. как kGraft, так и kpatch, предоставляя интерфейс прикладного программирования (API) для модулей ядра, содержащих горячие исправления, и двоичный интерфейс приложения (ABI) для утилит управления пользовательским пространством. Однако общее ядро, включенное в ядро Linux 4.0, поддерживает только архитектуру x86 и не предоставляет никаких механизмов для обеспечения согласованности на уровне функций во время применения горячих исправлений. По состоянию на апрель 2015 года [update]продолжается работа по портированию kpatch и kGraft на общее ядро оперативного исправления, предоставляемое основной веткой ядра Linux. [203] [204] [205]
Ошибки ядра представляют собой потенциальные проблемы безопасности. Например, они могут допускать повышение привилегий или создавать векторы атак типа «отказ в обслуживании» . За прошедшие годы было обнаружено и исправлено множество ошибок, влияющих на безопасность системы. [206] Часто внедряются новые функции для повышения безопасности ядра. [207] [208]
Возможности(7) уже были представлены в разделе о процессах и потоках. Android использует их, а systemd предоставляет администраторам детальный контроль над возможностями процессов. [209]
Linux предлагает множество механизмов для уменьшения поверхности атаки ядра и повышения безопасности, которые известны под общим названием « Модули безопасности Linux» (LSM). [210] Они включают в себя модуль Security-Enhanced Linux (SELinux), код которого был первоначально разработан, а затем опубликован АНБ , [ 211] и AppArmor [94] среди других. SELinux сейчас активно развивается и поддерживается на GitHub . [93] SELinux и AppArmor обеспечивают поддержку политик безопасности контроля доступа, включая обязательный контроль доступа (MAC), хотя они существенно различаются по сложности и сфере применения.
Еще одной функцией безопасности является Seccomp BPF (Безопасные вычисления с фильтрами пакетов Беркли), которая работает путем фильтрации параметров и сокращения набора системных вызовов, доступных для пользовательских приложений. [212]
Критики обвиняют разработчиков ядра в сокрытии недостатков безопасности или, по крайней мере, не объявляют о них; в 2008 году Линус Торвальдс ответил на это следующее: [213] [214]
Лично я считаю ошибки безопасности просто «обычными ошибками». Я их не скрываю, но у меня также нет никаких оснований думать, что отслеживать их и объявлять о чем-то особенном — это хорошая идея... одна из причин, по которой я отказываюсь беспокоиться о всей безопасности. Цирк заключается в том, что я думаю, что он прославляет – и, таким образом, поощряет – неправильное поведение. Это делает людей, занимающихся безопасностью, «героями», как будто люди, которые не просто исправляют обычные ошибки, не так важны. На самом деле, все скучные обычные ошибки гораздо важнее просто потому, что их [sic] намного больше. Я не думаю, что какую-то впечатляющую дыру в безопасности следует прославлять или рассматривать как более «особенную», чем случайный впечатляющий сбой из-за плохой блокировки.
Дистрибутивы Linux обычно выпускают обновления безопасности для исправления уязвимостей в ядре Linux. Многие предлагают выпуски с долгосрочной поддержкой , которые получают обновления безопасности для определенной версии ядра Linux в течение длительного периода времени.
Сообщество разработчиков ядра Linux насчитывает около 5000–6000 участников. Согласно исследованию «Состояние разработки ядра Linux в 2017 году», опубликованному Linux Foundation и охватывающему коммиты для выпусков с 4.8 по 4.13, в среднем около 1500 разработчиков внесли свой вклад из примерно 200-250 компаний. 30 лучших разработчиков внесли чуть более 16% кода. Среди компаний наибольший вклад вносят Intel (13,1%) и Red Hat (7,2%), Linaro (5,6%), IBM (4,1%), второе и пятое места занимают «нет» (8,2%) и «нет». неизвестные» (4,1%) категории. [216]
Вместо дорожной карты — технические рекомендации. Вместо централизованного распределения ресурсов существуют люди и компании, которые заинтересованы в дальнейшем развитии ядра Linux, совершенно независимо друг от друга: такие люди, как Линус Торвальдс и я, не планируют эволюцию ядра. Мы не сидим и не продумываем план действий на следующие два года, а затем распределяем ресурсы на различные новые функции. Это потому, что у нас нет ресурсов. Все ресурсы принадлежат различным корпорациям, которые используют и вносят свой вклад в Linux, а также различным независимым участникам. Решают те люди, которые владеют ресурсами...
— Эндрю Мортон , 2005 г.
Как и во многих крупных проектах программного обеспечения с открытым исходным кодом, разработчики обязаны соблюдать Соглашение участников — кодекс поведения , предназначенный для борьбы с преследованием участников меньшинства. [217] [218] Кроме того, во избежание правонарушений использование инклюзивной терминологии в исходном коде является обязательным. [219]
Сообщество разработчиков Linux использует Git для управления исходным кодом . Пользователи Git клонируют последнюю версию дерева Торвальдса с помощью git-clone(1) [220] и поддерживают ее в актуальном состоянии с помощью git-pull(1) . [221] [222] Вклады отправляются в виде патчей в виде текстовых сообщений в LKML (а часто также в других списках рассылки, посвященных конкретным подсистемам). Патчи должны соответствовать набору правил и формальному языку, который, среди прочего, описывает, какие строки кода следует удалить, а какие еще следует добавить в указанные файлы. Эти исправления могут автоматически обрабатываться, чтобы системные администраторы могли применять их для внесения лишь некоторых изменений в код или для постепенного обновления до следующей версии. [223] Linux также распространяется в форматах GNU zip (gzip) и bzip2 .
Разработчик, желающий изменить ядро Linux, начинает с разработки и тестирования этого изменения. В зависимости от того, насколько значительным является изменение и сколько подсистем оно модифицирует, изменение будет представлено либо в виде одного исправления, либо в виде нескольких исправлений исходного кода . В случае, если одна подсистема обслуживается одним сопровождающим, эти исправления отправляются по электронной почте сопровождающему подсистемы с соответствующим списком рассылки в поле Cc. Сопровождающий и читатели списка рассылки будут просматривать исправления и оставлять отзывы. После завершения процесса проверки специалист по сопровождению подсистемы принимает исправления в соответствующем дереве ядра Git . Если изменения в ядре Linux представляют собой исправления ошибок, которые считаются достаточно важными, запрос на получение исправлений будет отправлен Торвальдсу в течение нескольких дней. В противном случае запрос на включение будет отправлен Торвальдсу во время следующего окна слияния. Окно слияния обычно длится две недели и начинается сразу после выпуска предыдущей версии ядра. [224] В дереве исходного кода ядра Git имена всех разработчиков, внесших вклад в ядро Linux, указаны в каталоге « Кредиты» , а все сопровождающие подсистемы перечислены в разделе «Сопровождающие» . [225]
Linux написан на специальном языке программирования C , поддерживаемом GCC — компилятором, который во многих отношениях расширяет стандарт C, например, используя встроенные разделы кода , написанные на языке ассемблера (в синтаксисе GCC «AT&T-style») целевой архитектуры. . С 2002 года весь код должен соответствовать 21 правилу, составляющему стиль кодирования ядра Linux. [226] [227]
В сентябре 2021 года требования к версии GCC для компиляции и сборки ядра Linux были увеличены с GCC 4.9 до 5.1, что позволяет перейти от использования кода C, основанного на стандарте C89, к использованию кода, написанного с использованием стандарта C11 . 228] с переходом на стандарт, который состоится в марте 2022 года с выходом Linux 5.18. [229]
Первоначальная поддержка языка программирования Rust была добавлена в Linux 6.1 [5] , выпущенную в декабре 2022 года, [230] с более поздними версиями ядра, такими как Linux 6.2 и Linux 6.3, что еще больше улучшило поддержку. [231] [232]
Коллекция компиляторов GNU (GCC или GNU cc) является компилятором по умолчанию для основных исходных кодов Linux и вызывается утилитой make . Затем ассемблер GNU (чаще называемый GAS или GNU as) выводит объектные файлы из сгенерированного GCC ассемблерного кода. Наконец, GNU Linker (GNU ld) используется для создания статически связанного исполняемого файла ядра, называемого vmlinux . И as, и ld являются частью двоичных утилит GNU (binutils). Вышеупомянутые инструменты вместе известны как набор инструментов GNU .
GCC долгое время был единственным компилятором, способным правильно собирать Linux. В 2004 году Intel заявила, что модифицировала ядро так, чтобы его компилятор C также мог его компилировать. [233] Еще один подобный успех был зарегистрирован в 2009 году с модифицированной версией 2.6.22. [234] [235] Поддержка компилятора Intel прекращена в 2023 году. [236]
С 2010 года предпринимаются усилия по созданию Linux с Clang , альтернативным компилятором для языка C; [237] по состоянию на 12 апреля 2014 г. официальное ядро почти можно было скомпилировать с помощью Clang. [238] [239] Проект, посвященный этому проекту, назван LLVMLinux в честь инфраструктуры компилятора LLVM , на которой построен Clang. [240] LLVMLinux не преследует цель создать форк Linux или LLVM, поэтому это метапроект, состоящий из патчей, которые в конечном итоге передаются вышестоящим проектам. Включив компиляцию Linux с помощью Clang, разработчики могут получить выгоду от сокращения времени компиляции. [241]
В 2017 году разработчики завершили выпуск исправлений для поддержки сборки ядра Linux с помощью Clang в выпуске 4.15, перенеся поддержку X86-64 и AArch64 в ветки стабильного дерева ядра 4.4, 4.9 и 4.14. Google Pixel 2 поставлялся с первым ядром Linux , созданным Clang , [242] хотя патчи для Pixel (1-го поколения) существовали. [243] В 2018 году ChromeOS перешла на сборку ядер с помощью Clang по умолчанию, [244] в то время как Android (операционная система) сделала Clang [245] и компоновщик LLVM LLD [ 246] необходимыми для сборки ядра в 2019 году. Google перенесла производство ядра использовалась во всех центрах обработки данных, а в 2020 году была построена с помощью Clang . [247] Сегодня группа ClangBuiltLinux координирует исправления как для Linux , так и для LLVM для обеспечения совместимости, причем обе группы состоят из членов LLVMLinux и имеют исходные исправления от LLVMLinux .
Ошибки, связанные с ядром Linux, может быть сложно устранить. Это происходит из-за взаимодействия ядра с пользовательским пространством и оборудованием; а также потому, что они могут быть вызваны более широким спектром причин, чем причины пользовательских программ. Несколько примеров основных причин: семантические ошибки в коде, неправильное использование примитивов синхронизации и неправильное управление оборудованием. [12] : 364
Сообщение о нефатальной ошибке в ядре называется « упс »; такие отклонения от правильного поведения ядра Linux могут позволить продолжить работу с пониженной надежностью. [248]
О критической и фатальной ошибке сообщается с помощью функции паники() . Он печатает сообщение, а затем останавливает работу ядра. [12] : 371
Одним из наиболее распространенных методов поиска ошибок в коде является отладка путем печати . Для этой цели Linux предоставляет встроенный в ядро API под названием printk () , который сохраняет сообщения в кольцевом буфере. Системный вызов syslog (2) используется для чтения и/или очистки кольцевого буфера сообщений ядра и для установки максимального уровня журнала сообщений, отправляемых на консоль (т. е. один из восьми параметров KERN_* функции printk()). , которые указывают на тяжесть сообщаемого состояния); обычно он вызывается через оболочку glibC klogctl(3) . [249] Сообщения ядра также экспортируются в пользовательскую среду через интерфейс /dev/kmsg [250] (например, systemd-journald [251] [252] читает этот интерфейс и по умолчанию добавляет сообщения в /var/log/journal ).
Еще один фундаментальный метод отладки работающего ядра — трассировка. Механизм ftrace — это внутренний трассировщик Linux; он используется для мониторинга и отладки Linux во время выполнения, а также может анализировать задержки в пользовательском пространстве из-за неправильного поведения ядра. [253] [254] [255] [256] Кроме того, ftrace позволяет пользователям отслеживать Linux во время загрузки. [257]
kprobes и kretprobes могут проникать (как отладчики в пользовательском пространстве) в Linux и собирать информацию без прерывания работы. [258] kprobes можно вставлять в код (почти) по любому адресу, а kretprobes работают при возврате функции. У зондов схожие цели, но они также имеют некоторые различия в использовании и реализации. [259]
С помощью KGDB Linux можно отлаживать почти так же, как и программы пользовательского пространства. Для KGDB требуется дополнительная машина, на которой работает GDB и которая подключена к цели для отладки с помощью последовательного кабеля или Ethernet . [260]
Проект ядра Linux постоянно интегрирует новый код. Программное обеспечение, включенное в проект, должно работать и компилироваться без ошибок. За каждой подсистемой ядра закреплен специалист по сопровождению, который отвечает за проверку исправлений на соответствие стандартам кода ядра и поддерживает очередь исправлений, которые могут быть отправлены Линусу Торвальдсу в течение нескольких недель. Патчи объединяются Торвальдсом с исходным кодом предыдущей стабильной версии ядра Linux, создавая кандидата на выпуск -rc для следующей стабильной версии ядра. После закрытия окна слияния принимаются только исправления нового кода в разрабатываемой версии. Разрабатываемая версия ядра -rc проходит регрессионные тесты , и как только Торвальдс и специалисты по поддержке подсистемы ядра признают ее стабильной, выпускается новое ядро Linux, и процесс разработки начинается заново. [261]
Разработчики, которые считают, что с ними обошлись несправедливо, могут сообщить об этом в Технический консультативный совет Linux Foundation . [262] В июле 2013 года разработчик драйвера USB 3.0 Сейдж Шарп попросил Торвальдса устранить оскорбительные комментарии в сообществе разработчиков ядра. В 2014 году Шарп отказался от разработки ядра Linux, заявив, что «ориентация на техническое совершенство в сочетании с перегруженностью специалистов по сопровождению и людьми с разными культурными и социальными нормами означает, что специалисты по сопровождению ядра Linux часто бывают резкими, грубыми или жестокими, чтобы получить их работа выполнена». [263] На конференции linux.conf.au (LCA) в 2018 году разработчики выразили мнение, что за последние несколько лет культура сообщества стала намного лучше. Дэниел Веттер, сопровождающий драйвера графического ядра Intel drm/i915, отметил, что «довольно жестокие выражения и дискуссии» в сообществе ядра уменьшились или исчезли. [264]
Лоран Пиншар попросил разработчиков поделиться своим опытом взаимодействия с сообществом ядра на Европейской конференции по встроенному Linux 2017 года. Поднятые вопросы были обсуждены несколько дней спустя на Саммите сопровождающих. Обеспокоенность по поводу отсутствия единообразия в том, как сопровождающие реагировали на исправления, представленные разработчиками, была поддержана Шуа Ханом, сопровождающим среды самотестирования ядра. Торвальдс утверждал, что никогда не будет единообразия в обработке исправлений, поскольку разные подсистемы ядра со временем применяли разные процессы разработки. Поэтому было решено, что каждый сопровождающий подсистемы ядра будет документировать правила принятия исправлений. [265]
Дерево Git Линуса Торвальдса , содержащее ядро Linux, называется основной веткой Linux . Каждый стабильный выпуск ядра создается из основного дерева [266] и часто публикуется на kernel.org . Mainline Linux имеет надежную поддержку лишь для небольшого подмножества многих устройств, работающих под управлением Linux. Неосновная поддержка обеспечивается независимыми проектами, такими как Yocto или Linaro , но во многих случаях необходимо ядро от поставщика устройства. [267] Для использования ядра поставщика, вероятно, потребуется пакет поддержки платы .
Поддержка дерева ядра за пределами основной версии Linux оказалась сложной задачей. [268]
Под основной веткой понимаются усилия по добавлению поддержки устройства в основную ветку ядра, [269] тогда как раньше поддержка поддерживалась только в ответвлении или вообще не поддерживалась. Обычно это включает добавление драйверов или файлов дерева устройств . Когда это будет завершено, функция или исправление безопасности будет считаться основным . [270]
Сопровождающий стабильной ветки Грег Кроа-Хартман применил термин « Linux-подобный» к последующим вилкам ядра от поставщиков, которые добавляют миллионы строк кода в основное ядро. [271] В 2019 году Google заявила, что хочет использовать основное ядро Linux в Android , чтобы сократить количество разветвлений ядра. [272] Термин «подобный Linux» также применяется к подмножеству встраиваемого ядра Linux , которое включает не полное основное ядро Linux, а небольшое модифицированное подмножество кода. [273]
Существуют определенные сообщества, которые разрабатывают ядра на основе официального Linux. Некоторые интересные фрагменты кода из этих ответвлений , в том числе Linux-libre , Compute Node Linux , INK , L4Linux , RTLinux и User-Mode Linux (UML), были объединены в основную ветку. [274] Некоторые операционные системы, разработанные для мобильных телефонов, изначально использовали сильно модифицированные версии Linux, включая Google Android , Firefox OS , HP webOS , Nokia Maemo и Jolla Sailfish OS . В 2010 году сообщество Linux раскритиковало Google за эффективное создание собственного дерева ядра: [275] [276]
Это означает, что любые драйверы, написанные для аппаратных платформ Android, не могут быть объединены с основным деревом ядра, поскольку они зависят от кода, который находится только в дереве ядра Google, что приводит к невозможности его сборки в дереве kernel.org. Из-за этого Google теперь предотвратил объединение большого количества аппаратных драйверов и кода платформы в основное дерево ядра. Эффективное создание ветки ядра, на которую сейчас полагаются несколько различных поставщиков. [277]
— Грег Кроа-Хартман , 2010 г.
Сегодня Android использует адаптированную версию Linux [278] , в которой основные изменения реализованы в драйверах устройств, но требуются некоторые изменения в основном коде ядра. Разработчики Android также предоставляют исправления для официального Linux, которые, наконец, могут загружать операционную систему Android. Например, Nexus 7 может загружать и запускать основной Linux. [278]
На презентации 2001 года в Музее компьютерной истории Линус Торвальдс сказал следующее в ответ на вопрос о дистрибутивах Linux, использующих точно такие же исходные коды ядра или нет:
Они не... ну, они есть, и это не так. Единого ядра нет. В каждом дистрибутиве есть свои изменения. Это продолжается практически с первого дня. Я не знаю, помните ли вы, что Yggdrasil был известен своими весьма радикальными изменениями в ядре, и даже сегодня у всех основных поставщиков есть свои собственные настройки, потому что у них есть определенная часть рынка, которая им интересна, и, откровенно говоря, именно так должен быть. Потому что, если все ожидают, что один человек, я, сможет отслеживать все, это не является целью GPL. Суть открытой системы не в этом. Так что на самом деле тот факт, что дистрибутив решает, что что-то настолько важно для них, что они будут добавлять патчи, даже если этого нет в стандартном ядре, это действительно хороший знак для меня. Вот, например, как было добавлено что-то вроде ReiserFS. И причина, по которой ReiserFS стала первой журналируемой файловой системой, интегрированной в стандартное ядро, заключалась не в том, что я люблю Ханса Райзера. Это произошло потому, что SUSE фактически начала поставлять ReiserFS в качестве стандартного ядра, и это сказало мне «хорошо». Это фактически используется в производстве. Нормальные люди так делают. Они, должно быть, знают что-то, чего я не знаю. Так что, по сути, то, что делают многие дистрибьюторские дома, они являются частью этого подхода «давайте создадим свой собственный филиал» и «давайте внесем в него свои изменения». А благодаря лицензии GPL я могу забрать лучшие из них. [279]
— Линус Торвальдс , 2001 г.
Между разработчиками ядра Linux произошло несколько заметных конфликтов. Примеры таких конфликтов:
Выдающиеся разработчики ядра Linux осознавали важность предотвращения конфликтов между разработчиками. [292] Долгое время не существовало кодекса поведения для разработчиков ядра из-за противодействия Линуса Торвальдса . [293] Однако 8 марта 2015 года был представлен Кодекс конфликтов ядра Linux. [294] 16 сентября 2018 года он был заменен новым Кодексом поведения, основанным на Соглашении участников . Это совпало с публичными извинениями Торвальдса и кратким перерывом в разработке ядра. [295] [296] 30 ноября 2018 года, в соответствии с Кодексом поведения , Яркко Саккинен из Intel разослал патчи, заменяющие слова «ебать», появляющиеся в комментариях к исходному коду, подходящими версиями, ориентированными на слово «обнимать». [297]
По состоянию на 2021 год [update]версия ядра Linux 5.11 содержала около 30,34 миллиона строк кода. Примерно 14% кода является частью «ядра» (каталоги Arch, Kernel и mm), а 60% — это драйверы.
Linux — это эволюция, а не разумный замысел!
— Линус Торвальдс , 2005 [298] [299] [300]
Стоимость переработки версии 2.6.0 ядра Linux в рамках традиционной проприетарной разработки оценивается в 612 миллионов долларов США (467 миллионов евро, 394 миллиона фунтов стерлингов) в ценах 2004 года с использованием модели оценки человеко-месяца COCOMO . [301] В 2006 году исследование, профинансированное Европейским Союзом, показало, что стоимость доработки ядра версии 2.6.8 выше и составила 882 миллиона евро (1,14 миллиарда долларов, 744 миллиона фунтов стерлингов). [302]
К этой теме вновь обратились в октябре 2008 года Аманда Макферсон, Брайан Проффитт и Рон Хейл-Эванс. Используя методологию Дэвида А. Уиллера, они подсчитали, что переработка ядра 2.6.25 теперь стоит 1,3 миллиарда долларов (часть от общей суммы в 10,8 миллиарда долларов, потраченной на переработку Fedora 9). [303] Опять же, Гарсия-Гарсия и Алонсо де Магдалено из Университета Овьедо (Испания) подсчитали, что стоимость, ежегодно добавляемая к ядру, составляла около 100 миллионов евро в период с 2005 по 2007 год и 225 миллионов евро в 2008 году, это также будет стоить более 1 миллиарда евро ( около $1,4 млрд по состоянию на февраль 2010 года) для развития в Европейском Союзе. [304]
По состоянию на 7 марта 2011 года [update], используя текущие на тот момент LOC (строки кода) ядра Linux 2.6.x и цифры заработной платы по расчетам Дэвида А. Уиллера, переработка ядра Linux будет стоить примерно 3 миллиарда долларов (около 2,2 миллиарда евро) как оно становится все больше. Обновленный расчет по состоянию на 26 сентября 2018 года [update]с использованием текущих на тот момент 20 088 609 LOC (строк кода) для ядра Linux 4.14.14 и текущей средней зарплаты программиста в США в 75 506 долларов показывает, что переписывание обойдется примерно в 14 725 449 000 долларов (11 191 341 000 фунтов стерлингов). существующий код. [305]
Последняя версия ядра и более старые версии ядра поддерживаются отдельно. Большинство последних выпусков ядра курировались Линусом Торвальдсом. [306]
Сообщество разработчиков ядра Linux поддерживает стабильное ядро, применяя исправления программных ошибок , обнаруженных во время разработки последующего стабильного ядра. Поэтому на сайте www.kernel.org всегда будут указаны два стабильных ядра. Следующее стабильное ядро Linux будет выпущено всего через 8–12 недель. Поэтому специалисты по поддержке ядра Linux обозначили некоторые стабильные выпуски ядра как долгосрочные . Эти ядра Linux с долгосрочной поддержкой обновляются с исправлениями ошибок в течение двух или более лет. [307] По состоянию на февраль 2022 года [update]существует шесть долгосрочных ядер Linux: 5.15.23, 5.10.100, 5.4.179, 4.19.229, 4.14.266 и 4.9.301. [308] Полный список выпусков можно найти в истории версий ядра Linux .
Большинство пользователей Linux используют ядро, входящее в их дистрибутив Linux . Некоторые дистрибутивы поставляют «ванильные» или «стабильные» ядра. Однако некоторые поставщики дистрибутивов Linux (например, Red Hat и Debian ) поддерживают другой набор ветвей ядра Linux, которые интегрированы в их продукты. Они обычно обновляются медленнее по сравнению с «ванильной» веткой и обычно включают все исправления из соответствующей «стабильной» ветки, но в то же время могут также добавлять поддержку драйверов или функций, которые не были выпущены в предыдущей версии. «ванильная» версия, на которой поставщик дистрибутива начал основывать свою ветку.
Первоначально Торвальдс выпустил Linux по лицензии, запрещавшей любое коммерческое использование. [309] В версии 0.12 это было изменено путем перехода на Стандартную общественную лицензию GNU версии 2 (GPLv2). [28] Эта лицензия разрешает распространение и продажу, возможно, модифицированных и немодифицированных версий Linux, но требует, чтобы все эти копии выпускались под одной и той же лицензией и сопровождались полным соответствующим исходным кодом или, по запросу, предоставлялся свободный доступ к нему. код. [310] Торвальдс назвал лицензирование Linux по лицензии GPLv2 «лучшим, что я когда-либо делал». [309]
Ядро Linux лицензируется только по GNU General Public License версии 2 (только GPL-2.0) с явным исключением системного вызова (Linux-syscall-note), [6] [9] [10] без предоставления лицензиату возможности выберите любую более позднюю версию, которая является распространенным расширением GPL. Предоставленный код должен быть доступен по лицензии, совместимой с GPL . [11] [105]
Были серьезные споры о том, насколько легко можно изменить лицензию для использования более поздних версий GPL (включая версию 3) и желательно ли это изменение вообще. [311] Сам Торвальдс при выпуске версии 2.4.0 специально указал, что его собственный код выпускается только под версией 2. [312] Однако условия GPL гласят, что если версия не указана, то можно использовать любую версию. , [313] и Алан Кокс отметили, что очень немногие другие участники Linux указали конкретную версию GPL. [314]
В сентябре 2006 года опрос 29 ключевых программистов ядра показал, что 28 из них предпочли GPLv2 действующему на тот момент проекту GPLv3. Торвальдс прокомментировал: «Я думаю, что многие посторонние… считали, что лично я был просто лишним человеком, потому что публично я не был большим поклонником GPLv3». [315] Эта группа известных разработчиков ядра, включая Торвальдса, Грега Кроа-Хартмана и Эндрю Мортона , прокомментировала в средствах массовой информации свои возражения против GPLv3. [316] Они ссылались на положения, касающиеся DRM / тивизации , патентов, «дополнительных ограничений» и предупреждали о балканизации «Вселенной с открытым исходным кодом» GPLv3. [316] [317] Линус Торвальдс, который решил не принимать GPLv3 для ядра Linux, повторил свою критику даже годы спустя. [318]
Спорным является вопрос о том, следует ли считать некоторые загружаемые модули ядра (LKM) производными произведениями в соответствии с законом об авторском праве и, следовательно, подпадают ли они под условия GPL.
В соответствии с правилами лицензии LKM, использующие только общедоступное подмножество интерфейсов ядра [130] [131], являются непроизводными произведениями, поэтому Linux предоставляет системным администраторам механизмы для загрузки двоичных объектов вне дерева в адресное пространство ядра. . [11]
Существуют некоторые загружаемые вне дерева модули, которые законно используют функцию ядра dma_buf . [319] Код, соответствующий GPL, безусловно, может его использовать. Однако другим возможным вариантом использования может быть Nvidia Optimus , который объединяет быстрый графический процессор со встроенным графическим процессором Intel, где графический процессор Nvidia записывает данные в кадровый буфер Intel , когда он активен. Но Nvidia не может использовать эту инфраструктуру, поскольку это требует обхода правила, которое может использоваться только LKM, которые также являются GPL. [132] Алан Кокс ответил на LKML , отклонив просьбу одного из их инженеров удалить это техническое требование из API. [320] Торвальдс четко заявил в LKML, что «[я] заявляю, что модули ядра, работающие только в двоичном формате, ЯВЛЯЮТСЯ производными «по умолчанию»». [321]
С другой стороны, Торвальдс также сказал, что «[одна] серая зона, в частности, представляет собой что-то вроде драйвера, который изначально был написан для другой операционной системы (т. е. явно не является производной версией Linux). ЭТО серая зона. , и _это_ та область, в которой я лично считаю, что некоторые модули можно считать не производными просто потому, что они не были разработаны для Linux и не зависят от какого-либо особого поведения Linux». [322] В частности, активно обсуждаются проприетарные графические драйверы.
Всякий раз, когда в Linux загружаются проприетарные модули, ядро помечает себя как «испорченное», [323] и поэтому отчеты об ошибках из испорченных ядер часто игнорируются разработчиками.
Официальное ядро, то есть ветка Linus git в репозитории kernel.org, содержит двоичные объекты, выпущенные в соответствии с условиями лицензии GNU GPLv2. [6] [11] Linux также может выполнять поиск в файловых системах в поисках двоичных объектов, проприетарной прошивки, драйверов или других исполняемых модулей, а затем загружать и связывать их в пространство ядра. [324]
Когда это необходимо (например, для доступа к загрузочным устройствам или для повышения скорости), прошивка может быть встроена в ядро, это означает встраивание прошивки в vmlinux ; однако это не всегда приемлемый вариант по техническим или юридическим вопросам (например, не разрешается делать это с прошивкой, не совместимой с GPL, хотя, тем не менее, это довольно распространено). [325]
Linux является зарегистрированной торговой маркой Линуса Торвальдса в США, Европейском Союзе и некоторых других странах. [326] [327] Судебная тяжба по поводу товарного знака началась в 1996 году, когда Уильям Делла Кроче, юрист, который никогда не участвовал в разработке Linux, начал требовать лицензионные сборы за использование слова Linux . После того, как было доказано, что это слово широко использовалось задолго до того, как Делла Кроче заявил о первом использовании, товарный знак был передан Торвальдсу. [328] [329] [330]
{{cite book}}
: CS1 maint: location missing publisher (link)