Как собрать ядро linux под windows

Технический прогресс не стоит на месте, появляются новые компьютерные архитектуры, компиляторы становятся умнее и генерируют более быстрый машинный код. Соврем...

Технический прогресс не стоит на месте, появляются новые компьютерные архитектуры, компиляторы становятся умнее и генерируют более быстрый машинный код. Современные задачи требуют все более креативного и эффективного решения. В данной статье пойдет речь, на мой взгляд, про один из самых прогрессивных тулчейнов LLVM и компиляторы на его основе Clang и Clang++, для языков программирования С и C++ соответственно. Хоть GCC — конкурент Clang, может агрессивнее оптимизировать циклы и рекурсию, Clang дает на выходе более корректный машинный код, и чаще всего не ломает поведение приложений. Плюс оптимизация программ не заканчивается только оптимизацией циклов, поэтому Clang местами дает лучшую производительность. В GCC же за счет переоптимизации вероятность получить unpredictable behavior значительно выше. По этой причине на многих ресурсах не рекомендуют использовать -O3 и LTO(Link Time Optimization) оптимизации для сборки программ. Плюс в случае агрессивной оптимизации, размер исполняемых файлов может сильно увеличиться и программы на практике будут работать даже медленнее. Поэтому мы остановились на Clang не просто так и опции компиляции -O3 и LTO работают в нем более корректно. Плюс современные компиляторы более зрелые, и сейчас уже нет тех детских болячек переоптимизации и LTO.

Что меня побудило написать эту статью? — В первую очередь это несколько фактов:

  1. Впервые прочел про сборку ядра Linux с LTO оптимизацией и Clang из новостей, где упоминалась компания Google. Она использует Clang и LTO оптимизацию для сборки ядра Linux и получения лучшей производительности. Компания Google для меня является синонимом инноваций, лучших программистов в мире и поэтому для меня ее опыт является самым авторитетным. Плюс она привнесла очень много в развитие open source, и ее наработками пользуются тысячи компаний во всем мире.
  2. Хоть компания Google начала использовать Clang и LTO оптимизацию раньше, только с выходом ядра Linux 5.12.6 и 5.12.7 было закрыто большое количество багов, и сборка ядра c LTO оптимизаций стала доступна многим. До этого при сборке ядра с LTO оптимизацией многие драйвера давали сбой.
  3. Мною уже протестирована работа ядра с LTO на Ryzen 9 3900x + AMD Radeon 5700 XT. Плюс уже давно использую LLVM 12 и Clang для сборки системных программ. Инструментарий LLVM12 и Clang стали основными в моей системе по причине лучшей поддержки моего процессора и нужные мне программы работают быстрее при сборке с помощью Clang. Для программистов Clang дает лучший контроль ошибок, оптимизации и unpredictable behavior. -fdebug-macro, -fsanitize=address, -fsanitize=memory, -fsanitize=undefined, -fsanitize=thread, -fsanitize=cfi, -fstack-protector, -fstack-protector-strong, -fstack-protector-all, -Rpass=inline, -Rpass=unroll, -Rpass=loop-vectorize, -Rpass-missed=loop-vectorize, -Rpass-analysis=loop-vectorize и т.д.
  4. Данная возможность толком нигде не была описана в связи с п.2 и есть подводные моменты, которые будут рассмотрены в данной статье.

В этой статье будет описана сборка ядра Linux 5.12.12 c LLVM 12 + Clang и LTO оптимизацией. Но так как статья получилась бы короткой, то так же бонусом будет рассмотрен вопрос как сделать утилиты LLVM 12 и Clang сборочным инструментарием по умолчанию, и какие программы и библиотеки имеет смысл собрать вручную, чтобы получить лучший отклик и производительность от системы. GCC имеет более лояльную лицензию на использование, и поэтому он установлен во многих дистрибутивах по умолчанию.

Так как в новом ядре фиксится немалое количество багов для работы с моим оборудованием(Ryzen 9 3900x + AMD Radeon 5700 XT) будет рассмотрен вопрос автоматизации сборки и установки нового ядра, чтобы это сильно не отвлекало и занимало минимум времени. Думаю многим это будет полезно. Будет рассмотрен принцип работы моего сборочного скрипта. Все действия будут проводиться в Arch Linux. Если статья будет хорошо оценена, то она станет вводной частью в серию статей про оптимизацию Linux, где будут рассмотрены внутренние механизмы ОС, и как оптимизировать их работу, будут рассмотрены вредные советы и ошибки оптимизации, и будет дан ответ на вопрос оптимизации системы «Что для русского хорошо, то для немца смерть!».

Хоть тема оптимизации описывалась многократно, не мало где дают вредные советы, и некоторые механизмы ОС описаны с ошибками. Чаще всего это происходит из-за сложностей перевода или минимальной документации в интернете к компонентам ядра Linux. Где-то информация вовсе устарела. Плюс некоторые вещи понимают программисты, но не понимают системные администраторы, и наоборот. Изначально после установки Linux работает относительно медленно, но благодаря оптимизации и гибкой настройке, можно добиться более высокой производительности и значительно улучшить отклик системы. Arch Linux у меня используется как основная система, и отклик системы, производительность лучше, чем в Windows 10.

Внимание, автор статьи не несет ответственность за причиненный вред в следствии использования данной статьи! Все действия вы выполняете на свой страх и риск! Все действия должны выполнять только профессионалы!

▍Немного теории

LTO или Link Time Optimization это оптимизация на этапе линковки(компоновки). Чтобы понять, что такое LTO рассмотрим как работают компиляторы. В большинстве компиляторов используется двух этапная модель: этап компиляции и этап линковки.

На этапе компиляции:

— Парсятся исходные тексты программ, строится AST — Абстрактное Синтаксическое Дерево.

  • Оптимизируется Абстрактное Синтаксическое Дерево. Оптимизируются циклы, удаляется мертвый код, результат которого нигде не используется. Раскрываются выражения, например 2+5 можно заменить на 7, чтобы при работе приложения не вычислять его значение каждый раз и тем самым сделать его быстрее и т.д.
  • Оптимизированное дерево может быть преобразовано в машинный псевдокод понятный компилятору. Псевдокод используется для дополнительной оптимизации, упрощает разработку универсального компилятора для разных архитектур процессора, например для x86-64 и ARMv7. Так же как ASM листинг, этот псевдокод еще используется, чтобы понять, как компилятор генерирует машинный код, и служит для понимания работы компилятора, поиска ошибок, например, ошибок оптимизации и unpredictable behavior. Стоит заметить этот этап не является обязательным и в некоторых компиляторах отсутствует.
  • Происходит векторизация. Векторизация ,Automatic Vectorization, SIMD
  • Генерируется объектный файл. Объектный файл содержит в себе машинный код для компьютера, и специальные служебные структуры, в которых все еще есть неизвестные адреса функций и данных, поэтому этот файл все еще не может быть запущен на исполнение. Чтобы разрешить неизвестные адреса, был добавлен этап линковки.

Компьютер работает только с бинарными данными, и может оперировать только адресам, поэтому имя функции и переменной ему ничего не говорят. Имя это лишь формальность для программистов, чтобы удобнее было читать исходный код. Во многих компилируемых языках программирования невозможно вычислить адрес функций на этапе компиляции, поэтому в них был придуман механизм описания функций.

Если мы используем функцию и она реализована в каком-то другом файле, то мы должны описать ее имя, параметры и возвращаемое значение. Тем самым мы скажем компилятору, что не надо искать ее в этом файле и она будет добавлена на этапе линковки. Так же, это упрощает парсинг исходных файлов. Нам больше не надо для компиляции и разрешения адресов читать все файлы за один раз. Представьте себе, что у вас исходный код программы занимает несколько гигабайт, такой размер нередко встречается в серьезных программах, тогда оперативной памяти большинства компьютеров не хватило бы, чтобы хранить все служебные структуры компилятора, что значительно повысило бы стоимость разработки и самих программ.

На этапе линковки:

  • Происходит подстановка адресов
  • Добавляются дополнительных данных для работы программы, например ресурсы
  • Происходит сборка всех объектных файлов в конечный исполняемый файл или распространяемую библиотеку, которая может быть использована в других программах

Понимая это мы можем понять, что LTO оптимизация это дополнительная оптимизация исполняемых файлов, которая не может быть произведена на этапе компиляции и происходит на этапе линковки.

