Ядро Linux — это свободное и открытое ядро , [12] : 4 UNIX-подобное ядро , которое используется во многих компьютерных системах по всему миру. Ядро было создано Линусом Торвальдсом в 1991 году и вскоре было принято в качестве ядра для операционной системы GNU (ОС), которая была создана как бесплатная замена Unix . С конца 1990-х годов оно было включено во многие дистрибутивы операционных систем , многие из которых называются Linux . Одной из таких операционных систем на основе ядра Linux является Android , которая используется во многих мобильных и встраиваемых устройствах.
Большая часть кода ядра написана на языке C , поддерживаемом коллекцией компиляторов GNU (GCC), которая имеет расширения за пределами стандартного C. [12] : 18 [13] Код также содержит ассемблерный код для логики, специфичной для архитектуры, такой как оптимизация использования памяти и выполнения задач. [12] : 379–380 Ядро имеет модульную конструкцию, так что модули могут быть интегрированы как программные компоненты – в том числе динамически загружаемые. Ядро является монолитным в архитектурном смысле, поскольку вся ОС работает в пространстве ядра .
Linux предоставляется по лицензии GNU General Public License версии 2 , хотя содержит файлы по другим совместимым лицензиям . [11]
В апреле 1991 года Линус Торвальдс, 21-летний студент факультета компьютерных наук Хельсинкского университета, начал работать над операционной системой для персонального компьютера, вдохновленной UNIX. [14] Он начал с переключателя задач на языке ассемблера Intel 80386 и драйвера терминала . [14] 25 августа 1991 года Торвальдс опубликовал следующее сообщение в comp.os.minix , группе новостей в Usenet : [15]
Я делаю (бесплатную) операционную систему (просто хобби, не будет большой и профессиональной, как gnu) для клонов AT 386(486) . Это назревало с апреля и начинает готовиться. Я хотел бы получить любые отзывы о том, что людям нравится/не нравится в minix, так как моя ОС чем-то похожа на нее (та же физическая структура файловой системы (по практическим причинам) среди прочего).
В настоящее время я портировал bash (1.08) и gcc (1.40), и, похоже, все работает. Это означает, что я получу что-то практичное в течение нескольких месяцев [...]
Да - она свободна от кода minix и имеет многопоточную файловую систему. Она НЕ переносимая [ sic ] (использует переключение задач 386 и т. д.), и она, вероятно, никогда не будет поддерживать ничего, кроме жестких дисков AT, поскольку это все, что у меня есть :-(.
17 сентября 1991 года Торвальдс подготовил версию 0.01 Linux и разместил ее на "ftp.funet.fi" – FTP-сервере Финской университетской и исследовательской сети ( FUNET ). Она даже не была исполняемой, поскольку ее код все еще нуждался в Minix для компиляции и тестирования. [16]
5 октября 1991 года Торвальдс анонсировал первую «официальную» версию Linux — версию 0.02. [17] [16]
[Как] я упоминал месяц назад, я работаю над бесплатной версией Minix-подобного для компьютеров AT-386. Он наконец-то достиг стадии, когда его можно использовать (хотя это может быть и не так, в зависимости от того, что вы хотите), и я готов выложить исходники для более широкого распространения. Это всего лишь версия 0.02... но я успешно запускал bash, gcc, gnu-make, gnu-sed, compress и т. д. под ним.
Linux быстро рос, так как многие разработчики, включая сообщество MINIX , вносили свой вклад в проект. [ необходима цитата ] В то время проект GNU завершил многие компоненты для своей бесплатной замены UNIX, GNU OS , но ее ядро, GNU Hurd , было незавершенным. Проект принял ядро Linux для своей ОС. [18]
Торвальдс обозначил ядро основной версией 0, чтобы указать, что оно еще не предназначено для общего использования. [19] Версия 0.11, выпущенная в декабре 1991 года, была первой версией, размещенной на собственном сервере ; она была скомпилирована на компьютере, работающем под управлением ядра Linux.
Когда Торвальдс выпустил версию 0.12 в феврале 1992 года, он принял GNU General Public License версии 2 (GPLv2) вместо своей предыдущей самостоятельно разработанной лицензии, которая не допускала коммерческого распространения. [20] В отличие от Unix , все исходные файлы Linux находятся в свободном доступе, включая драйверы устройств . [21]
Первоначальный успех Linux был обусловлен программистами и тестировщиками по всему миру. С поддержкой POSIX API, через libC, который, при необходимости, действует как точка входа в адресное пространство ядра, Linux мог запускать программное обеспечение и приложения, разработанные для Unix. [22]
19 января 1992 года был отправлен первый пост в новую группу новостей alt.os.linux . [23] 31 марта 1992 года группа новостей была переименована в comp.os.linux . [24]
Тот факт, что Linux является монолитным ядром, а не микроядром, был темой дебатов между Эндрю С. Таненбаумом , создателем MINIX, и Торвальдсом. [25] Дебаты Таненбаума –Торвальдса начались в 1992 году в группе Usenet comp.os.minix как общее обсуждение архитектур ядер. [26] [27]
Версия 0.95 была первой, способной запускать X Window System . [28] В марте 1994 года был выпущен Linux 1.0.0 с 176 250 строками кода. [29] Как указано в номере версии, это была первая версия, считавшаяся подходящей для производственной среды . [19] В июне 1996 года, после выпуска 1.3, Торвальдс решил, что Linux достаточно развился, чтобы оправдать новый основной номер, и поэтому обозначил следующий выпуск как версию 2.0.0. [30] [31] Важные особенности 2.0 включали симметричную многопроцессорность (SMP), поддержку большего количества типов процессоров и поддержку выбора определенных аппаратных целей, а также включение архитектурно-специфичных функций и оптимизаций. [22] Семейство команд make *config kbuild включает и настраивает параметры для сборки исполняемых файлов ядра ad hoc ( vmlinux ) и загружаемых модулей. [32] [33]
Версия 2.2, выпущенная 20 января 1999 года, [34] улучшила гранулярность блокировок и управление SMP, добавила поддержку m68k , PowerPC , Sparc64 , Alpha и других 64-битных платформ. [35] Кроме того, она добавила новые файловые системы , включая возможность чтения только NTFS от Microsoft . [35] В 1999 году IBM опубликовала свои исправления к коду Linux 2.2.13 для поддержки архитектуры S/390 . [36]
Версия 2.4.0, выпущенная 4 января 2001 года, [37] содержала поддержку ISA Plug and Play , USB и PC Cards . В Linux 2.4 была добавлена поддержка Pentium 4 и Itanium (последний представил ia64 ISA, который был совместно разработан Intel и Hewlett-Packard для замены старого PA-RISC ), а также для нового 64-битного процессора MIPS . [38] Разработка для 2.4. x немного изменилась, так как на протяжении всей серии стало доступно больше функций, включая поддержку Bluetooth , Logical Volume Manager (LVM) версии 1, поддержку RAID , файловых систем InterMezzo и ext3 .
Версия 2.6.0 была выпущена 17 декабря 2003 года. [39] Разработка версии 2.6. x продолжила развиваться в сторону включения новых функций во все части серии. Среди изменений, которые были сделаны в серии 2.6, следующие: интеграция μClinux в исходные тексты основного ядра, поддержка PAE , поддержка нескольких новых линеек процессоров , интеграция Advanced Linux Sound Architecture (ALSA) в исходные тексты основного ядра, поддержка до 232 пользователей (вместо 216 ) , поддержка до 229 идентификаторов процессов (только 64-разрядные, 32-разрядные архитектуры по-прежнему ограничены 215 ) , [40] существенно увеличено количество типов устройств и количество устройств каждого типа, улучшена поддержка 64-разрядных систем , поддержка файловых систем , которые поддерживают размеры файлов до 16 терабайт , внутриядерное вытеснение , поддержка Native POSIX Thread Library (NPTL), интеграция Linux пользовательского режима в исходные тексты основного ядра, интеграция SELinux в исходные тексты основного ядра, поддержка InfiniBand и многое другое.
Начиная с версий 2.6.x, ядро поддерживало большое количество файловых систем; некоторые из них были разработаны для Linux, например, ext3 , ext4 , FUSE , Btrfs , [41] а другие были родными для других операционных систем, например , JFS , XFS , Minix, Xenix , Irix , Solaris , System V , Windows и MS-DOS . [42]
Хотя до сих пор разработка не использовала систему контроля версий , в 2002 году разработчики Linux приняли BitKeeper , который был предоставлен им в свободном доступе, хотя и не был свободным программным обеспечением . В 2005 году из-за попыток его реверс-инжиниринга компания, которой принадлежало программное обеспечение, отозвала свою поддержку сообщества Linux. В ответ Торвальдс и другие написали Git . Новая система была написана в течение нескольких недель, а через два месяца было выпущено первое официальное ядро, созданное с его использованием. [43]
В 2005 году была сформирована стабильная команда в ответ на отсутствие дерева ядра, где люди могли бы работать над исправлением ошибок , и которая продолжала бы обновлять стабильные версии. [44] В феврале 2008 года было создано дерево linux-next, которое должно было служить местом, где собирались патчи, предназначенные для слияния в течение следующего цикла разработки. [45] [46] Несколько сопровождающих подсистем также приняли суффикс -next для деревьев, содержащих код, который они намеревались представить для включения в следующий цикл выпуска. По состоянию на январь 2014 года [обновлять]разрабатываемая версия Linux хранится в нестабильной ветке под названием linux-next . [47]
Двадцатилетие Linux Торвальдс отметил в июле 2011 года выпуском версии 3.0.0. [30] Поскольку номер версии 2.6 оставался таковым в течение 8 лет, в ядро пришлось добавить новую личность uname26 , которая сообщает о 3.x как о 2.6.40+x, чтобы старые программы работали. [48]
Версия 3.0 была выпущена 22 июля 2011 года. [49] 30 мая 2011 года Торвальдс объявил, что главным изменением было «НИЧЕГО. Абсолютно ничего». и попросил: «...давайте удостоверимся, что мы действительно сделаем следующий релиз не просто совершенно новым блестящим номером, но и хорошим ядром». [50] После ожидаемых 6–7 недель процесса разработки он был выпущен около 20-й годовщины Linux.
11 декабря 2012 года Торвальдс решил снизить сложность ядра, убрав поддержку процессоров i386 — в частности, не эмулируя [ 51] атомарную инструкцию CMPXCHG, представленную в i486 для обеспечения надежных мьютексов — что сделало серию ядер 3.7 последней, все еще поддерживающей оригинальный процессор. [52] [53] Эта же серия унифицирована для поддержки процессора ARM . [54]
Изменение нумерации с 2.6.39 на 3.0 и с 3.19 на 4.0 не подразумевало значимой технической дифференциации; основной номер версии был увеличен просто для того, чтобы избежать больших второстепенных номеров. [49] [55] Стабильные ядра 3.xy выпускались до версии 3.19 в феврале 2015 года. Версия 3.11, выпущенная 2 сентября 2013 года, [56] добавила много новых функций, таких как новый флаг O_TMPFILE для уменьшения уязвимостей временных файлов, экспериментальное динамическое управление питанием AMD Radeon , сетевой опрос с низкой задержкой и zswap (сжатый кэш подкачки). [57]
В апреле 2015 года Торвальдс выпустил ядро версии 4.0. [30] К февралю 2015 года в Linux внесли свой вклад около 12 000 программистов из более чем 1200 компаний, включая некоторых крупнейших мировых поставщиков программного обеспечения и оборудования. [58] Версия 4.1 Linux, выпущенная в июне 2015 года, содержит более 19,5 миллионов строк кода, внесённого почти 14 000 программистов. [59]
Линус Торвальдс объявил, что версия ядра 4.22 вместо этого будет иметь номер 5.0 в марте 2019 года, заявив, что «„5.0“ не означает ничего, кроме того, что числа 4.x начали становиться настолько большими, что у меня закончились пальцы на руках и ногах». [60] Он включал в себя множество важных дополнений, таких как поддержка дисплеев AMD Radeon FreeSync и NVIDIA Xavier, исправления для F2FS , EXT4 и XFS , восстановленную поддержку файлов подкачки в файловой системе Btrfs и продолжение работы над графикой Intel Icelake Gen11 и SoC NXP i.MX8 . [61] [62] Этот выпуск был заметно больше остальных, Торвальдс упомянул, что «общие изменения для всех выпусков 5.0 намного больше». [60]
В общей сложности 1991 разработчик, из которых 334 были новичками, добавили более 553 000 строк кода в версию 5.8, побив рекорд, установленный ранее версией 4.9. [63]
По данным ежегодного опроса разработчиков Stack Overflow за 2019 год, более 53% всех респондентов разрабатывали программное обеспечение для Linux и около 27% — для Android [64] , хотя только около 25% разрабатывают с использованием операционных систем на базе Linux. [65]
Большинство веб-сайтов работают на операционных системах на базе Linux , [66] [67] и все 500 самых мощных суперкомпьютеров мира используют ту или иную форму ОС на базе Linux. [68]
Дистрибутивы Linux объединяют ядро с системным программным обеспечением (например, библиотекой GNU C , systemd и другими утилитами и демонами Unix ), а также широким выбором прикладного программного обеспечения , но их доля использования на настольных компьютерах невелика по сравнению с другими операционными системами.
Поскольку Android , который является Linux, составляет большинство операционных систем мобильных устройств, [69] [70] [71] и из-за его растущего использования во встраиваемых устройствах , Android в значительной степени ответственен за рост использования Linux в целом. [22]
Стоимость повторной разработки версии 2.6.0 ядра Linux в традиционных условиях разработки с использованием собственной разработки оценивается в 612 миллионов долларов США (467 миллионов евро, 394 миллиона фунтов стерлингов) в ценах 2004 года с использованием модели оценки человеко-месяцев COCOMO . [72] В 2006 году исследование, финансируемое Европейским союзом, оценило стоимость повторной разработки версии ядра 2.6.8 выше — в 882 миллиона евро (1,14 миллиарда долларов, 744 миллиона фунтов стерлингов). [73]
Эта тема была повторно рассмотрена в октябре 2008 года Амандой Макферсон, Брайаном Проффиттом и Роном Хейл-Эвансом. Используя методологию Дэвида А. Уилера, они оценили, что переработка ядра 2.6.25 теперь стоит $1,3 млрд (часть из общей суммы $10,8 млрд на переработку Fedora 9). [74] Опять же, Гарсия-Гарсия и Алонсо де Магдалено из Университета Овьедо (Испания) оценивают, что стоимость, ежегодно добавляемая к ядру, составляла около €100 млн в период с 2005 по 2007 год и €225 млн в 2008 году, это также будет стоить более €1 млрд (около $1,4 млрд по состоянию на февраль 2010 года) для разработки в Европейском Союзе. [75]
По состоянию на 7 марта 2011 года [обновлять], используя текущие LOC (строки кода) ядра Linux 2.6.x и цифры заработной платы с расчетами Дэвида А. Уиллера, переработка ядра Linux обойдется примерно в 3 млрд долларов (около 2,2 млрд евро), поскольку оно продолжает расти. Обновленный расчет по состоянию на 26 сентября 2018 года [обновлять], используя текущие 20 088 609 LOC (строки кода) для ядра Linux 4.14.14 и текущую среднюю зарплату программиста в США в размере 75 506 долларов, показывает, что переписывание существующего кода обойдется примерно в 14 725 449 000 долларов (11 191 341 000 фунтов стерлингов). [76]
Большинство пользователей Linux делают это через дистрибутив Linux . Некоторые дистрибутивы поставляют ванильное или стабильное ядро. Однако несколько поставщиков (такие как Red Hat и Debian ) поддерживают настроенное дерево исходного кода. Они обычно обновляются медленнее, чем ванильная ветка, и обычно включают все исправления из соответствующей стабильной ветки, но в то же время они также могут добавлять поддержку драйверов или функций, которые не были выпущены в ванильную версию, с которой поставщик дистрибутива начал базировать свою ветку.
Сообщество разработчиков ядра 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%). [78]
Вместо дорожной карты есть технические руководства. Вместо центрального распределения ресурсов есть люди и компании, которые все заинтересованы в дальнейшей разработке ядра Linux, совершенно независимо друг от друга: Такие люди, как Линус Торвальдс и я, не планируют эволюцию ядра. Мы не сидим и не придумываем дорожную карту на следующие два года, а затем не выделяем ресурсы на различные новые функции. Это потому, что у нас нет никаких ресурсов. Все ресурсы принадлежат различным корпорациям, которые используют и вносят вклад в Linux, а также различным независимым участникам. Именно те люди, которые владеют ресурсами, решают...
— Эндрю Мортон , 2005
Известные конфликты среди разработчиков ядра Linux:
Известные разработчики ядра Linux осознают важность избегания конфликтов между разработчиками. [91] Долгое время не существовало кодекса поведения для разработчиков ядра из-за противодействия Торвальдса. [92] Однако 8 марта 2015 года был представлен Кодекс конфликта ядра Linux . [93] 16 сентября 2018 года он был заменен новым Кодексом поведения, основанным на Соглашении участников . Это совпало с публичными извинениями Торвальдса и кратким перерывом в разработке ядра. [94] [95] 30 ноября 2018 года, соблюдая Кодекс поведения , Яркко Саккинен из Intel разослал патчи, заменяющие случаи появления слова «fuck» в комментариях к исходному коду на подходящие версии, сосредоточенные на слове «hug». [96]
Разработчики, которые считают, что с ними обошлись несправедливо, могут сообщить об этом в Технический консультативный совет Linux Foundation . [97] В июле 2013 года разработчик драйвера USB 3.0 Сейдж Шарп попросил Торвальдса ответить на оскорбительные комментарии в сообществе разработчиков ядра. В 2014 году Шарп отказался от разработки ядра Linux, заявив, что «Упор на техническое совершенство в сочетании с перегруженными разработчиками и людьми с разными культурными и социальными нормами означает, что разработчики ядра Linux часто бывают резкими, грубыми или жестокими, чтобы выполнить свою работу». [98] На конференции linux.conf.au (LCA) в 2018 году разработчики выразили мнение, что культура сообщества значительно улучшилась за последние несколько лет. Дэниел Веттер, разработчик графического драйвера ядра Intel drm/i915, прокомментировал, что «довольно агрессивный язык и обсуждения» в сообществе разработчиков ядра уменьшились или исчезли. [99]
Лоран Пинчарт попросил разработчиков высказать свое мнение об их опыте работы с сообществом разработчиков ядра на конференции Embedded Linux Conference Europe 2017 года. Поднятые вопросы обсуждались несколько дней спустя на саммите мейнтейнеров. Опасения по поводу отсутствия последовательности в том, как мейнтейнеры реагируют на исправления, представленные разработчиками, были поддержаны Шуахом Ханом , мейнтейнером фреймворка самотестирования ядра. Торвальдс утверждал, что последовательности в обработке исправлений никогда не будет, поскольку разные подсистемы ядра со временем приняли разные процессы разработки. Поэтому было решено, что каждый мейнтейнер подсистемы ядра будет документировать правила принятия исправлений. [100]
Linux — это эволюция, а не разумный замысел !
- Линус Торвальдс, 2005 г. [101] [102] [103]
Исходный код ядра, также известный как исходное дерево, управляется в системе контроля версий Git , также созданной Торвальдсом. [104]
По состоянию на 2021 год [обновлять], версия 5.11 ядра Linux содержала около 30,34 млн строк кода. Примерно 14% кода является частью «ядра», включая архитектурно-специфический код, код ядра и код mm [ необходимо разъяснение ] , а 60% — это драйверы.
Вклады отправляются в виде патчей, в форме текстовых сообщений в списке рассылки ядра Linux (LKML) (а часто также в других списках рассылки, посвященных определенным подсистемам). Патчи должны соответствовать набору правил и формальному языку, который, среди прочего, описывает, какие строки кода должны быть удалены, а какие другие должны быть добавлены в указанные файлы. Эти патчи могут автоматически обрабатываться, чтобы системные администраторы могли применять их, чтобы внести лишь некоторые изменения в код или постепенно обновиться до следующей версии. [105] Linux также распространяется в форматах GNU zip (gzip) и bzip2 .
Разработчик, который хочет изменить ядро Linux, пишет и тестирует изменение кода. В зависимости от того, насколько значительным является изменение и сколько подсистем оно изменяет, изменение будет либо отправлено как один патч, либо в виде нескольких патчей исходного кода . В случае одной подсистемы, которая поддерживается одним сопровождающим, эти патчи отправляются в виде электронных писем сопровождающему подсистемы с соответствующим списком рассылки в Cc. Сопровождающий и читатели списка рассылки рассмотрят патчи и предоставят обратную связь. После завершения процесса проверки сопровождающий подсистемы принимает патчи в соответствующем дереве ядра Git . Если изменения в ядре Linux являются исправлениями ошибок, которые считаются достаточно важными, запрос на извлечение патчей будет отправлен Торвальдсу в течение нескольких дней. В противном случае запрос на извлечение будет отправлен Торвальдсу во время следующего окна слияния. Окно слияния обычно длится две недели и начинается сразу после выпуска предыдущей версии ядра. [106] В исходном дереве ядра Git все разработчики, внесшие вклад в ядро Linux, перечислены в каталоге Credits , а все сопровождающие подсистем перечислены в Maintainers . [107]
Как и во многих крупных проектах с открытым исходным кодом, разработчики обязаны придерживаться Соглашения участников — кодекса поведения , призванного бороться с притеснениями участников из числа меньшинств. [108] [109] Кроме того, для предотвращения правонарушений использование инклюзивной терминологии в исходном коде является обязательным. [110]
Linux написан на специальном языке программирования C , поддерживаемом GCC — компилятором, который расширяет стандарт C во многих отношениях, например, используя встроенные разделы кода, написанные на языке ассемблера (в синтаксисе GCC «AT&T-style») целевой архитектуры.
В сентябре 2021 года требования к версии GCC для компиляции и сборки ядра Linux были увеличены с GCC 4.9 до 5.1, что позволило потенциально перевести ядро с использования кода C на основе стандарта C89 на использование кода, написанного с использованием стандарта C11 [111] , при этом переход на стандарт состоится в марте 2022 года с выпуском Linux 5.18 [112] .
Первоначальная поддержка языка программирования Rust была добавлена в Linux 6.1 [5] , выпущенном в декабре 2022 года, [113] а более поздние версии ядра, такие как Linux 6.2 и Linux 6.3, еще больше улучшили поддержку. [114] [115]
С 2002 года код должен соответствовать 21 правилу, составляющим стиль кодирования ядра Linux. [116] [117]
Как и для большинства программ, версия ядра обозначается серией чисел, разделенных точками.
Для ранних версий версия состояла из трех или четырех разделенных точками номеров, которые назывались major release , minor release и revision. [12] : 9 В то время нечетные второстепенные релизы предназначались для разработки и тестирования, а четные второстепенные релизы — для производства. Необязательная четвертая цифра указывала уровень исправления. [19] Разрабатываемые релизы обозначались суффиксом релиз-кандидата ( -rc ).
Текущие соглашения о версиях отличаются. Нечетное/четное число, подразумевающее dev/prod, было удалено, и основная версия обозначается первыми двумя числами вместе. В то время как временные рамки открыты для разработки следующего основного выпуска, суффикс -rcN используется для обозначения n-го кандидата на релиз для следующей версии. [118] Например, выпуску версии 4.16 предшествовало семь 4.16-rcN (от -rc1 до -rc7). После выпуска стабильной версии ее поддержка передается стабильной команде . Обновления стабильной версии идентифицируются трехзначной схемой (например, 4.16.1, 4.16.2, ...). [118]
Ядро обычно собирается с помощью GNU toolchain . Компилятор GNU C, GNU cc, часть GNU Compiler Collection (GCC), является компилятором по умолчанию для основной ветки Linux. Последовательность обрабатывается GNU make . GNU Assembler (часто называемый GAS или GNU as) выводит объектные файлы из сгенерированного GCC ассемблерного кода. Наконец, GNU Linker (GNU ld) создает статически скомпонованный исполняемый файл ядра, называемый vmlinux . И as, и ld являются частью GNU Binary Utilities (binutils).
GNU cc долгое время был единственным компилятором, способным правильно собирать Linux. В 2004 году Intel заявила, что модифицировала ядро так, что ее компилятор C также был способен его компилировать. [119] Еще один такой успех был зарегистрирован в 2009 году с измененной версией 2.6.22. [120] [121] Поддержка компилятора Intel была прекращена в 2023 году. [122]
С 2010 года ведутся работы по сборке Linux с помощью Clang , альтернативного компилятора для языка C; [123] по состоянию на 12 апреля 2014 года официальное ядро почти могло быть скомпилировано Clang. [124] [125] Проект, посвященный этим работам, называется LLVMLinux в честь инфраструктуры компилятора LLVM , на которой построен Clang. [126] LLVMLinux не ставит своей целью создание ответвлений ни Linux, ни LLVM, поэтому это метапроект, состоящий из патчей, которые в конечном итоге отправляются в проекты upstream. Благодаря возможности компиляции Linux с помощью Clang разработчики могут выиграть от сокращения времени компиляции. [127]
В 2017 году разработчики завершили апстриминг патчей для поддержки сборки ядра Linux с Clang в выпуске 4.15, перенеся поддержку X86-64 и AArch64 в ветки 4.4, 4.9 и 4.14 стабильного дерева ядра. Pixel 2 от Google поставлялся с первым ядром Linux , собранным с помощью Clang , [128] хотя патчи для Pixel (1-го поколения) существовали. [129] В 2018 году ChromeOS перешла на сборку ядер с помощью Clang по умолчанию, [130] в то время как Android (операционная система) сделала Clang [131] и компоновщик LLD LLVM [ 132] обязательными для сборок ядер в 2019 году. Google перевела свое производственное ядро, используемое в ее центрах обработки данных, на сборку с помощью Clang в 2020 году. [133] Сегодня группа ClangBuiltLinux координирует исправления как для Linux, так и для LLVM для обеспечения совместимости, обе группы состоят из членов LLVMLinux и имеют обновленные исправления из LLVMLinux .
Как и в случае с любым программным обеспечением, проблемы с ядром Linux могут быть трудноразрешимыми . Распространенные проблемы связаны с доступом к пользовательскому пространству и пространству ядра, неправильным использованием примитивов синхронизации и неправильным управлением оборудованием. [12] : 364
Упс — это нефатальная ошибка в ядре. После такой ошибки операции продолжаются с подозрительной надежностью. [134]
Паника (сгенерированная panic() ) является фатальной ошибкой. После такой ошибки ядро выводит сообщение и останавливает компьютер. [12] : 371
Ядро обеспечивает отладку путем печати через printk () , который сохраняет сообщения в кольцевом буфере (перезаписывая старые записи новыми). Системный вызов syslog(2) обеспечивает чтение и очистку буфера сообщений и установку максимального уровня журнала сообщений, отправляемых на консоль. [135] Сообщения ядра также экспортируются в пользовательское пространство через интерфейс /dev/kmsg . [136]
Механизм ftrace позволяет выполнять отладку путем трассировки. Он используется для мониторинга и отладки Linux во время выполнения и может анализировать задержки пользовательского пространства из-за неправильного поведения ядра. [137] [138] [139] [140] Кроме того, ftrace позволяет пользователям трассировать Linux во время загрузки. [141]
kprobes и kretprobes могут вторгаться в выполнение ядра (как отладчики в пользовательском пространстве) и собирать информацию, не прерывая работу. [142] kprobes можно вставлять в код по (почти) любому адресу, в то время как kretprobes работают при возврате функции. uprobes имеют схожие цели, но они также имеют некоторые различия в использовании и реализации. [143]
С помощью KGDB Linux можно отлаживать практически так же, как и программы пользовательского пространства. Для KGDB требуется дополнительная машина, на которой работает GDB и которая подключена к отлаживаемой цели с помощью последовательного кабеля или Ethernet . [144]
Проект ядра Linux интегрирует новый код на постоянной основе. Стандартная рабочая процедура заключается в том, что программное обеспечение, добавленное в проект, должно работать и компилироваться без ошибок.
Каждой подсистеме ядра назначается ответственный за поддержку, который отвечает за проверку исправлений на соответствие стандартам кода ядра и ведение очереди исправлений, которые могут быть отправлены Торвальдсу в течение окна слияния, которое обычно составляет несколько недель.
Патчи объединяются Торвальдсом с исходным кодом предыдущего стабильного релиза ядра Linux, создавая релиз-кандидат (-rc) для следующего стабильного релиза. После закрытия окна слияния принимаются только исправления нового кода в разрабатываемом релизе. Разрабатываемый релиз -rc ядра проходит регрессионное тестирование , и как только Торвальдс и сопровождающие подсистемы считают его стабильным, выпускается новая версия, и процесс разработки начинается заново. [145]
Дерево Git, содержащее исходный код ядра Linux, называется mainline Linux . Каждый стабильный релиз ядра происходит из mainline дерева, [146] и часто публикуется на kernel.org . Mainline Linux имеет надежную поддержку только для небольшого подмножества множества устройств, работающих под управлением Linux. Поддержка non-mainline предоставляется независимыми проектами, такими как Yocto или Linaro , но во многих случаях требуется ядро от поставщика устройства. [147] Использование ядра поставщика, вероятно, потребует пакета поддержки платы .
Поддержание дерева ядра за пределами основной ветки Linux оказалось сложной задачей. [148]
Mainlining относится к усилиям по добавлению поддержки устройства в основное ядро, [149] в то время как раньше была только поддержка в форке или вообще не было поддержки. Обычно это включает добавление драйверов или файлов дерева устройств . Когда это завершено, функция или исправление безопасности считаются включенными в основное ядро . [150]
Ответственный за стабильную ветку Грег Кроа-Хартман применил термин «подобный Linux» к нисходящим форкам ядра, которые добавляют миллионы строк кода в основное ядро. [151] В 2019 году Google заявила, что хочет использовать основное ядро Linux в Android, чтобы сократить количество форков ядра. [152] Термин «подобный Linux» также применялся к Embeddable Linux Kernel Subset , который включает в себя не полное основное ядро Linux, а небольшое измененное подмножество кода. [153]
Существуют определенные сообщества, которые разрабатывают ядра на основе официального Linux. Некоторые интересные фрагменты кода из этих ответвлений , включая Linux-libre , Compute Node Linux , INK , L4Linux , RTLinux и User-Mode Linux (UML), были объединены в основную ветку. [154] Некоторые операционные системы, разработанные для мобильных телефонов, изначально использовали сильно модифицированные версии Linux, включая Google Android , Firefox OS , HP webOS , Nokia Maemo и Jolla Sailfish OS . В 2010 году сообщество Linux раскритиковало Google за то, что она фактически начала собственное дерево ядра: [155] [156]
Это означает, что любые драйверы, написанные для аппаратных платформ Android, не могут быть объединены в основное дерево ядра, поскольку они зависят от кода, который существует только в дереве ядра Google, что приводит к тому, что он не может быть собран в дереве kernel.org. Из-за этого Google теперь предотвратил объединение большого куска аппаратных драйверов и кода платформы в основное дерево ядра. Фактически создавая ветвь ядра, на которую теперь полагаются несколько различных поставщиков. [157]
— Грег Кроа-Хартман , 2010
Сегодня Android использует настроенный Linux [158] , где основные изменения реализованы в драйверах устройств, но требуются некоторые изменения в основном коде ядра. Разработчики Android также отправляют исправления в официальный Linux, которые наконец могут загружать операционную систему Android. Например, Nexus 7 может загружать и работать с основной версией Linux. [158]
На презентации в Музее компьютерной истории в 2001 году Торвальдс сказал следующее в ответ на вопрос о том, используют ли дистрибутивы Linux одни и те же исходные коды ядра или нет:
Они не... ну, они есть, и они не есть. Нет единого ядра. Каждый отдельный дистрибутив имеет свои собственные изменения. Это происходит практически с самого первого дня. Я не знаю, помните ли вы, что Yggdrasil был известен тем, что вносил довольно существенные изменения в ядро, и даже сегодня все основные поставщики имеют свои собственные настройки, потому что у них есть некоторая часть рынка, в которой они заинтересованы, и, честно говоря, так и должно быть. Потому что если все ожидают, что один человек, я, сможет отслеживать все, что не является смыслом GPL. Это не смысл открытой системы. Так что на самом деле тот факт, что дистрибутив решает, что что-то настолько важно для него, что он добавит исправления, даже если этого нет в стандартном ядре, это действительно хороший знак для меня. Так, например, как было добавлено что-то вроде ReiserFS. И причина, по которой ReiserFS стала первой журналируемой файловой системой, которая была интегрирована в стандартное ядро, заключалась не в том, что я люблю Ганса Райзера. Это произошло потому, что SUSE фактически начала поставлять ReiserFS в качестве своего стандартного ядра, что сказало мне «ок». Это на самом деле используется в производстве. Обычные люди делают это. Они должны знать что-то, чего не знаю я. Так что в самом реальном смысле то, что делают многие дистрибьюторские дома, они являются частью этого «давайте сделаем нашу собственную ветку» и «давайте внесем наши изменения в это». И благодаря GPL я могу взять лучшие части из них. [159]
— Линус Торвальдс , 2001
Последняя версия и более старые версии поддерживаются отдельно. Большинство последних выпусков ядра контролировались Торвальдсом. [160]
Сообщество разработчиков ядра Linux поддерживает стабильное ядро, применяя исправления ошибок программного обеспечения , обнаруженных в ходе разработки следующего стабильного ядра. Поэтому на сайте www.kernel.org всегда перечислены два стабильных ядра. Следующее стабильное ядро Linux выпускается примерно через 8–12 недель.
Некоторые релизы предназначены для долгосрочной поддержки с исправлением ошибок в течение двух или более лет. [ 161]
Несмотря на кажущуюся противоречивость, ядро Linux является как монолитным, так и модульным. Ядро классифицируется как монолитное ядро с точки зрения архитектуры, поскольку вся ОС работает в пространстве ядра. Конструкция является модульной, поскольку ее можно собирать из модулей , которые в некоторых случаях загружаются и выгружаются во время выполнения. [12] : 338 [162] Она поддерживает функции, которые когда-то были доступны только в закрытых исходных ядрах несвободных операционных систем.
В остальной части статьи используется соглашение UNIX и Unix-подобных операционных систем на страницах руководства . Число, следующее за именем команды, интерфейса или другой функции, указывает раздел (т. е. тип компонента или функции ОС), к которому она принадлежит. Например, execve(2) относится к системному вызову, а exec(3) относится к оболочке библиотеки пользовательского пространства.
Ниже приводится обзор архитектурного проекта и его примечательных особенностей.
Большинство драйверов устройств и расширений ядра работают в пространстве ядра ( кольцо 0 во многих архитектурах ЦП ) с полным доступом к оборудованию. Некоторые исключения работают в пространстве пользователя ; яркими примерами являются файловые системы на основе FUSE /CUSE и части UIO. [186] [187] Кроме того, X Window System и Wayland , оконная система и протоколы сервера отображения, которые большинство людей используют с Linux, не работают в ядре. Иными словами, фактическое взаимодействие с графическими процессорами графических карт осуществляется подсистемой ядра, называемой Direct Rendering Manager (DRM).
В отличие от стандартных монолитных ядер, драйверы устройств легко настраиваются как модули и загружаются или выгружаются во время работы системы, а также могут быть вытеснены при определенных условиях для правильной обработки аппаратных прерываний и лучшей поддержки симметричной многопроцессорной обработки . [169] По собственному желанию, Linux не имеет стабильного двоичного интерфейса приложения драйвера устройства . [188]
Linux обычно использует защиту памяти и виртуальную память , а также может обрабатывать неравномерный доступ к памяти , [189] однако проект вобрал в себя μClinux , который также позволяет запускать Linux на микроконтроллерах без виртуальной памяти. [190]
Аппаратное обеспечение представлено в файловой иерархии. Пользовательские приложения взаимодействуют с драйверами устройств через записи в каталогах /dev или /sys . [191] Информация о процессе отображается в каталоге /proc . [191]
Linux начинался как клон UNIX и нацелен на соответствие POSIX и Single UNIX Specification . [193] Ядро предоставляет системные вызовы и другие интерфейсы, специфичные для Linux. Чтобы быть включенным в официальное ядро, код должен соответствовать набору правил лицензирования. [6] [11]
Двоичный интерфейс приложений Linux (ABI) между ядром и пользовательским пространством имеет четыре степени стабильности (стабильный, тестируемый, устаревший, удаленный); [194] Системные вызовы , как ожидается, никогда не изменятся, чтобы сохранить совместимость для программ пользовательского пространства , которые полагаются на них. [195]
Загружаемые модули ядра (LKM) по своей природе не могут полагаться на стабильный ABI. [188] Поэтому их всегда необходимо перекомпилировать всякий раз, когда в системе устанавливается новый исполняемый файл ядра, в противном случае они не будут загружены. Драйверы в дереве, настроенные на то, чтобы стать неотъемлемой частью исполняемого файла ядра ( vmlinux ), статически связываются процессом сборки.
Нет гарантии стабильности API на уровне исходного кода ядра [188] и, из-за этого, код драйвера устройства , а также код любой другой подсистемы ядра, должен обновляться с эволюцией ядра. Любой разработчик, который вносит изменения в API, должен исправить любой код, который ломается в результате его изменений. [196]
Набор API ядра Linux , который касается интерфейсов, предоставляемых пользовательским приложениям, в основном состоит из системных вызовов, специфичных для UNIX и Linux . [197] Системный вызов является точкой входа в ядро Linux. [198] Например, среди системных вызовов, специфичных для Linux, есть семейство системных вызовов clone(2) . [199] Большинство расширений должны быть включены путем определения макроса в заголовочном файле или при компиляции кода пользовательского пространства. [200]_GNU_SOURCE
Системные вызовы могут быть вызваны только через инструкции сборки, которые позволяют перейти из непривилегированного пространства пользователя в привилегированное пространство ядра в кольце 0. По этой причине стандартная библиотека C (libC) действует как оболочка для большинства системных вызовов Linux, предоставляя функции C, которые при необходимости [201] прозрачно входят в ядро, которое будет выполняться от имени вызывающего процесса. [197] Для системных вызовов, не предоставляемых libC, таких как быстрый мьютекс пользовательского пространства , [202] библиотека предоставляет функцию syscall(2), которую можно использовать для их явного вызова. [203]
Псевдофайловые системы (например, файловые системы sysfs и procfs ) и специальные файлы (например, /dev/random
, /dev/sda
, /dev/tty
, и многие другие) составляют еще один уровень интерфейса к структурам данных ядра, представляющим аппаратные или логические (программные) устройства. [204] [205]
Из-за различий, существующих между сотнями различных реализаций ОС Linux, исполняемые объекты, даже если они скомпилированы, собраны и скомпонованы для запуска на определенной аппаратной архитектуре (то есть они используют ISA целевого оборудования), часто не могут работать на разных дистрибутивах Linux. Эта проблема в основном связана с конфигурациями, специфичными для дистрибутивов, и набором исправлений, примененных к коду ядра Linux, различиями в системных библиотеках, службах (демонах), иерархиях файловых систем и переменных окружения.
Основным стандартом, касающимся приложений и двоичной совместимости дистрибутивов Linux, является Linux Standard Base (LSB). [206] [207] Однако LSB выходит за рамки того, что касается ядра Linux, поскольку он также определяет спецификации рабочего стола, библиотеки X и Qt, которые имеют мало общего с ним. [208] LSB версии 5 построен на нескольких стандартах и проектах (POSIX, SUS, X/Open, File System Hierarchy (FHS) и других). [209]
Части LSB, более относящиеся к ядру, — это General ABI (gABI), [210] особенно System V ABI [211] [212] и Executable and Linking Format (ELF), [213] [214] и Processor Specific ABI (psABI), например, Core Specification для X86-64. [215] [216]
Стандартный ABI для того, как пользовательские программы x86_64 вызывают системные вызовы, заключается в загрузке номера системного вызова в регистр rax , а других параметров в rdi , rsi , rdx , r10 , r8 и r9 , и, наконец, в помещении инструкции ассемблера системного вызова в код. [217] [218] [219]
Существует несколько внутренних API ядра между подсистемами ядра. Некоторые из них доступны только внутри подсистем ядра, в то время как несколько ограниченный набор символов ядра (т. е. переменных, структур данных и функций) доступен динамически загружаемым модулям (например, драйверам устройств, загружаемым по требованию), независимо от того, экспортируются ли они с помощью макросов EXPORT_SYMBOL() и EXPORT_SYMBOL_GPL() [221] [222] (последний зарезервирован для модулей, выпущенных по лицензии, совместимой с GPL). [223]
Linux предоставляет API-интерфейсы ядра, которые манипулируют структурами данных (например, связанными списками , базисными деревьями , [224] красно-черными деревьями , [225] очередями ) или выполняют общие процедуры (например, копируют данные из пользовательского пространства и в него, выделяют память, печатают строки в системный журнал и т. д.), которые остаются стабильными по крайней мере с версии Linux 2.6. [226] [227] [228]
Встроенные в ядро API включают библиотеки низкоуровневых общих служб, используемых драйверами устройств:
Разработчики Linux решили не поддерживать стабильный внутриядерный ABI. Модули, скомпилированные для определенной версии ядра, не могут быть загружены в другую версию без перекомпиляции. [188]
Linux создает процессы посредством системных вызовов clone(2) или более нового clone3(2) [238] . Эти системные вызовы создают новые сущности, начиная от новых независимых процессов (каждый из которых имеет специальный идентификатор TGID в структуре данных task_struct в пространстве ядра, хотя тот же идентификатор называется PID в пространстве пользователя), и заканчивая новыми потоками в вызывающем процессе. [239] [240]
Если исполняемый файл динамически связан с общими библиотеками, то динамический компоновщик используется для поиска и загрузки необходимых объектов, подготовки программы к запуску и последующего ее запуска. [241]
Собственная библиотека потоков POSIX (NPTL) [242] предоставляет стандартный интерфейс потоков POSIX ( pthreads ) для пользовательского пространства.
Ядро предоставляет механизмы futex(7) (быстрый мьютекс пользовательского пространства) для блокировки и синхронизации пользовательского пространства. [243] Большинство операций выполняются в пользовательском пространстве, но может потребоваться взаимодействие с ядром с помощью системного вызова futex(2) . [202]
В отличие от потоков пользовательского пространства, описанных выше, потоки ядра работают в пространстве ядра. [244]
Планировщик процессов Linux является модульным в том смысле, что он позволяет использовать различные классы и политики планирования. [245] [246] Классы планировщиков — это подключаемые алгоритмы планировщиков, которые можно зарегистрировать с помощью базового кода планировщика. Каждый класс планирует различные типы процессов. Основной код планировщика выполняет итерации по каждому классу в порядке приоритета и выбирает планировщик с наивысшим приоритетом, у которого есть готовая к запуску планируемая сущность типа struct sched_entity. [12] : 46–47 Сущности могут быть потоками, группами потоков и даже всеми процессами определенного пользователя.
Linux обеспечивает как пользовательское вытеснение , так и полное вытеснение ядра . [12] : 62–63 Вытеснение уменьшает задержку , увеличивает скорость отклика [247] и делает Linux более подходящим для настольных приложений и приложений реального времени .
Для обычных задач ядро по умолчанию использует класс Completely Fair Scheduler (CFS), представленный в версии 2.6.23. [171] Планировщик определяется как макрос в заголовке C как SCHED_NORMAL
. В других ядрах POSIX похожая политика, известная как SCHED_OTHER
выделяет кванты времени ЦП (т. е. назначает абсолютные кванты времени процессора в зависимости от предопределенного или динамически вычисляемого приоритета каждого процесса). Linux CFS устраняет абсолютные кванты времени и назначает справедливую долю времени ЦП в зависимости от таких параметров, как общее количество запущенных процессов и время, которое они уже выполнили; эта функция также учитывает своего рода вес, который зависит от их относительных приоритетов (хорошие значения). [12] : 46–50
С помощью пользовательского вытеснения планировщик ядра может заменить текущий процесс выполнением переключения контекста на другой, который, таким образом, получает вычислительные ресурсы для выполнения (ЦП, память и т. д.). Он делает это в соответствии с алгоритмом CFS (в частности, он использует переменную vruntime для сортировки сущностей, а затем выбирает ту, которая имеет меньшее vruntime, - т. е. планируемую сущность, которая имела наименьшую долю времени ЦП), с активной политикой планировщика и с относительными приоритетами. [248] С помощью вытеснения ядра ядро может вытеснять себя, когда возвращается обработчик прерываний, когда блокируются задачи ядра и когда подсистема явно вызывает функцию schedule().
Ядро также содержит два класса планирования в реальном времени, соответствующих POSIX [249],SCHED_FIFO
которые называются (realtime first-in-first-out ) и SCHED_RR
(realtime round-robin ), оба из которых имеют приоритет над классом по умолчанию. [245] Дополнительная политика планирования, известная как SCHED DEADLINE
, реализующая алгоритм «первым пришел самый ранний крайний срок» (EDF), была добавлена в версию ядра 3.14, выпущенную 30 марта 2014 года. [250] [251] SCHED_DEADLINE
имеет приоритет над всеми другими классами планирования.
Исправления в реальном времени PREEMPT_RT
, включённые в основную ветку Linux, начиная с версии 2.6, обеспечивают детерминированный планировщик , удаление приоритета и отключения прерываний (где это возможно), PI Mutex (т. е. блокирующие примитивы, которые избегают инверсии приоритетов), [252] [253] поддержку высокоточных таймеров событий (HPET), приоритетного чтения-копирования-обновления (RCU), (принудительных) потоков IRQ и других второстепенных функций. [254] [255] [256]
В 2023 году Питер Зейлстра предложил заменить CFS на планировщик EEVDF ( ранний подходящий виртуальный крайний срок первого планирования ) [257] [258] , чтобы предотвратить необходимость исправлений CFS «latency nice». [259] Планировщик EEVDF заменил CFS в версии 6.6 ядра Linux. [260]
Ядро имеет различные причины параллелизма (например, прерывания, нижние половины, вытеснение задач ядра и пользователей, симметричная многопроцессорная обработка). [12] : 167
Для защиты критических областей (разделов кода, которые должны выполняться атомарно), разделяемых областей памяти (таких как глобальные переменные и другие структуры данных с глобальной областью действия) и областей памяти, которые асинхронно изменяются аппаратным обеспечением (например, имеющих квалификатор типа C ), Linux предоставляет большой набор инструментов. Они состоят из атомарных типов (которые могут быть изменены только набором определенных операторов), спин-блокировок , семафоров , мьютексов , [261] [12] : 176–198 [262] и алгоритмов без блокировок (например, RCU ). [263] [264] [265] Большинство алгоритмов без блокировок построены поверх барьеров памяти с целью обеспечения порядка памяти и предотвращения нежелательных побочных эффектов из-за оптимизации компилятора . [266] [267] [268] [269]volatile
PREEMPT_RT
Код, включенный в основную линейку Linux, предоставляет RT-мьютексы , особый вид мьютексов, которые не отключают приоритетное прерывание и поддерживают наследование приоритетов. [270] [271] Почти все блокировки преобразуются в спящие блокировки при использовании конфигурации для работы в реальном времени. [272] [256] [271] Наследование приоритетов позволяет избежать инверсии приоритетов, предоставляя низкоприоритетной задаче, которая удерживает спорную блокировку, приоритет ожидающего с более высоким приоритетом до тех пор, пока эта блокировка не будет снята. [273] [274]
Linux включает в себя валидатор блокировки ядра, называемый Lockdep . [275] [276]
Хотя управление прерываниями можно рассматривать как одну задачу, оно разделено на две части. Это разделение на две части обусловлено различными временными ограничениями и потребностями в синхронизации задач, из которых состоит управление. Первая часть состоит из асинхронной процедуры обслуживания прерываний , которая в Linux известна как верхняя половина , в то время как вторая часть выполняется одним из трех типов так называемых нижних половин ( softirq , tasklets и work queues ). [12] : 133–137
Подпрограммы обслуживания прерываний Linux могут быть вложенными. Новый IRQ может попасть в высокоприоритетный ISR, который вытесняет любой другой ISR с более низким приоритетом.
Linux реализует виртуальную память с пятиуровневыми таблицами страниц . [277] Ядро не является страничным (то есть оно всегда находится в физической памяти и не может быть выгружено на диск), и нет защиты памяти (нет сигналов SIGSEGV , в отличие от пользовательского пространства), поэтому нарушения памяти приводят к нестабильности и сбоям системы. [12] : 20 Пользовательская память по умолчанию является страничной, хотя страничное хранение для определенных областей памяти можно отключить с помощью семейства mlock()
системных вызовов .
Информация о кадре страницы хранится в соответствующих структурах данных (типа struct page ), которые заполняются сразу после загрузки и сохраняются до выключения, независимо от того, связаны ли они с виртуальными страницами. Физическое адресное пространство разделено на различные зоны в соответствии с архитектурными ограничениями и предполагаемым использованием. Также поддерживаются системы NUMA с несколькими банками памяти. [278]
Небольшие фрагменты памяти могут динамически выделяться в пространстве ядра с помощью семейства kmalloc()
API и освобождаться с помощью соответствующего варианта kfree()
. vmalloc()
и kvfree()
используются для больших виртуально непрерывных фрагментов. alloc_pages()
выделяет желаемое количество целых страниц.
Ядро использовало для включения распределителей SLAB, SLUB и SLOB в качестве настраиваемых альтернатив. [280] [281] Распределитель SLOB был удален в Linux 6.4 [282] , а распределитель SLAB был удален в Linux 6.8. [283] Единственным оставшимся распределителем является SLUB, который нацелен на простоту и эффективность, [281] совместим [284] и был представлен в Linux 2.6.PREEMPT_RT
Хотя изначально Linux не был разработан как переносимый , [15] [285] Linux в настоящее время является одним из наиболее широко переносимых ядер операционных систем, работающих на самых разных системах от архитектуры ARM до мэйнфреймов IBM z/Architecture . Первый перенос был выполнен на платформе Motorola 68000. Изменения в ядре были настолько фундаментальными, что Торвальдс рассматривал версию Motorola как ответвление и «операционную систему типа Linux». [285] Однако это побудило Торвальдса возглавить серьезную реструктуризацию кода для облегчения переноса на большее количество вычислительных архитектур. Первый Linux, который в едином исходном дереве имел код для более чем i386, поддерживал 64-битную платформу DEC Alpha AXP . [286] [287] [285]
Linux работает в качестве основной операционной системы на IBM Summit ; по состоянию на октябрь 2019 года все 500 самых быстрых суперкомпьютеров[обновлять] мира работают под управлением той или иной операционной системы на основе ядра Linux, [288] что является большим изменением по сравнению с 1998 годом, когда в список был добавлен первый суперкомпьютер Linux. [289]
Linux также был портирован на различные портативные устройства, такие как iPhone 3G и iPod от Apple . [290]
В 2007 году был запущен проект LKDDb для создания всеобъемлющей базы данных оборудования и протоколов, известных ядрам Linux. [291] База данных создается автоматически путем статического анализа исходных кодов ядра. Позже в 2014 году был запущен проект Linux Hardware для автоматического сбора базы данных всех протестированных конфигураций оборудования с помощью пользователей различных дистрибутивов Linux. [292]
Обновления без перезагрузки можно применять к ядру даже с помощью технологий live patching , таких как Ksplice , kpatch и kGraft . Минималистичные основы для live kernel patching были объединены в основную ветку ядра Linux в версии ядра 4.0, которая была выпущена 12 апреля 2015 года. Эти основы, известные как livepatch и основанные в первую очередь на функциональности ядра ftrace , образуют общее ядро, способное поддерживать hot patching как kGraft, так и kpatch, предоставляя интерфейс прикладного программирования (API) для модулей ядра, содержащих hot patching, и прикладной двоичный интерфейс (ABI) для утилит управления пользовательским пространством. Однако общее ядро, включенное в ядро Linux 4.0, поддерживает только архитектуру x86 и не предоставляет никаких механизмов для обеспечения согласованности на уровне функций во время применения hot patching. По состоянию на апрель 2015 года [update]ведется работа по переносу kpatch и kGraft в общее live patching ядро, предоставляемое основной веткой ядра Linux. [293] [294] [295]
Ошибки ядра представляют потенциальные проблемы безопасности. Например, они могут допускать повышение привилегий или создавать векторы атак типа «отказ в обслуживании» . За эти годы были найдены и исправлены многочисленные ошибки, влияющие на безопасность системы. [296] Новые функции часто внедряются для улучшения безопасности ядра. [297] [298]
Capabilities(7) уже были представлены в разделе о процессах и потоках. Android использует их, а systemd предоставляет администраторам подробный контроль над возможностями процессов. [299]
Linux предлагает множество механизмов для уменьшения поверхности атаки ядра и повышения безопасности, которые в совокупности известны как модули безопасности Linux (LSM). [300] Они включают модуль Security-Enhanced Linux (SELinux), код которого был изначально разработан и затем опубликован АНБ , [ 301] и AppArmor [185] среди прочих. SELinux в настоящее время активно разрабатывается и поддерживается на GitHub . [184] SELinux и AppArmor обеспечивают поддержку политик безопасности контроля доступа, включая обязательный контроль доступа (MAC), хотя они существенно различаются по сложности и области применения.
Еще одной функцией безопасности является Seccomp BPF (SECure COMPuting with Berkeley Packet Filters), которая работает путем фильтрации параметров и сокращения набора системных вызовов, доступных для пользовательских приложений. [302]
Критики обвиняли разработчиков ядра в сокрытии уязвимостей безопасности или, по крайней мере, в необъявлении о них; в 2008 году Торвальдс ответил на это следующим образом: [303] [304]
Лично я считаю, что ошибки безопасности — это просто «обычные ошибки». Я их не скрываю, но у меня также нет никаких причин думать, что отслеживать их и объявлять о них как о чем-то особенном — это хорошая идея... одна из причин, по которой я отказываюсь беспокоиться обо всем этом цирке с безопасностью, заключается в том, что, по моему мнению, он прославляет — и, таким образом, поощряет — неправильное поведение. Он делает из специалистов по безопасности «героев», как будто люди, которые не просто исправляют обычные ошибки, не так важны. На самом деле, все скучные обычные ошибки гораздо важнее, просто потому, что их [sic] гораздо больше. Я не думаю, что какую-то впечатляющую дыру в безопасности следует прославлять или беспокоиться о ней как о чем-то более «особенном», чем случайный впечатляющий сбой из-за плохой блокировки.
Дистрибутивы Linux обычно выпускают обновления безопасности для исправления уязвимостей в ядре Linux. Многие предлагают долгосрочные релизы поддержки, которые получают обновления безопасности для определенной версии ядра Linux в течение длительного периода времени.
Первоначально Торвальдс выпустил Linux под лицензией, которая запрещала любое коммерческое использование. [305] Это было изменено в версии 0.12 путем перехода на GNU General Public License версии 2 (GPLv2). [20] Эта лицензия позволяет распространять и продавать возможно модифицированные и немодифицированные версии Linux, но требует, чтобы все эти копии были выпущены под той же лицензией и сопровождались — или чтобы по запросу предоставлялся свободный доступ — полным соответствующим исходным кодом. [306] Торвальдс описал лицензирование Linux под GPLv2 как «лучшее, что я когда-либо делал». [305]
Ядро Linux лицензируется явно по GNU General Public License версии 2 (GPL-2.0-only) с явным исключением системных вызовов (Linux-syscall-note), [6] [9] [10] без предоставления лицензиату возможности выбора любой более поздней версии, что является общим расширением GPL. Внесенный код должен быть доступен по лицензии, совместимой с GPL . [11] [196]
Существовали значительные дебаты о том, насколько легко можно изменить лицензию для использования более поздних версий GPL (включая версию 3), и желательно ли вообще это изменение. [307] Сам Торвальдс при выпуске версии 2.4.0 специально указал, что его собственный код выпускается только под версией 2. [308] Однако условия GPL гласят, что если версия не указана, то может использоваться любая версия, [309] и Алан Кокс указал, что очень немногие другие участники Linux указали определенную версию GPL. [310]
В сентябре 2006 года опрос 29 ключевых программистов ядра показал, что 28 из них предпочли GPLv2 актуальному на тот момент проекту GPLv3. Торвальдс прокомментировал: «Я думаю, что ряд посторонних... считали, что я лично был просто лишним, потому что я публично не был большим поклонником GPLv3». [311] Эта группа известных разработчиков ядра, включая Торвальдса, Грега Кроа-Хартмана и Эндрю Мортона , прокомментировала в СМИ свои возражения против GPLv3. [312] Они ссылались на положения, касающиеся DRM / тивоизации , патентов, «дополнительных ограничений» и предупреждали о балканизации «Вселенной с открытым исходным кодом» из-за GPLv3. [312] [313] Торвальдс, который решил не принимать GPLv3 для ядра Linux, повторил свою критику даже годы спустя. [314]
Ведутся споры о том, следует ли считать некоторые загружаемые модули ядра (LKM) производными работами в соответствии с законодательством об авторском праве и, следовательно, подпадают ли они под условия GPL.
В соответствии с правилами лицензии, LKM, использующие только общедоступное подмножество интерфейсов ядра [221] [222], не являются производными работами, поэтому Linux предоставляет системным администраторам механизмы для загрузки двоичных объектов вне дерева в адресное пространство ядра. [11]
Есть некоторые загружаемые модули out-of-tree, которые законно используют функцию ядра dma_buf . [315] Код, совместимый с GPL, безусловно, может ее использовать. Однако другим возможным вариантом использования будет Nvidia Optimus , который объединяет быстрый графический процессор с интегрированным графическим процессором Intel, где графический процессор Nvidia записывает в кадровый буфер Intel , когда он активен. Но Nvidia не может использовать эту инфраструктуру, поскольку это требует обхода правила, которое может использоваться только LKM, которые также являются GPL. [223] Алан Кокс ответил на LKML , отклонив запрос одного из инженеров Nvidia на удаление этого технического принуждения из API. [316] Торвальдс четко заявил на LKML, что «[я] утверждаю, что двоичные модули ядра ЯВЛЯЮТСЯ производными «по умолчанию»». [317]
С другой стороны, Торвальдс также сказал, что «[одна] серая зона в частности — это что-то вроде драйвера, который изначально был написан для другой операционной системы (т.е., явно не производная работа Linux по происхождению). ЭТО серая зона, и _это_ область, где, как я лично считаю, некоторые модули могут считаться не производными работами просто потому, что они не были разработаны для Linux и не зависят от какого-либо особого поведения Linux». [318] В частности, активно обсуждаются проприетарные графические драйверы.
Всякий раз, когда в Linux загружаются проприетарные модули, ядро помечает себя как «испорченное» [319] , и поэтому сообщения об ошибках в испорченных ядрах часто игнорируются разработчиками.
Официальное ядро, то есть ветвь git Linus в репозитории kernel.org, содержит двоичные файлы, выпущенные в соответствии с условиями лицензии GNU GPLv2. [6] [11] Linux также может выполнять поиск в файловых системах для обнаружения двоичных файлов, фирменных прошивок, драйверов или других исполняемых модулей, а затем загружать и связывать их с пространством ядра. [320]
При необходимости (например, для доступа к загрузочным устройствам или для повышения скорости) встроенное ПО может быть встроено в ядро, что означает встраивание встроенного ПО в vmlinux ; однако это не всегда приемлемый вариант из-за технических или юридических проблем (например, это не разрешается делать с встроенным ПО, несовместимым с GPL, хотя это, тем не менее, довольно распространено). [321]
Linux — зарегистрированная торговая марка Линуса Торвальдса в США, Европейском союзе и некоторых других странах. [322] [323] Судебная тяжба за торговую марку началась в 1996 году, когда Уильям Делла Кроче, юрист, никогда не участвовавший в разработке Linux, начал требовать лицензионные сборы за использование слова Linux . После того, как было доказано, что слово было общеупотребительным задолго до заявленного Делла Кроче первого использования, торговая марка была присуждена Торвальдсу. [324] [325] [326]
В октябре 2024 года Грег Кроа-Хартман удалил имена россиян из MAINTAINERS
файла, сохранив при этом код указанных подсистем. Это удаление было поддержано Торвальдсом. [327]