В Clang используется два вида LTO Оптимизации: Full LTO и Thin LTO. Full LTO — это классическая реализация LTO оптимизации, которая обрабатывает конечный исполняемый файл за раз целиком и использует много оперативной памяти. Отсюда эта оптимизация занимает много времени, но дает на выходе самый быстрый код. Thin LTO — это развитие LTO оптимизации, в которой нет оптимизации всего файла целиком, а вместо этого вместе с объектными файлами записывают дополнительные метаданные, и LTO оптимизатор работает с этими данными, что дает более высокую скорость получения оптимизированного исполняемого файла (скорость сравнима с линковкой файла без LTO оптимизации) и код сравнимый или чуть уступающий в производительности Full LTO. Но самое главное Full LTO может значительно увеличить размер файла, и код наоборот может из-за этого работать медленнее. Thin LTO лишен этого недостатка и в некоторых приложениях на практике мы можем получить лучшую производительность! Поэтому наш выбор будет сборка ядра Linux с Thin LTO.

Дополнительная информация:

  • blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html>
  • clang.llvm.org/docs/ThinLTO.html>

▍Установка LLVM 12 и Clang

Поставить llvm и clang можно выполнив в консоли под root команду:

pacman -Syu base-devel llvm clang lld vim

Это самый простой вариант установки, но лично предпочитаю новые версии ПО, и git версия закрыла часть багов компилятора и даже стабильнее релиза. Так как за время написания статьи многое поменялось, вышел официальный пакет llvm 12, то чтобы понять ход мыслей, рекомендуется к прочтению прошлая версия по установке.

Прошлая версия

На момент написания статьи, в дистрибутиве Arch Linux используются LLVM и Clang версии 11. А LLVM и Clang версии 12 находятся в staging репозитории Arch Linux [LLVM](https://archlinux.org/packages/staging/x86_64/llvm/). Staging репозиторий это репозиторий, где находятся версии пакетов, которые ломают приложения, зависящие от прошлой версии. Он используется для компиляции всех зависящих программ, и когда все они будут собраны, все пакеты за раз переходит в общий репозиторий. Например, в Arch Linux от LLVM и Clang версии 11 зависят blender, rust и qt creator и т.д. Если мы поставим LLVM и Clang версии 12, то они перестанут работать.
Upd. Пакет уже перешел в основной репозиторий. Так как мною одним из первых была произведена миграция на LLVM и Clang 12, то было придумано простое решение, создать пакет [llvm11-libs](https://aur.archlinux.org/packages/llvm11-libs-bin/) с необходимыми библиотеками для обратной совместимости, который позволяет оставить зависимые программы рабочими. Но данный пакет работает только с моим сборочным пакетом [llvm12-git](https://aur.archlinux.org/packages/llvm12-git/). Поэтому мы будем собирать LLVM и Clang 12 из исходников. Но вы можете дождаться, когда LLVM и Clang 12 появятся в основном репозитории Arch Linux или использовать 11 версию. Лично предпочитают новые версии ПО, и LLVM и Clang 12 лучше поддерживают мой процессор Ryzen 9 3900X. Плюс git версия закрыла часть багов компилятора и даже стабильнее релиза. Релизный архив с официального сайта у меня не проходит больше тестов при сборке чем git версия. Не стоит пугаться того, что часть тестов компилятор провалил, там нет критических багов для x84-64 архитектуры, и большая часть затрагивают другие компоненты, например openmp и lldb. За очень долгое время тестирования llvm и clang 12 мною не было замечено ни одного бага влияющего на работу системы. Стоит заметить, на данный момент 13 версия является очень сырой и нам не подходит!

Поставим llvm и clang 11 версии(Если 12 версия появилась в основном репозитории, то поставится 12я версия) можно выполнив в консоли под root команду:

pacman -Syu base-devel llvm clang lld libclc vim

Обновить Arch Linux и поставить новые версии программ можно командой(это будет полезно тем кто будет ждать официального выхода 12 версии, думаю это произойдет уже через пару дней):

pacman -Syu

Кто остановился на этом варианте можно пропустить следующий пункт. Для остальных, будет дана инструкция по установке моего пакета.

Cборка LLVM 12 из Arch User Repository

Для сборки нам понадобиться git и нам надо будет собрать программу yay.

Поставим необходимые зависимости, для этого нам будут нужны права root: pacman -Syu base-devel git go vim

Если вы хотите собрать llvm 12 с помощью clang 11, то надо поставить еще их: pacman -S llvm clang lld

Отредактируем конфигурационный файл сборщика пакетов makepkg в Arch Linux и увеличим количество потоков для сборки программ. Это ускорит скорость сборки. Под root выполним: vim /etc/makepkg.conf

Найдем строки MAKEFLAGS и NINJAFLAGS. Нажмем латинскую букву A. Нам после -j надо указать количество потоков для сборки. Рекомендуется ставить ваше количество ядер или потоков процессора, если ядер 4, то ставим 4 или 8. У меня это 20, 12 ядер — 24 потока, 4 остаются запасными для других задач. Или используем автоматическое определение $(nproc).

В итоге получим:

MAKEFLAGS="-j20"
NINJAFLAGS="-j20"

или

MAKEFLAGS="-j$(nproc)"
NINJAFLAGS="-j$(nproc)"

Нажмем ESC, дальше SHIFT + :(буква Ж). Внизу появится : — строка для ввода команд, вводим wq. w — write, записать изменения в файл. q — quit, выйти из vim. q! выход из vim без сохранения файла. Кому сложно разобраться с vim, в Linux есть замечательная программа, называется она vimtutor. Если у вас настроена правильно локаль, то vimtutor будет на русском, запустить его можно командой vimtutor. Стоит заметить, вопреки распространенному мнению, обучение у вас не займет много времени. Обычно новичков пугают мифом: vi и vim люди изучают очень долго, и осилить их могут только единицы. На самом деле это не так и там нет ничего сложного.

Под обычным пользователем клонируем репозиторий yay, собираем и устанавливаем:

git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -cfi

Импортирует открытый gpg ключ, он необходим для проверки подписи llvm12-git:

gpg --keyserver pgp.mit.edu --recv-keys 33ED753E14757D79FA17E57DC4C1F715B2B66B95

Поставим LLVM 12 и библиотеки совместимости с 11 версией. Стоит заметить, мой пакет LLVM 12 уже содержит все необходимые утилиты, включая Clang и LLD и их не надо ставить отдельно.
Под обычным пользователем выполним команду:

pacman -Syu base-devel llvm clang lld vim git 
  ninja cmake libffi libedit ncurses libxml2
  ocaml ocaml-ctypes ocaml-findlib python-setuptools 
  python-psutil python-sphinx python-recommonmark

Затем

git clone https://github.com/h0tc0d3/llvm-git.git && cd llvm-git && makepkg -cfi

Команда yay задаст вам несколько вопросов, нажмите Enter в ответ на все. Сборщик LLVM задаст 3 вопроса:

  • Build with clang and llvm toolchain? — Собрать с помощью llvm и clang? Отвечаем Y или Enter если да, и N если нет. Рекомендую собирать LLVM с помощью Clang.
  • Skip build tests? Пропустить сборку тестов? Отвечаем Y или Enter. Так как во время сборки, не все тесты проходят проверку, то сборка будет прекращена. Поэтому мы пропускаем сборку тестов, и на самом деле сборка будет идти даже быстрее.
  • Skip build documentation? Пропустить сборку документации? Отвечаем Y или Enter если да, и N если нет. Если вам не нужна документация, то можно пропустить, это ускорит сборку. Лучше читать документацию на официальном сайте, это удобнее.
  • Skip build OCaml and Go bindings? Пропустить сборку OCaml и Go биндингов? Отвечаем Y или Enter если да, и N если нет. Для большинства ответ Y и их сборку можно смело пропустить в угоду скорости сборки. Для тех кому они нужны, а это очень маленькое количество людей могут ответить N.

Сборка может занять от 20 минут до пары часов. Ждете и в конце отвечаете Y на вопрос: хотите ли вы поставить собранные пакеты?

После установка LLVM надо собрать libclc12-git yay -S libclc12-git. libclc необходим для компиляции opencl и для сборки mesa.

▍Делаем LLVM и Clang сборочным тулчейном по умолчанию в Arch Linux

Большинство программ в Arch Linux собираются с помощью команды makepkg: man makepkg и PKGBUILD файлов. Поэтому в первую очередь внесем изменения в конфигурационный файл /etc/makepkg.conf. Выполним под root в консоли команду: vim /etc/makepkg.conf. Перейдем к строке CHOST="x86_64-pc-linux-gnu" поставим курсор на следующей пустой строке и нажмем латинскую букву «A», и вставим после строки:

export CC=clang
export CXX=clang++
export LD=ld.lld
export CC_LD=lld
export CXX_LD=lld
export AR=llvm-ar
export NM=llvm-nm
export STRIP=llvm-strip
export OBJCOPY=llvm-objcopy
export OBJDUMP=llvm-objdump
export READELF=llvm-readelf
export RANLIB=llvm-ranlib
export HOSTCC=clang
export HOSTCXX=clang++
export HOSTAR=llvm-ar
export HOSTLD=ld.lld

Дальше заменим строки CPPFLAGS, CXXFLAGS, LDFLAGS на содержимое ниже:

CFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
CXXFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"

Если вкратце мы используем -O2 оптимизацию для всех программ, -fstack-protector-strong используем улучшенную защиту стека, что снижает вероятность потенциально опасных ошибок при работе со стеком в программах, она же включена у меня в ядре. Плюс на моем процессоре при сборке с Clang с -fstack-protector-strong код при работе с целыми числами работает чуть быстрее, при работе с числами с плавающей запятой есть небольшой оверхед. В GCC наоборот есть более заметный оверхед и производительность снижается. -march=native есть смысл заменить на ваш, у меня это -march=znver2 gcc.gnu.org/onlinedocs/gcc/x86-Options.html.

Изменим количество потоков в MAKEFLAGS и NINJAFLAGS для сборки программ. Это помогает ускорить сборку программ. После -j надо указать количество потоков для сборки. Рекомендуется ставить ваше количество ядер или потоков процессора, если ядер 4, то ставим 4 или 8. У меня это 20, 12 ядер, 24 потока, 4 остаются запасными для других задач. Или используем автоматическое определение $(nproc).

В итоге получим:

MAKEFLAGS="-j20"
NINJAFLAGS="-j20"

или

MAKEFLAGS="-j$(nproc)"
NINJAFLAGS="-j$(nproc)"

Из DEBUG_CFLAGS и DEBUG_CXXFLAGS надо удалить -fvar-tracking-assignments. LLVM не поддерживает данный параметр.

Файл должен будет принять примерно такой вид:

CARCH="x86_64"
CHOST="x86_64-pc-linux-gnu"

CARCH="x86_64"
CHOST="x86_64-pc-linux-gnu"
#-- Compiler and Linker Flags
export CC=clang
export CXX=clang++
export LD=ld.lld
export CC_LD=lld
export CXX_LD=lld
export AR=llvm-ar
export NM=llvm-nm
export STRIP=llvm-strip
export OBJCOPY=llvm-objcopy
export OBJDUMP=llvm-objdump
export READELF=llvm-readelf
export RANLIB=llvm-ranlib
export HOSTCC=clang
export HOSTCXX=clang++
export HOSTAR=llvm-ar
export HOSTLD=ld.lld

CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
CXXFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
RUSTFLAGS="-C opt-level=2"
#-- Make Flags: change this for DistCC/SMP systems
MAKEFLAGS="-j20"
NINJAFLAGS="-j20"
#-- Debugging flags
DEBUG_CFLAGS="-g"
DEBUG_CXXFLAGS="-g"
#DEBUG_CFLAGS="-g -fvar-tracking-assignments"
#DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"
#DEBUG_RUSTFLAGS="-C debuginfo=2"

Нажмем ESC, дальше SHIFT + :(буква Ж). Внизу появится: — строка для ввода команд, вводим wq. w — write, записать изменения в файл. q — quit, выйти из vim. q! выход из vim без сохранения файла. Кому сложно разобраться с vim, в Linux есть замечательная программа, называется она vimtutor. Если у вас настроена правильно локаль, то vimtutor будет на русском, запустить его можно командой `vimtutor`. Стоит заметить, вопреки распространенному мнению, обучение у вас не займет много времени. Обычно новичков пугают мифом: vi и vim люди изучают очень долго, и осилить их могут только единицы. На самом деле это не так и там нет ничего сложного.

Следующим этапом можно добавить настройки в файл .bashrc текущего пользователя. Не root, сборка программ под root очень плохая идея! Это относительно вредный совет и с помощью clang будут собираться все программы! Поэтому делайте это только если хорошо понимаете зачем это вам. Это можно сделать командой:

cat << 'EOF' >> "${HOME}/.bashrc"

export CARCH="x86_64"
export CHOST="x86_64-pc-linux-gnu"
export CC=clang
export CXX=clang++
export LD=ld.lld
export CC_LD=lld
export CXX_LD=lld
export AR=llvm-ar
export NM=llvm-nm
export STRIP=llvm-strip
export OBJCOPY=llvm-objcopy
export OBJDUMP=llvm-objdump
export READELF=llvm-readelf
export RANLIB=llvm-ranlib
export HOSTCC=clang
export HOSTCXX=clang++
export HOSTAR=llvm-ar
export HOSTLD=ld.lld

export CPPFLAGS="-D_FORTIFY_SOURCE=2"
export CFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
export CXXFLAGS="-fdiagnostics-color=always -pipe -O2 -march=native -fstack-protector-strong"
export LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
export RUSTFLAGS="-C opt-level=2"
export MAKEFLAGS="-j20"
export NINJAFLAGS="-j20"
export DEBUG_CFLAGS="-g"
export DEBUG_CXXFLAGS="-g"

EOF

▍Список системных библиотек и программ которые стоит собирать вручную

Внимание, сборка всех программ и все консольные команды надо выполнять под обычным пользователем, перед установкой у вас попросит пароль root. Сборка всех библиотек и программ из списка не занимает много времени. Все кроме Mesa у меня собирается в районе 1 минуты. Список дан в той в последовательности в которой рекомендуется сборка! К примеру от zlib-ng и zstd зависит Mesa, а от Mesa зависит xorg-server.

Самое первое, что надо сделать в Arch Linux это заменить zlib на zlib-ng. Это дает хороший выигрыш производительности в приложениях, которые зависят от zlib. Больше всего это заметно на веб браузерах и веб серверах, которые используют gzip сжатие для передачи данных. На высоко нагруженных серверах это дает очень значительную прибавку к производительности. Сборка довольно быстрая. Поставить можно командой(под обычным пользователем): yay -Syu zlib-ng. На вопрос хотите ли вы удалить zlib отвечайте Y. Не бойтесь библиотеки полностью взаимозаменяемы, и ничего не сломается!

Дальше у нас идет zstd это вторая по популярности библиотека используемая в ядре и в программах для сжатия данных. Поэтому имеет смысл собрать так же ее. Чтобы собрать, вам нужно скопировать содержимое zstd, создать директорию, например zstd, а в ней создать файл PKGBUILD и в него вставить содержимое по ссылке. Дальше в консоли перейти в директорию содержащую PKGBUILD, выполнить команду makepkg -cfi .

libjpeg-turbo — Библиотека для работы c jpeg файлами. Ее очень часто используют браузеры и программы рабочего стола. libjpeg-turbo собранный с clang дает у меня лучшую производительность. Действия такие же, как в zstd. Создать директорию, и вставить в файл PKGBUILD содержимое по ссылке libjpeg-turbo. Дальше в консоли перейдите в директорию содержащую PKGBUILD, выполнить команду makepkg -cfi.

libpng — Библиотека для работы с PNG файлами. По сборке и установке все то же самое. libpng. Для сборки вам понадобится патч: 72fa126446460347a504f3d9b90f24aed1365595.patch, его надо положить в одну директорию с файлом PKGBUILD. Для сборки надо внести изменения в PKGBUILD, заменить source и sha256sums на строки ниже, и добавить функцию prepare.

source=("https://downloads.sourceforge.net/sourceforge/$pkgname/$pkgname-$pkgver.tar.xz"
  "72fa126446460347a504f3d9b90f24aed1365595.patch")
sha256sums=('505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca'
  '84298548e43976265f414c53dfda1b035882f2bdcacb96ed1bc0a795e430e6a8')

prepare() {
  cd $pkgname-$pkgver
  patch --forward --strip=1 --input="${srcdir:?}/72fa126446460347a504f3d9b90f24aed1365595.patch"
}

Mesa — это святой грааль для всех графических приложений. Стоит собирать всегда вручную, дает хорошую прибавку в десктоп приложениях, улучшается отклик рабочего стола. Одно время сидел на git версии, чтобы получить лучшую поддержку новых видеокарт AMD. Вот мой PKGBUILD оптимизированный для сборки с помощью Clang.

Для сборки вам надо отредактировать файл mesa.conf и установить необходимые вам драйвера dri, gallium, vulkan для сборки. У меня сборка только под новые видеокарты AMD. Подглядеть можно тут: Mesa OpenGL, mesa-git package, Mesa Documentation. При выходе новой версии Mesa не забудьте сменить 21.1.2 на новую версию. А после смены версии обновите контрольные суммы файлов, выполнив в директории с PKGBUILD команду updpkgsums.

xorg-server — X сервер с которым взаимодействуют почти все среды рабочего стола. Сборка дает заметное улучшение отклика рабочего стола. Сборка такая же через mapkepkg -cfi. Скачать необходимые файлы для сборки можно тут: xorg-server Сборочный пакет немного кривой и собирает пакет без оптимизаций. Поэтому его надо пропатчить. Для это после строки arch-meson ${pkgbase}-$pkgver build надо добавить строки:

  -D debug=false 
  -D optimization=2 
  -D b_ndebug=true 
  -D b_lto=true 
  -D b_lto_mode=thin 
  -D b_pie=true 

Полный список критических важных программ влияющих на производительность системы вы можете посмотреть в моём github репозитории arch-packages. Список был создан с помощью системного профилировщика perf. Все сборочные файлы оптимизированы для сборки с помощью llvm и сборка полностью автоматизирована. На моем ryzen 9 3900x сборка всего занимает около 20 минут. Единственный пакет который невозможно собрать с помощью clang и llvm это glibc. Его надо собирать вручную, и с оптимизацией -march= под ваш процессор, это самая часто вызываемая библиотека. Сборку glibc могут проводить только профессионалы, понимающие, что они делают. Не правильная сборка может сломать систему!

Для того, что бы воспользоваться автоматизированной сборкой надо выполнить(под обычным пользователем):

git clone https://github.com/h0tc0d3/arch-packages.git && cd arch-packages && chmod +x build.sh

Дальше нам надо установить все gpg сертификаты и зависимости необходимые для сборки, выполним ./build.sh --install-keys, а затем ./build.sh --install-deps

Для сборки программ достаточно просто запустить скрипт: ./build.sh --install, скрипт вам будет задавать вопросы, какие программы хотите собрать и поставить. На вопрос:

хотите ли вы отправить все ваши деньги и пароли автору статьи?

хотите ли вы заменить программы?(например, zlib-ng и zlib конфликтуют. Удалить zlib? [y/N] ) ответьте Y . Если вам нужна принудительная пересборка всех программ, то надо выполнить ./build.sh --install --force. По умолчанию, если пакет был уже собран и найден с нужной версией, то он не собирается, а просто устанавливается.

Для сборки mesa надо отредактировать файл mesa/mesa.conf и установить необходимые вам драйвера dri, gallium, vulkan для сборки.

С помощью команды ./build.sh --check можно проверить различия версий в моем репозитории и в официальном, помогает быстро адаптировать сборочные файлы и собрать актуальные версии программ. Слева версия в моем репозитории, справа от стрелки в официальном. Мой репозиторий может служить удобной тренировочной точкой на пути к созданию своего дистрибутива, создания LFS и развитию навыка пересборки ПО не ломая систему.

[+] zstd 1.5.0-1
[+] libpng 1.6.37-3
[+] libjpeg-turbo 2.1.0-1
[+] mesa 21.1.2-1
[+] pixman 0.40.0-1
[-] glib2 2.68.3-1 -> 2.68.2-1
[+] gtk2 2.24.33-2
[+] gtk3 1:3.24.29-2
[+] gtk4 1:4.2.1-2
[+] qt5-base 5.15.2+kde+r196-1
[+] icu 69.1-1
[+] freetype2 2.10.4-1
[+] pango 1:1.48.5-1
[+] fontconfig 2:2.13.93-4
[+] harfbuzz 2.8.1-1
[+] cairo 1.17.4-5
[+] wayland-protocols 1.21-1
[+] egl-wayland 1.1.7-1
[+] xorg-server 1.20.11-1
[+] xorgproto 2021.4-1
[+] xorg-xauth 1.1-2
[+] xorg-util-macros 1.19.3-1
[+] xorg-xkbcomp 1.4.5-1
[+] xorg-setxkbmap 1.3.2-2
[+] kwin 5.22.0-1
[+] plasma-workspace 5.22.0-2
[+] glibc 2.33-5

▍Сборка Ядра с помощью LLVM и Clang с LTO оптимизацией

Внимание! Сборку ядра необходимо выполнять под обычным пользователем. Перед установкой ядра у вас попросит sudo пароль. Не рекомендуется использовать патчи ядра linux-ck, linux-zen, MuQSS и т.д. Мною были протестированы все, при кажущемся увеличении производительности системы, происходят кратковременные лаги и снижается стабильность системы, некоторые подсистемы ядра работают не стабильно! С выходом ядра 5.11 стандартный планировщик работает не хуже и значительно стабильнее! Единственный патч который мною применяется это патч для применения оптимизации под процессор github.com/graysky2/kernel_gcc_patch Выбрать ваш процессор можно в меню конфигуратора ядра Processor type and features—>Processor family.

Сборка ядра с помощью LLVM описана в официальной документации Linux Kernel Build with LLVM. Но там есть несколько подводных моментов, которые не описаны. Первый подводный момент заключается в OBJDUMP=llvm-objdump, тут идет переопределение objdump, но так как параметры objdump в llvm имеет другой синтаксис, то при сборке будет пропущена часть тестов для проверки корректности сборки, и будет warning ругающийся на objdump. Правильно будет оставить родной objdump OBJDUMP=objdump

Неправильно:

make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip 
  READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ 
  HOSTAR=llvm-ar HOSTLD=ld.lld OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump

Правильно:

make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip 
  READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ 
  HOSTAR=llvm-ar HOSTLD=ld.lld OBJCOPY=llvm-objcopy OBJDUMP=objdump

Второй подводный момент заключается в том, что если мы не добавим LLVM_IAS=1 в строку make, то нам не будет доступна LTO оптимизация в конфигураторе ядра!

Поэтому полная строка для сборки с LTO будет:

export BUILD_FLAGS="LLVM=1 LLVM_IAS=1 CC=clang CXX=clang++ LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld OBJCOPY=llvm-objcopy OBJDUMP=objdump"
make ${BUILD_FLAGS} -j$(nproc)

Полный список команд для сборки ядра. /tmp
надо заменить на вашу директорию куда будут распакованы исходные файлы ядра, а mykernel
надо заменить на ваш постфикс для имени ядра.

export BUILD_FLAGS="LLVM=1 LLVM_IAS=1 CC=clang CXX=clang++ LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld OBJCOPY=llvm-objcopy OBJDUMP=objdump"
tar -xf linux-5.12.12.tar.xz -C /tmp
cd /tmp/linux-5.12.12
zcat /proc/config.gz > .config # Берем конфигурацию запущенного ядра из /proc/config.gz и используем ее для сборки
echo "-mykernel" > .scmversion
make ${BUILD_FLAGS} oldconfig
make ${BUILD_FLAGS} -j$(nproc) nconfig

C помощью oldconfig конфигурация адаптируется под новое ядро и запускается конфигуратор nconfig. Подробнее о конфигураторах ядра можно прочесть в официальной документации [Kernel configurator](https://www.kernel.org/doc/html/latest/kbuild/kconfig.html).

В конфигураторе переходим в General architecture-dependent option —> Link Time Optimization (LTO) и выбираем Clang ThinLTO (EXPERIMENTAL). Для дополнительной защиты стека в General architecture-dependent options ставим * напротив Stack Protector buffer overflow detection и Strong Stack Protector. Жмем F9 и сохраняем новый конфигурационный файл. Далее идет список команд для сборки и установки нового ядра.

make ${BUILD_FLAGS} -j$(nproc)
make ${BUILD_FLAGS} -j$(nproc) modules
sudo make ${BUILD_FLAGS} -j$(nproc) modules_install
sudo cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-mykernel

Следующий подводный момент заключается в DKMS, после установки ядра собранного с помощью Clang, DKMS пытается собрать модули ядра с помощью GCC. По этой причине сборка и установка DKMS модулей в новое ядро завершается ошибкой. Решение проблемы заключается в передаче DKMS компилятора Clang таким образом:

sudo ${BUILD_FLAGS} dkms install ${dkms_module} -k 5.12.12-mykernel

▍Автоматизация сборки ядра Linux

Для автоматизации сборки ядра мы будем использовать мой bash скрипт github.com/h0tc0d3/kbuild. Клонируем репозиторий и перейдем в рабочую директорию: git clone https://github.com/h0tc0d3/kbuild.git && cd kbuild && chmod +x kbuild.sh

Отредактируем файл build.sh или поместим содержимое ниже в файл ${HOME}/.kbuild. Рекомендуется второй способ vim "${HOME}/.kbuild" т.к. при обновлении скрипта наши настройки сохранятся. Если использовалось клонирование репозитория git, то в директории со скриптом можно выполнить команду git pull, чтобы обновить скрипт. Ниже даны параметры по умолчанию, они формируют поведение скрипта по умолчанию, если соответствующий параметр не был передан. Эти параметры в дальнейшем можно будет переопределить с помощью параметров командной строки для скрипта. Так же можно добавить команду в ваш .bashrc. Для этого в директории со скриптом kbuild.sh надо выполнить echo "alias kbuild='${PWD}/kbuild.sh" >> "${HOME}/.bashrc", ${PWD} автоматом заменит на текущую директорию. Или из любой другой директории можно указать полный пусть к скрипту echo "alias kbuild='полный-путь/kbuild.sh'" >> "${HOME}/.bashrc" После редактирования .bashrc необходимо перезапустить терминал! Теперь можно будет запускать скрипт командой kbuild --help .

KERNEL_VERSION='5.12.12'         # Версия Linux для сборки. Любая версия с официального сайта kernel.org, включая rc версии.
KERNEL_POSTFIX='noname'         # Постфикс для названия ядра. Ядро будет иметь имя версия-постфикс, 5.12.12-noname, нужно для разделения в системе ядер с одной версией.
KERNEL_CONFIG='/proc/config.gz' # Конфигурационный файл ядра. Поддерживает любые текстовые файлы и с жатые с расширением gz.
KERNEL_CONFIGURATOR='nconfig'   # Конфигуратор ядра nconfig, menuconfig, xconfig.
# Рекомендую использовать nconfig, он лучше menuconfig.
# Можно писать полную строку, например MENUCONFIG_COLOR=blackbg menuconfig
# Дополнительную информацию можно найти в документации к ядру https://www.kernel.org/doc/html/latest/kbuild/kconfig.html
MKINITCPIO=1 # Запускать "mkinitcpio -p конфигурационный_файл" После сборки? 0 - Нет, 1 - Да.
MKINITCPIO_CONFIG="${KERNEL_POSTFIX}" # Имя конфигурационного файла mkinitcpio, по умолчанию равно постфиксу.

CONFIGURATOR=0      # Запускать конфигуратор ядра? 0 - Нет, 1 - Да. Если вам не нужно конфигурировать ядро, то можно поставить 0.
LLVM=0              # Использовать LLVM Для сборки? 1 - Да, 0 - Нет(Будет использован GCC или другой системный компилятор по умолчанию)
THREADS=8           # Количество поток для сборки. Ускоряет сборку. Для автоматического определения надо заменить на $(nproc)
BUILD_DIR='/tmp'    # Директория в которой будет проходить сборки ядра. У меня 32gb оперативной памяти и сборка происходит в tmpfs.
DOWNLOAD_DIR=${PWD} # Директория для сохранения архивных файлов с исходниками ядра. ${PWD} - в папке из которой запущен скрипт сборки.

DIST_CLEAN=0    # Если директория с исходниками существует выполнять make disclean перед сборкой? 0 - Нет, 1 - Да
CLEAN_SOURCE=0  # Выполнять make clean после сборки ядра? 0 - Нет, 1 - Да
REMOVE_SOURCE=1 # Удалять директорию с исходными файлами ядра после сборки? 0 - Нет, 1 - Да.
SYSTEM_MAP=0    # Копировать System.map в /boot После сборки? 0 - Нет, 1 - Да.

PATCH_SOURCE=1                          # Применять патчи ядра? 0 - Нет, 1 - Да.
PATCHES=("${HOME}/confstore/gcc.patch") # Список патчей ядра. Нельзя поменять с помощью параметров скрипта.

DKMS_INSTALL=1                                        # Выполнять DKMS Install? 0 - Нет, 1 - Да.
DKMS_UNINSTALL=1                                      # Выполнять DKMS Uninstall? 0 - Нет, 1 - Да.
DKMS_MODULES=('openrazer-driver/3.0.1' 'digimend/10') # Список DKMS модулей, который нужно собрать и установить. Нельзя поменять с помощью параметров скрипта.

Внимание! Сборку ядра необходимо выполнять под обычным пользователем. Перед установкой ядра у вас попросит sudo пароль. Не рекомендуется использовать патчи ядра linux-ck, linux-zen, MuQSS и т.д. Мною были протестированы все, при кажущемся увеличении производительности системы, происходят кратковременные лаги и снижается стабильность системы, некоторые подсистемы ядра работают не стабильно. С выходом ядра 5.11 стандартный планировщик работает не хуже и значительно стабильнее! Единственный патч который мною применяется это патч для применения оптимизации под процессор github.com/graysky2/kernel_gcc_patch. Нас интересует файл more-uarches-for-kernel-5.8+.patch. Путь к нему имеет смысл указать в PATCHES. Выбрать ваш процессор можно в меню конфигуратора ядра Processor type and features—>Processor family.

Принцип работы скрипта:

1) set -euo pipefail — скрипт переходит в строгий режим, в случае ошибок скрипт завершается с ошибкой. Является хорошим тоном, при написании bash скриптов. Скрипт проверяет запущен ли он под рут, если запущен под рут, то выдает ошибку и завершается. Загружается настройки пользователя из файла ${HOME}/.kbuild

2) Скрипт проверяет существование директории linux-версия в директории BUILD_DIR. Если существует, то исходники распакованы. Перед сборкой может выполняться команда make distclean, поведение задается переменной DIST_CLEAN. Если этой директории не существует, то проверяется существование файла linux-версия.tar.gz

или linux-версия.tar.xz. Если файл найден, то он распаковывается в BUILD_DIR. Иначе файл скачивается с kernel.org в директорию DOWNLOAD_DIR.

3) Скрипт применяет патчи ядра и устанавливает постфикс для версии ядра(записывает его в файл .scmversion ).

4) Скрипт копирует настройки ядра из файла KERNEL_CONFIG в .config и выполняет make oldcofig для адаптации настроек под новое ядро и запускает конфигуратор ядра.

5) Скрипт собирает ядро и модули.

6) Скрипт удаляет модули DKMS из ядра которое сейчас запущено, если это необходимо. Это необходимо, чтобы в списке dkms status не отображались мертвые ядра. Удаляет директорию `/lib/modules/версия-постфикс` если она существует. Она существует в том случае, если мы собираем одну и туже версию несколько раз. Это дополнительная защита от unpredictable behavior .

7) Скрипт устанавливает модули ядра, копирует ядро в /boot/vmlinuz-постфикс.

8) Скрипт собирает DKMS модули и устанавливает их. Копирует System.map в /boot/System-постфикс.map, если это необходимо.

9) Обновляет загрузочный img файл для ядра. Выполняет mkinitcpio -p конфиг.

10) Выполняет make clean если необходимо. Удаляет директорию linux-версия в директории BUILD_DIR, если это необходимо.

Собрать ядро с llvm можно командой ./kbuild.sh -v 5.12.12 --llvm --start или kbuild -v 5.12.12 --llvm --start, если был установлен alias. -v 5.12.12 — указывает версию ядра для сборки, --llvm — указывает собирать ядро с помощью llvm и clang. --start — указывает, что надо запускать конфигуратор ядра. Получить справку по параметрам скрипта можно выполнив команду kbuild --help.

Русская справка

Параметры:                     Описание:              Пример:
--version, -v                  Версия ядра для сборки --version 5.12.12 | -v 5.13-rc4
--postfix, -p                  Постфикс ядра          --postfix noname | -p noname
--config, -c                   Файл конфигурации ядра --config /proc/config.gz | -c /proc/config.gz
--dir, -d                      Директории сборки      --dir /tmp | -d /tmp
--download, -z                 Директория загрузки    --download /tmp | -z /tmp
--threads, -t                  Количество потоков сборки --threads 8 | -t 8
--configurator, -x             Конфигуратор ядра      --configurator nconfig | -x "MENUCONFIG_COLOR=blackbg menuconfig"

--start, -s                    Запускать конфигуратор
--disable-start, -ds           Не запускать конфигуратор

--mkinitcpio, -mk              Запускать mkinitcpio после установки ядра
--disable-mkinitcpio, -dmk     Не запускать mkinitcpio после установки ядра
--mkinitcpio-config, -mc       Конфиг mkinitcpio      --mkinitcpio-config noname | -mc noname

--llvm, -l                     Использовать LLVM
--disable-llvm, -dl            Не использовать LLVM

--patch, -ps                   Применять патчи ядра
--disable-patch, -dp           Не применять патчи ядра

--map, -m                      Копировать System.map в /boot/System-постфикс.map
--disable-map, -dm             Не копировать System.map

--clean, -cs                   Чистить исходники после сборки. make clean
--disable-clean, -dc           Не чистить исходники после сборки.
--distclean, -cd               Чистить исходники перед сборкой. make distclean
--disable-distclean, -dd       Не чистить исходники перед сборкой.
--remove, -r                   Удалять директорию с исходниками после сборки
--disable-remove, -dr          Не удалять директорию с исходниками после сборки

--dkms-install, -di            Устанавливать DKMS модули
--disable-dkms-install, -ddi   Не устанавливать DKMS модули
--dkms-uninstall, -du          Деинсталлировать DKMS модули перед их установкой
--disable-dkms-uninstall, -ddu Не деинсталлировать DKMS модули перед их установкой

Список параметров которые помогают отлавливать ошибки на разных этапах и продолжить вручную:

--stop-download, -sd           Стоп посл загрузки файла
--stop-extract, -se            Стоп после распаковки архива с исходниками
--stop-patch, -sp              Стоп после применения патчей ядрей
--stop-config, -sc             Стоп после конфигуратора ядра
--stop-build, -sb              Стоп после сборки ядра
--stop-install, -si            Стоп после установки нового ядра и модулей

Как можно понять из статьи сборка ядра с LLVM и Clang относительно простая. И самое главное можно автоматизировать сборку и установку ядра, и в дальнейшем не тратить много времени на сборку новых ядер.

Всем кто дочитал до конца, спасибо! Комментарии и замечания приветствуются!

UPD. 16.06.2021 Обновил сборочные скрипт библиотек и программ, производительность еще выросла github.com/h0tc0d3/arch-packages
UPD. Cделан репозиторий с оптимизированными пакетами для Arch Linux archlinux.club

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Была ли полезна и понравилась вам статья?


82.14%
Да, статья понравилась и была полезна
92


13.39%
Нет, статья не понравилась и не была полезна
15


4.46%
Другое, ответ в комментарии
5

Проголосовали 112 пользователей.

Воздержались 30 пользователей.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Продолжить серию статей по оптимизации Linux?


90.08%
Продолжить серию статей
118


8.4%
Не продолжать серию статей
11


1.53%
Другое, ответ в комментарии
2

Проголосовал 131 пользователь.

Воздержались 25 пользователей.

Правильно ли я понимаю, что есть одно единственное и неповторимое ядро Linux, на базе которого разработаны все эти многочисленные дистрибутивы (Ubuntu, Debian, Mint и т. д).

Не совсем. Едина только база (изначальный исходный код). То есть разработчики дистрибутивов скачивают исходные коды нужной им версии Linux-а, вносят в них какие-то свои исправления (патчи), задают параметры сборки для включения нужных и исключения ненужных возможностей и компилируют ядро. Иными словами, дистрибутивы отличаются не только репозиториями и прикладными программами, но и вариациями ядра.

… и при этом можно установить именно это самое чистое ядро, а не какой-то из дистрибутивов?

Можно. Но так как ядро распространяется в исходных кодах, вам придётся скомпилировать из них свой вариант, заточенный конкретно под ваш компьютер и, возможно, потребности — штатный конфигуратор make menuconfig богат на опции:

menuconfig

Главное окно графического конфигуратора параметров сборки Linux. Источник: Википедия

Однако, получение даже минимальной рабочей системы — довольно длительный и многоэтапный процесс, требующий достаточных познаний в принципах работы Linux-а.

Правильно ли я понимаю, что само по себе ядро это уже по сути ОС, только без графического интерфейса (что-то вроде DOS) а сам GUI-интерфейс можно уже установить отдельно?

И снова не совсем. Ядро — это всего лишь прослойка между программами и железом. В случае Linux-а там в комплекте ещё идут драйвера.

Чтобы получить что-то, похожее на DOS, вам дополнительно потребуются как минимум GNU Coreutils — набор программ, определяющих пользовательское окружение (ls, cat, su и т. д.), и загрузчик (например, grub, lilo), который будет загружать ядро при включении компьютера.

Кстати, именно из-за симбиоза ядра Linux и пакета программ GNU Coreutils операционную систему и называют GNU/Linux.

Слышал много раз о том, что ядро в начале обычно нужно скомпилировать, а затем установить. Есть ли возможность получить уже скомпилированное ядро, распространяется ли оно в таком виде?

Распространение в исходных кодах — это своего рода политика разработчиков ядра, а потому скомпилированное ядро можно только выдрать из какого-то имеющегося дистрибутива.

Хорошая ли идея — пытаться скомпилировать это самое ядро Linux на Windows, и насколько это вообще возможно?

Для сборки Linux вам потребуются компилятор GCC и компоновщик LD. Теоретически, при сборке под Cygwin проблем быть не должно (если именно компилировать ядро), но есть информация о трудностях с регистрозависимыми имёнами файлов, которые Windows считает одинаковыми.

Слышал много раз о всяких менеджерах пакетов, при помощи которых осуществляется установка различного софта в системах на базе Linux, при этом у каждой такой ОС (Ubuntu, Debian, Mint и т.д) свои собственные менеджеры пакетов. А как быть с чистым ядром? Каким образом на него что-то ставится?

Компиляцией из исходников. То есть в случае чистого ядра у вас под рукой всегда должен быть компилятор.

Каким вообще образом распространяется софт для Linux? Только в open source, с последующей компиляцией? А такие штуки как установочные файлы, .exe-шники и прочее — обычно не используется?

Сборка из исходников является обязательной только для компонентов ядра, таких как драйвера. Прикладные же программы можно ставить и в виде двоичных файлов. Идёте на сайт разработчика, скачиваете какой-нибудь пакет. Затем, зная что любой пакет — это всего лишь архив одного из распространённых форматов, распаковываете его и раскидываете содержащиеся внутри файлы на подобающие им места в системе. И наконец удостоверяетесь, что у вас есть все библиотеки, нужные для запуска этой программы.

Если есть только один ПК без установленной ОС, как обычно на него устанавливается ядро Linux?

Для сборки Linux нужна другая копия Linux. Поэтому вам надо хотя бы раздобыть live cd какого-нибудь дистрибутива.

Самым основным компонентом операционной системы Linux есть ядро. Именно ядро выступает промежуточным звеном между пользовательскими программами и оборудованием компьютера. Во всех бинарных дистрибутивах не нужно заботиться о сборке и настройке ядра, все уже сделали за нас разработчики дистрибутива. Но если вы хотите установить самую свежую версию ядра или настроить его под себя удалив от туда всё лишнее, вам придется собрать его вручную.

Раньше ядро собирали для того чтобы получить максимальную производительность от своего оборудования, но сейчас, учитывая стремительное увеличение мощности компьютеров увеличение производительности при сборке ядра совсем незаметно. Сейчас сборка ядра может понадобиться пользователям не бинарных дистрибутивов, таких как Gentoo, тем, кто хочет внести некоторые изменения в ядро, получить новую самую свежую версию ядра и, конечно, же тем, кто хочет полностью разобраться в работе своей системы. В этой статье мы рассмотрим как собрать ядро Linux на примере дистрибутива Ubuntu.

Первая часть расскажет как настроить ядро в автоматическом режиме. Так сказать, для тех кто не хочет разбираться как оно работает, кому нужно лишь получить на выходе готовый продукт — собранное ядро. Во второй части мы рассмотрим основные этапы ручной настройки ядра, это процесс сложный, и не быстрый, но я попытаюсь дать основу, чтобы вы могли со всем разобраться сами.

1. Текущая версия ядра

Для того чтобы посмотреть текущую версию ядра, установленную в системе используйте такую команду:

uname -a

2. Установка необходимых пакетов

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

sudo apt install libncurses-dev libncurses dwarves build-essential gcc bc bison flex libssl-dev libelf-dev

После установки пакетов можно переходить к загрузке исходников ядра.

3. Получение исходников ядра

Исходники лучшие брать с сайта вашего дистрибутива, если они там есть или официального сайта ядра: kernel.org. В этой статье будет рассмотрена загрузка исходников с kernel.org.

Перед тем как скачивать исходники нужно определиться с версией ядра которую надо собирать. Есть две основных версии релизов — стабильные (stable) и кандидаты в релизы (rc), есть, конечно, еще стабильные с длительным периодом поддержки (longterm), но важно сейчас разобраться с первыми двумя. Стабильные это, как правило, не самые новые, но зато уже хорошо протестированные ядра с минимальным количеством багов. Тестовые — наоборот, самые новые, но могут содержать различные ошибки.

Итак когда определились с версией зайдите на kernel.org и скачайте нужные исходники в формате tarball:

В этой статье будет использована самая новая на данный момент стабильная версия 5.13.7. Полученный с официального сайта архив необходимо распаковать. Для этого перейдите в папку загрузок и выполните команду распаковки:

cd ~/Загрузки/

tar xvf linux*

Затем нужно перейти в папку с распакованными исходниками ядра. Например, для версии 5.13.7 команда будет выглядеть вот так:

cd linux-5.13.7/

4. Текущая конфигурация ядра

Вы можете сами настраивать ядро с нуля, но это, скорее всего, займет очень много времени и точно не для новичков. Поэтому удобнее всего взять текущую конфигурацию ядра и использовать её в качестве базы для сборки нового. Во многих дистрибутивах конфигурация хранится в файле /proc/config.gz. Однако это будет работать только если была включена соответствующая опция ядра. Извлечь такую конфигурацию можно с помощью команды:

zcat /proc/config.gz > .config

Часто поддержка этой возможности отключена. Но в Ubuntu и других современных дистрибутивах, конфигурация ядра находится в папке /boot, в файле с названием config и версия ядра. Если у вас в системе установлено несколько ядер, то будет несколько конфигурационных файлов. Например, config-5.11.0-25-generic:

ls /boot

Для того чтобы скопировать этот конфигурационный файл в папку с исходниками выполните:

cp /boot/config-5.11.0-25-generic .config

5. Автоматическая конфигурация

Полученную конфигурацию необходимо актуализировать до состояния текущего ядра. В новых версиях ядра, обычно, добавляются новые опции, значений которых ещё нет в конфигурации ядра вашего дистрибутива. Для этого есть несколько скриптов. В этой статье будет рассмотрено только два: oldconfig и localmodulesconfig. Первый скрипт позволяет в интерактивном режиме заполнить новые поля конфигурации. Для его запуска в папке с исходниками ядра выполните:

make oldconfig

После запуска скрипта вам придется просмотреть все вопросы и ответить на них. Обычно скрипт советует как отвечать и в большинстве случаев можно оставить значение по умолчанию, но если вы сомневаетесь, то можно посмотреть какое значение стоит выбрать в Google. Особое внимание уделяйте пунктам, не отмеченным как NEW, такие настройки не новые и требуют вашего вмешательства.

После ответа на все вопросы можно переходить к следующему шагу. Однако, при таком способе конфигурации ядра останутся включёнными многие ненужные модули, а значит сборка займет много времени, много места на диске (до 20 Гб) и само ядро получится большого размера.

С помощью команды localmodulesconfig можно оптимизировать процесс. Это ответ на вопрос как собрать ядро Linux под свое железо  проще всего. Она работает аналогично предыдущей, только в дополнение к этому проверяет какие модули ядра сейчас загружены и оставляет включёнными только их, сборку всех остальных отключает. Такое ядро соберется намного быстрее, да и вопросов, на которые надо будет ответить будет меньше.

make localmodulesconfig

Здесь обратите внимание на алгоритм сжатия модулей ядра. Лучше оставить без сжатия:

6. Ручная настройка ядра

После того как вы выполнили один из автоматических скриптов настройки ядра, вы можете захотеть настроить что-то дополнительно вручную. Для этого используется команда menuconfig. Она позволяет изменять настройки ядра в псвевдографическом меню. Для его запуска выполните:

make menuconfig

Для перемещения по меню используйте клавиши со стрелками вверх и вниз. Для включения или отключения функции нужно поставить на неё курсор и нажать у (включить), n (отключить), m (включить в виде модуля). Её можно использовать пробел или Enter для переключения состояния включено или выключено. Для открытия пункта конфигурации используйте Enter. Для перехода на уровень выше — Exit. Для перемещения между кнопками используйте стрелки вправо и влево. Всё это написано в окне меню:

Давайте рассмотрим несколько настроек. В разделе General Setup можно включить поддержку получения конфигурации из файла /proc/config.gz. Для этого найдите пункты Kernel .config support и Enable access to .config through /proc/config.gz и поставьте перед ними звездочку с помощью клавиши Enter.

По каждому пункту можно получить справку. Для этого выберите кнопку Help и нажмите Enter:

С помощью пункта Kernel compression mode вы можете выбрать способ сжатия образа ядра. Самый эффективный — LZMA:

Пункт Support for paging of anonymous memory (swap) позволяет включить поддержку подкачки:

Возвращайтесь назад с помощью кнопки Exit, а затем откройте пункт File systems. Здесь можно включить или отключить поддержку файловых систем. Убедитесь, что включена поддержка ext4 и ext3, а также можете включить Btrfs и F2FS:

Самый большой и сложный раздел — это Device drivers в главном меню. Здесь можно включить или отключить поддержку драйверов всех устройств которые поддерживает Linux. Именно в этом разделе вам придется внести большинство настроек если вы собираетесь уменьшить размер своего ядра и не хотите использовать localmodconfig. После завершения настройки нажмите кнопку Save и подтвердите сохранение в файл .config:

6. Сборка ядра и установка вручную

Если вы хотите установить ядро вручную достаточно выполнить такие команды последовательно для его сборки:

make

make modules

По умолчанию будет использоваться только одно ядро процессора. Вы можете ускорить сборку попросив программу использовать сразу несколько ядер с помощью опции -j. Например, для сборки в 8 потоков используйте такую команду:

make -j8

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

make modules_install

Затем:

make install

Скрипт автоматически обновит конфигурацию Grub и вы сможете перезагрузить компьютер и получить новое ядро:

Но прежде чем идти дальше, давайте рассмотрим ещё один способ сборки ядра.

7. Сборка пакета для Ubuntu

Описанный выше способ установки не очень удобный, поскольку если вы захотите удалить ядро, вам придется это делать вручную. Вместо этого вы можете собрать пакет для своего дистрибутива и установить его с помощью пакетного менеджера. Для сборки deb пакета выполните такую команду:

make deb-pkg

После завершения сборки ядра Linux пакеты появятся на каталог выше каталога с исходниками:

Для установки этих пакетов достаточно выполнить такую команду:

sudo dpkg -i ../*.deb

Затем вы можете перезагрузить компьютер и убедится, что теперь используется новое ядро:

Для удаления ядра, установленного таким способом достаточно загрузится с другим ядром и удалить пакеты ядра из системы. Например, для этой версии команда будет выглядеть так:

sudo apt remove linux-headers-5.13.7 linux-image-5.13.7 linux-image-5.13.7-dbg linux-libc-dev

Что делать если ядро не загружается

Если по каким-либо причинам собранное только что ядро не загружается, то ничего страшного ещё не произошло. Вы можете загрузится со старым ядром и начать всё сначала или удалить новое ядро и продолжить использовать систему со старым ядром. Для этого в меню Grub необходимо выбрать пункт Дополнительные параметры, а потом нужную версию ядра, например: 5.11.0.25:

Если меню Grub не отображается, попробуйте зажать перед загрузкой операционной системы клавишу Shift. После авторизации в системе вы можете удалить новое ядро с помощью пакетного менеджера, если использовали его для установки или вручную. Для удаления вручную следует удалить файлы ядра из папки /boot. Например:

sudo rm /boot/vmlinuz-5.13.7
sudo rm /boot/config-5.13.7
sudo rm /boot/initrd.img-5.13.7
sudo rm /boot/System.map-5.13.7
sudo rm -Rf /lib/modules/5.13.7/

А затем необходимо обновить конфигурацию Grub:

sudo update-grub2

После этого в вашей системе останутся только старые ядра.

Выводы

Вот и все. В этой статье мы подробно рассмотрели выполняется сборка ядра Linux из исходников. Это будет полезно всем желающим лучшие понять свою систему, и тем, кто хочет получить самую новую версию ядра в своей системе. Если остались вопросы, задавайте комментарии!

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

0 / 0 / 0

Регистрация: 20.07.2012

Сообщений: 6

1

20.07.2012, 20:51. Показов 6750. Ответов 10


Можно ли как-то компилировать ядро linux на Windows XP? Система стоит на виртуальной машине. Хотелось бы узнать все подробности

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



202 / 44 / 2

Регистрация: 19.03.2012

Сообщений: 283

20.07.2012, 21:50

2

Я компиляцией ядра не занимался не когда. Хотелось бы узнать зачем это вам? Может помогу найти другой выход из данной ситуации.



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

20.07.2012, 21:53

3

для компиляции используется некоторый набор тулов, которых нет под windows
да и сборка специфична

даже если это и возможно, то собрать будет намного проблематичней



0



202 / 44 / 2

Регистрация: 19.03.2012

Сообщений: 283

20.07.2012, 22:02

4

На мой взгляд самый главный вопрос зачем это нужно? Потому что как я понял система используется под виртуалкой.



0



0 / 0 / 0

Регистрация: 20.07.2012

Сообщений: 6

20.07.2012, 22:18

 [ТС]

5

Цитата
Сообщение от toxin
Посмотреть сообщение

На мой взгляд самый главный вопрос зачем это нужно? Потому что как я понял система используется под виртуалкой.

Да, основная система Mac OS X Snow Leopard, если это что то меняет.
Мне бы хотелось бы поэксперементировать над ядром, и ради интереса создать простейший дистрибутив для себя



0



202 / 44 / 2

Регистрация: 19.03.2012

Сообщений: 283

20.07.2012, 22:22

6

Тогда почитай в интернете про gentoo это как раз для тебя.



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

20.07.2012, 22:23

7

Цитата
Сообщение от Ender40
Посмотреть сообщение

Да, основная система Mac OS X Snow Leopard, если это что то меняет.

тогда шансов на самом деле больше
я бы взял какую-нибудь инструкцию сборки и попытался бы собрать
там станет очевидно чего не хватает



1



202 / 44 / 2

Регистрация: 19.03.2012

Сообщений: 283

20.07.2012, 22:24

8

А ещё проще поставить под виртуалкой linux и там уже компилировать ядро. Зачем заниматься дикими извращениями!?



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

20.07.2012, 22:39

9

Цитата
Сообщение от toxin
Посмотреть сообщение

А ещё проще поставить под виртуалкой linux и там уже компилировать ядро. Зачем заниматься дикими извращениями!?

в случае никсовой оси извращения возможно не окажутся дикими
гнушный софт вполне компилируется под макось
хотя не понимаю в чем проблема погуглить — оказывается подобные мысли приходят достаточно большому количеству народа



0



toxin

20.07.2012, 22:47

Не по теме:

У меня тоже возникает такой вопрос часто



0



0 / 0 / 0

Регистрация: 20.07.2012

Сообщений: 6

21.07.2012, 21:22

 [ТС]

11

Цитата
Сообщение от alex_x_x
Посмотреть сообщение

тогда шансов на самом деле больше
я бы взял какую-нибудь инструкцию сборки и попытался бы собрать
там станет очевидно чего не хватает

Большое вам спасибо, я уж забыл про то что Mac OS это UNIX, а линукс с ней совместим
Работает отлично!
Вот лог (Если кому то понадобится)

ыыы$ make config
scripts/kconfig/conf —oldaskconfig Kconfig
#
# using defaults found in arch/x86/configs/x86_64_defconfig
#
*
* Linux/x86_64 3.1.0 Kernel Configuration
*
*
* General setup
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?]

Ядро Линукса использовал старое, потому что новое на виртуалке



0



Пересборка ядра Linux дело очень интересное и почему-то часто отпугивает новичков. Но ничего сложного в этом нет, и скомпилировать ядро Linux бывает не сложнее, чем собрать (скомпилировать) любую другую программу из исходников. Пересборка ядра может понадобиться, когда вам требуются какие-нибудь функции, не включенные в текущее ядро, или же, наоборот, вы хотите что-то отключить. Все дальнейшие действия мы будем выполнять в Ubuntu Linux.

Установка утилит

Для настройки и сборки ядра Linux вам потребуется установить несколько пакетов, которые понадобятся для сборки и настройки ядра: kernel-package, build-essential, libncurses-dev. Сделать это можно командой:

sudo apt-get install build-essential kernel-package libncurses-dev

Скачиваем исходный код ядра

Теперь нужно скачать исходный код ядра. Мы будем скачивать ядро для Ubuntu. Вы можете скачать определенную версию ядра, например, ту, которую вы в данный момент используете или же скачать самую последнюю версию. Для того, чтобы определить версию ядра Linux, которую вы используете, выполните команду uname с параметром -r:

uname -r

Вывод команды будет примерно следующим:

$uname -r
2.6.27-11-generic

Имя пакета, содержащего исходные коды ядра обычно имеет следующий вид: linux-source-Версия. Например, для ядра версии 2.6.24: linux-source-2.6.24. Самая последняя версия ядра в репозиториях Ubuntu называется просто linux-source, без указания версии на конце. Для установки исходных кодов последней версии ядра Ubuntu Linux, выполните команду:

sudo apt-get install linux-source

Эта команда скачивает исходники ядра и размещает их в директории /usr/src. На момент написания заметки последняя версия ядра, которая была скачана — 2.6.27, ее мы и будем использовать. Если мы теперь перейдем в директорию /usr/src и выполним команду ls, то увидим, что среди файлов присутствует файл linux-source-2.6.27.tar.bz2. Это и есть исходные коды ядра Linux (ядра Ubuntu).

Распаковываем исходный код ядра

Перейдем в директорию /usr/src и разархивируем ядро. Для этого выполните следующие команды:

cd /usr/src
sudo tar xjf linux-source-2.6.27.tar.bz2
sudo ln -s linux-source-2.6.27 linux

Для удобства мы создали символьную ссылку с именем linux, которая указывает на директорию с исходниками.

Конфигурация ядра

Теперь перейдем к конфигурированию ядра. Чтобы не создавать конфигурацию с нуля, возьмем за основу конфигурацию ядра, которая в данный момент используется. Получить текущую конфигурацию можно выполнив команду make oldconfig. Выполните в терминале:

cd /usr/src/linux
sudo make oldconfig

В результате выполнения команды make oldconfig создастся файл .config, содержащий параметры конфигурации ядра.

Получить справку по всем параметрам make для ядра Linux вы можете, выполнив команду make help.

Для изменения конфигурации ядра мы воспользуемся консольной утилитой menuconfig. Для ее запуска выполните:

sudo make menuconfig

Перед вами появится интерфейс, в котором вы можете включать или отключать определенные опции ядра:

Утилита Menuconfig

Для примера я включу опцию «NTFS write support». Для этого, нажимая кнопку Вниз, найдите пункт «File systems» и нажмите Enter.

Настройка ядра Linux - File systems

Вы окажетесь в меню настройки файловых систем. Найдите в этом списке пункт «DOS/FAT/NT Filesystems» и нажмите Enter.

Настройка ядра Linux - DOS/FAT/NT Filesystems

Перейдите к пункту «NTFS write support» и нажмите Пробел, рядом с пунктом появится звездочка, означающая, что данная опция будет включена в ядро.

Настройка ядра Linux - NTFS write support

Теперь выберите «Exit» (нажав кнопку Вправо и затем Enter) и выйдите из утилиты. Перед выходом из утилиты выскочит сообщение с вопросом — сохранить проделанные изменения, выберите Yes.

Компиляция ядра

Пришло время скомпилировать ядро с теми изменениями, которые мы внесли на предыдущем шаге. Для начала выполним команду, которая удалит файлы (если они имеются), оставшиеся от предыдущей компиляции:

sudo make-kpkg clean

Наконец, чтобы запустить компиляцию ядра, выполним команду:

sudo make-kpkg --initrd --append-to-version=-mykernel kernel_image kernel_headers

Ключ -append-to-version используется, чтобы добавить к имени файла образа ядра, который мы получим после компиляции, строку -mykernel, чтобы было проще идентифицировать свое ядро. Вместо -mykernel вы можете использовать любой префикс.

Компиляция ядра занимает довольно много времени и может длиться от нескольких десятков минут до нескольких часов, в зависимости от мощности вашего компьютера.

Установка (инсталляция) ядра

После компиляции ядра вы получили на выходе два файла: linux-image-2.6.27.18-mykernel_2.6.27.18-mykernel-10.00.Custom_i386.deb, linux-headers-2.6.27.18-mykernel_2.6.27.18-mykernel-10.00.Custom_i386.deb. Мы воспользуемся командной dpkg -i, которая автоматически установит ядро и пропишет его в ваш загрузчик GRUB (в файл /boot/grub/menu.lst). Отмечу, что ядро будет установлено, как ядро по умолчанию, поэтому если оно у вас не загрузится вам нужно будет загрузиться, используя ваше предыдущее ядро (оно должно быть в списке меню GRUB при загрузке компьютера) и вручную изменять файл menu.lst. Итак, для установки ядра выполните команды:

dpkg -i linux-image-2.6.27.18-mykernel_2.6.27.18-mykernel-10.00.Custom_i386.deb
dpkg -i linux-headers-2.6.27.18-mykernel_2.6.27.18-mykernel-10.00.Custom_i386.deb

Запуск системы с новым ядром

Проверим работоспособность системы с новым ядром. Перезагрузите компьютер. В меню загрузчика GRUB вы должны будете увидеть новый пункт, соответствующей вашему новому ядру, которое должно загрузиться по умолчанию. Если все пройдет успешно, то система запустится с новым ядром.

Понравилась статья? Поделить с друзьями:
  • Как собрать установщик программ для windows
  • Как собрать собственную сборку windows 10
  • Как собрать свою сборку windows 10 с программами
  • Как собрать свой образ windows 10
  • Как собрать проект с github в windows