Как собрать ядро linux под свое железо
Перейти к содержимому

Как собрать ядро linux под свое железо

  • автор:

Блог начинающего линуксоида.

Иногда может потребоваться собрать своё собственное ядро Linux. Причины для этого могут быть следующими:

  • вам нужно чистое ядро, без дистрибутивных патчей;
  • вы хотите наложить собственные патчи (коих очень много);
  • вы хотите собрать ядро под свою конфигурацию железа, выкинуть из него лишнее и/или заточить под определённые задачи;
  • вы хотите включить в состав ядра эксперементальный драйвер или файловую систему, которой нет в «ванильном» ядре (например ZFS или Raiser 4);
  • вам нужно будет пересобирать ядро при каждом его обновлении (качать «обновляющий патч», накладывать его и собирать ядро);
  • пересобранное ядро может не заработать, если в вашей системе используются какие-нибудь хаки для обеспечения работоспособности того или иного оборудования;
  • при неправильном конфигурировании ядра, особенно в случае неграмотного или бездумного наложения патчей, вы можете получить либо тормозящую до ужаса систему, либо лишиться её вовсе.

Простая сборка ядра без применения патчей.

Исходные коды ядра Linux находятся на сайте kernel.org. Там же находятся «обновляющие патчи». Что нам нужно? Качаем с сайта тарболл (архив) с последней стабильной версией ядра (на момент написания статьи, это версия 4.3). Качаем любым удобным способом. Далее нам потребуются инструменты для сборки:

sudo apt install build-essential gcc kernel-package patch
sudo apt-get build-dep linux

После того как установятся все необходимые инструменты, распакуйте архив с кодом ядра в любую удобную директорию. Пусть это будет /home/user/KERNEL, где «user» — имя пользователя системы. Далее откройте терминал и перейдите туда:

Осталось собрать ядро:

fakeroot make-kpkg -j 3 —initrd —append-to-version=-custom kernel_image kernel_headers #-j 3

Цифра 3 после j — это количество ядер вашего процессора + 1. То есть для двухядерного это 3, для 4-х ядерного это 5 и так далее.
-custom — здесь можете указать удобное имя для ядра, чтобы было легче его отличить от дистрибутивного.
kernel_image и kernel_headers — это само ядро и его заголовочные файлы соответственно. Headers необходимы для сборки драйверов и модулей ядра, а также для некоторых других целей. После выполнения этой команды, начнут появляться несколько вопросов по конфигурированию ядра. Так как мы всё оставляем по умолчанию, просто жмите Enter пока не начнётся сборка. В зависимости от мощности вашего компьютера, сборка может занять от 15-20 минут до нескольких часов. После сборки, в директории /home/user появятся два deb-пакета: ядро и заголовки. Установите их командой:

sudo dpkg -i linux-image-4.3*deb linux-headers-4.3*deb
sudo update-grub

и перезагрузитесь. В меню GRUB теперь можно будет выбрать для загрузки системы другое ядро.

Сборка ядра с применением патчей и дополнительной конфигурации.

В этот раз мы соберём оптимизированное ядро для работы со звуком и видео, а также для большей отзывчивости системы. Для этого мы применим два патча: так называемый патч для режима реального времени (PREEMPT RT) и патч для компилятора GCC, чтобы добавить дополнительные опции для процессорных оптимизаций. Для начала, что такое патч? Патч — это текстовый файл, который создаётся программой diff, содержащий в себе изменения кода в определённых частях, которые при применении патча, заносятся в нужные места. Так как RT-патч выходит с большим запаздыванием, последняя его версия — для ядра 4.1. Впрочем это не так важно. По той же схеме, качаем ядро 4.1 с kernel.org и распаковываем в директорию /home/user/KERNEL-CUSTOM. Теперь качаем патчи. PREEMPT_RT и GCC Patch. Из скачанных архивов, нам нужны файлы с расширением .patch, которые необходимо положить в каталог с исходным кодом ядра. То есть в /home/user/KERNEL-CUSTOM. Перед применением патчей нужно убедиться, что не будет никаких ошибок. Открываем терминал:

cd /home/user/KERNEL-CUSTOM
patch -p1 -i patch-4.1.13-rt15.patch —dry-run

Опция —dry-run позволяет симулировать применение патча, без внесения изменений в файлы. Если ошибок не обнаружено (см. скриншот) — примните патч уже без опции —dry-run. Аналогичные действия проведите и со вторым патчем. Не применяйте одновременно больше одного патча! Теперь нам нужно сконфигурировать наше ядро. На выбор нам предлагаются следующие варианты:

make config — в терминал будут поочерёдно выводиться вопросы о конфигурации той или иной подсистемы ядра. Крайне долгий и утомительный процесс. Забудем о нём 🙂
make oldconfig — будет задействована конфигурация работающего в данный момент ядра. Так как мы собираем своё с нуля, этот способ также бесполезен.
make defconfig — аналогично предыдущему, только значения будут по умолчанию. Такими, какими его задали разработчики ядра. Аналог первого способа сборки.
make menuconfig — псевдографический интерфейс на основе библиотеки Ncurses. На экран будет выводиться интерфейс с удобным иерархическим меню. Управления с помощью клавиш направления, пробела и клавиши TAB. Рекомендуется если вы собираете ядро в системе, не имеющей графической оболочки.
make gconfig — графический интерфейс на основе GTK, рекомендуется в окружениях GNOME, Mate, Xfce, Cinnamon, Unity и прочих, использующих GTK.
make xconfig — графический интерфейс на основе Qt. Рекомендуется в KDE. Так как в моей системе используется KDE, я воспользуюсь этим способом. Помимо этого есть ещё пара способов, но их применения ни чем особенным не отличается. Итак, после применения патчей, запускаем make xconfig и перед нами предстаёт вот это:

Первым делом выключаем dynticks. Для этого идём в Timers subsystem и выбираем Periodic timer ticks

Идём ниже и включаем параметр Full preemptible kernel (RT). Режим жёсткого реального времени.

Листаем ниже и в пункте Timer frequency выставляем частоту системных прерываний на 1000 Гц

Полностью выключаем любое энергосбережение. Это важно! Слева ищем пункт Power management and ACPI options и снимаем галочку с ACPI. Также выключаем энергосбережение процессора

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

fakeroot make-kpkg -j 3 —initrd —append-to-version=-rt-custom kernel_image kernel_headers #-j 3
sudo update-grub

На моём компьютере с процессором Intel Core i3-550 (3.2 ГГц), прирост производительности был довольно ощутимый. Но самое главное — при работе в LMMS и Kdenlive, исчезли периодические заикания рассинхронизация звуковой и видеодорожек, а также подвисания при сильной нагрузке на жёсткий диск. Вывод — работает! Напоследок опишу два модифицированных ядра, которые весьма популярны в кругах линуксоидов:

PF-kernel — самый популярный набор патчей от украинца Александра Наталенко (aka post-factum). Это набор патчей, которые не входят в основное ядро, но обеспечивают повышенную отзывчивость системы, предоставляют альтернативную подсистему гибернации, более быструю, нежели основная, а также уменьшают использование памяти с помощью техники объединения одинаковых страниц. В набор входят:

  • планировщик процессов BFS от Кона Коливаса (Con Kolivas) с дополнительными исправлениями от Альфреда Чена (Alfred Chen);
  • планировщик ввода-вывода BFQ от Паоло Валенте (Paolo Valente), Арианны Аванзини (Arianna Avanzini) и Мауро Маринони (Mauro Marinoni);
  • подсистема гибернации TuxOnIce от Найджела Каннингема (Nigel Cunningham);
  • реализация техники слияния одинаковых страниц в памяти UKSM от Най Ся (Nai Xia);
  • патч от Graysky, расширяющий список процессоров для оптимизации ядра компилятором (тот, что мы применили выше)

Zen-kernel — второй по популярности, но первый по количеству патчей набор. Zen Kernel использует комбинацию нескольких проектов, обновляет код через git-репозиторий, а также имеет несколько специфичных для Zen вещей, стремящихся удовлетворить большинство потребностей пользователей, реализовав их в одном ядре. Некоторые возможности патча: drm-next, wireless-testing, выбор планировщиков CPU (CFS/BFS), BFQ-планировщик ввода-вывода, aufs, unionfs, reiser4, tuxonice, PHC и многие другие вещи, которые замечательно подойдут для оптимизации настольных систем или ноутбуков. Всё это доступно в виде одного патча к ванильному ядру. Официальный сайт. GIT- репозиторий. Пакеты для Debian/Ubuntu.

На сегодня, пожалуй, всё. Больше информации вы можете найти в ссылках к статье. Всё описанное в статье проверено мной на многих конфигурациях.

# Голое железо

В этом туториале мы напишем простое 32х-битное ядро и загрузим его. Это первый шаг в создании вашей операционной системы. Здесь вы узнаете как создать минимальную систему, но не как нужно структурировать ваш проект.

# Настройка кросс-компилятора

Первым делом вам необходимо настроить GCC для i686-elf. Вы еще не модифицировали свой компилятор, чтобы дать ему знать о существовании вашей операционной системы, поэтому мы будем использовать стандартную сборку под i686-elf, который предоставляет инструменты для System V ABI.

Вы не сможете правильную сборку вашей ОС без кросс-компилятора.

Вы не сможете корректно завершить этот туториал с x86_64-elf, потому что GRUB способен загружать только 32х-битные мультизагрузочные

(opens new window) ядра. Если это ваша первая ОС, то следует начать с 32х-битного ядра.

# Обзор

Теперь вам понадобится три входных файлов:

  • boot.s — точка входа ядра, которая настроит среду процессора,
  • kernel.c — код вашего ядра,
  • linker.ld — информация компоновки файлов выше.

# Загружаем ядро ОС

Для запуска ОС необходимо иметь ПО, которое сможет загрузить её. Такое ПО называют загрузчиками, мы будем использовать GRUB. Ядро получает от загрузчика минимальную среду, в которой ещё не настроен стек, виртуальная память, подключенные устройства и так далее.

Чтобы сообщить загрузчику как загрузить ОС будем использовать стандарт мультизагрузки, который описывает простой интерфейс между загрузчиком и ядром. Это работает благодаря глобальным переменным, которые ищет загрузчик.

В этом примере используется ассемблер GNU, который является частью кросс-компилятора, настроенного ранее.

Теперь вы можете собрать boot.s , используя:

# Реализация ядра

После написания базового загрузчика можно использовать более высокоуровневые языки, например C/C++.

# Отдельные и размещённые среды

Если вы уже использовали C/C++ для пользовательских прогрмамм, то вы использовали так называемую резмещённую (англ. hosted) среду, что означает наличие стандартной библиотеки языка и различных удобств, доступных во время выполнения (англ. runtime). Также сущесвуют отдельные (англ. freestanding) среды, которые мы и будем использовать. Это означает, что у нас ничего не будет из стандартного набора, и мы должы будет реализовать их самостоятельно. Тем не менее, у нас будут некоторые заголовочные файлы, которые являются частью компилятора, а не стандарта C.

  • stdbool.h — тип для булевых (логических) значений;
  • stddef.h — size_t и NULL ;
  • stdint.h — intx_t и uintx_t для точных размеров переменных (если вы использовали short вместо uint16_t , то при изменении размера типа всё может неожиданно сломаться;
  • float.h , iso646.h , limits.h , и stdarg.h .

# Пищем ядро на C

Для начала мы напишем простое ядро, которое будет использовать текстовый режим VGA (адрес 0xB8000 ). Оно будет запоминать положение следущего символа в буффере и выводить простые симфолы, но буде поддержки переноса строк. Добавление поддержки этой функции может стать вашей первой самостоятельной задачей. Потратьте немного времени, чтобы понять собственный код.

Текстовый режим (также как и BIOS) является устаревшим на новых устройствах, т. к. UEFI поддерживает только буффер пикселей. Для будущей совместимости вы можете начать с этого. Просим загрузчик настроить графический буффер соответствующим флагом мультизагрузки, либо самостоятельно используем вызовы VESA VBE. В отличии от текстового режима VGA, буффер имеет пиксели, что озачает ручную отрисовку каждого символа, поддержку пролистывания (скролла), перемещения курсока и т. д. Также значит, что вам потребуется другой terminal_putchar и шрифт (изображения для каждого символа). Все дистрибутивы Linux поставляют экранные шрифты (англ. PC Screen Fonts), которые вы можете использовать.

Обратите внимание, что в коде мы хотели использовать обычную функцию C strlen , которая является частью стандартной библиотеки C, которой у вас нет. Вместо этого мы положились на отдельный заголовок stddef.h , и собственную реализацию. И так вам придётся делать с каждой функцией из стандартной библиотеки, которую захотите использовать (заголовки для отдельной среды предоставляют только типы данным и макросы).

Пример выше можно собрать, выполнив:

Заметим, что код примера использует некоторый функционал из сборщика GNU для C99.

# Пишем ядро на C++

Написать ядро на C++ легко, но стоит помнить, что не весь функционал языка доступен. К примеру, выбрасывание исключений требует особой поддержи в среде выполнения, а также выделений памяти. В нашем случае просто добавляется extern "C" для главной функции. Важно, чтобы функция kernel_main была объявлена как видимостью для C, иначе компилятор добавит информацию в название сборки (англ. assembly). Это делает невозможным вызов этой функции из ассеблера.

Сохраните всё в файл kernel.cpp (или с вашим любимым расширением файла с кодом на C++). Вы можете скомпилировать этот файл, используя:

# Компоновка ядра

Выше упомянутые boot.s и kernel.c содержат части нашего ядра, и для создания полноценного ядра остаётся только скомпоновать их собранные версии в программу ядра, которую загрузчик сможет использовать. При сборке пользовательских программ мы используем стандартные скрипты компоновки инструментов разработки. В нашем случае нужно написать собственный скрипт. Ниже пример linker.ld :

Мы используем компилятор в качестве компоновщика из-за большего контроля процесса. Не забудьте, что если вы использовали C++ при написании ядра, то нужно будет использовать компилятор для C++.

Вы можете скомпоновать ядро командой ниже:

Некоторые туториалы предлагаю использовать i686-elf-ld вместо компилятор Note: Some tutorials suggest linking with i686-elf-ld rather than the compiler, но это не позволяет выполнять компилятору некоторые задачи во время компоновки.

Теперь файл my_kernel.bin — ваше ядро (другие файлы более не нужны)! The file myos.bin is now your kernel (all other files are no longer needed). Note that we are linking against libgcc, which implements various runtime routines that your cross-compiler depends on. Leaving it out will give you problems in the future. If you did not build and install libgcc as part of your cross-compiler, you should go back now and build a cross-compiler with libgcc. The compiler depends on this library and will use it regardless of whether you provide it or not.

# Проверяем ядро

# Проверка мультизагрузочности

Проверить присутствие заголовка мультизагрузочности v1 можно при помощи GRUB:

Важно, чтобы заголовок находился в первых 8 КиБ с выравнивание в 4 байта, иначе GRUB выйдет с кодом 1. Поверка v2 заголовка проводится с аргументом —is-x86-multiboot2 . Чтобы не проверять возвращаемый код, можно использовать sh-скрипт:

# Сборка загрузочного CD-ROM образа

Для начала нужно создать файл boot/grub/grub.cfg в папке isodir , который будет хранить загрузочную конфигурацию:

Далее переместим скомпилированное ядро myos.bin в isodir/boot и соберём сам образ:

# Тестовый запуск

После загрузки вы, скорее всего, увидите "Hello, kernel World!".

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

# Что дальше?

Только что на свет появилась ещё одна ОС, поздравляем! Но это только начало. Вот что вы можете сделать:

# Поддержка переносов строки в драйвер терминала

Текстовый режим VGA на месте \n хранит другой символ, поэтому следует добавить проверку в terminal_putchar , которая будет увелимивать terminal_row и сбрасывать terminal_column .

# Пролистывание терминала

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

# Цветные ASCII-арты

Текущий терминальный драйвер поддерживает только 16 цветов (из них 8 фоновых), поэтому вам понадобится нормальный VGA драйвер.

# Глобальные конструкторы

This tutorial showed a small example of how to create a minimal environment for C and C++ kernels. Unfortunately, you don’t have everything set up yet. For instance, C++ with global objects will not have their constructors called because you never do it. The compiler uses a special mechanism for performing tasks at program initialization time through the crt*.o objects, which may be valuable even for C programmers. If you combine the crt*.o files correctly, you will create an _init function that invokes all the program initialization tasks. Your boot.o object file can then invoke _init before calling kernel_main .

# Организация ОС

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

# Дальнейшее изучение

# Частые вопросы

# Почему используется мультизагрузочный заголовок? Разве GRUB не умеет работать с ELF?

GRUB может загружать множество разных форматов. Однако, этот туториал описывает создание ядра, сомвестимого со стандартам мультизагрузочности, что означает поддержку и другимим загрузчиками.

# GRUB очищает секцию BSS перед загрузкой ядра?

Да. Для ELF секция .bss автоматически определяется и очищается (хотя в стандарте мультизагрузочности нет чётких указаний). Для других форматов вы можете использовать флаг №16 мультизагрузочного заголовка и не нулевое значение для поля bss_end_addr .

# [GRUB] Error 13: Invalid or unsupported executable format

Chances are the Multiboot header is missing from the final executable, or it is not at the right location. If you are using some other format than ELF (such as PE), you should specify the AOUT kludge in the Multiboot header. The grub-file program describe aboveand "objdump -h" should give you more hints about what is going on. It may also happen if you use an ELF object file instead of an executable (e.g. you have an ELF file with unresolved symbols or unfixable relocations). Try to link your ELF file to a binary executable to get more accurate error messages. A common problem when your kernel size increases, is that the Multiboot header does no longer appear at the start of the output binary. The common solutions is to put the Multiboot header in a separate section and make sure that section is first in the output binary, or to include the Multiboot header itself in the linker script.

# [QEMU] Could not read from CD-ROM (code 0009)

If your development system is booted from EFI it may be that you don’t have the PC-BIOS version of the grub binaries installed anywhere. If you install them then grub-mkrescue will by default produce a hybrid ISO that will work in QEMU. On Ubuntu this can be achieved with: apt-get install grub-pc-bin.

Сборка ядра Linux 5.12.12 c LLVM 12 + Clang и LTO оптимизацией

Технический прогресс не стоит на месте, появляются новые компьютерные архитектуры, компиляторы становятся умнее и генерируют более быстрый машинный код. Современные задачи требуют все более креативного и эффективного решения. В данной статье пойдет речь, на мой взгляд, про один из самых прогрессивных тулчейнов 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 и есть подводные моменты, которые будут рассмотрены в данной статье.

Так как в новом ядре фиксится немалое количество багов для работы с моим оборудованием(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
  • Генерируется объектный файл. Объектный файл содержит в себе машинный код для компьютера, и специальные служебные структуры, в которых все еще есть неизвестные адреса функций и данных, поэтому этот файл все еще не может быть запущен на исполнение. Чтобы разрешить неизвестные адреса, был добавлен этап линковки.

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

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

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

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

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

▍Установка 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 версии, думаю это произойдет уже через пару дней):

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

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).

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

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

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

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

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

Команда 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.

После установка 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», и вставим после строки:

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

Если вкратце мы используем -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).

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

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

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

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

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

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

Самое первое, что надо сделать в 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.

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 $-$pkgver build \ надо добавить строки:

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

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

Дальше нам надо установить все 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 и развитию навыка пересборки ПО не ломая систему.

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

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

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

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

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

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

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 и сохраняем новый конфигурационный файл. Далее идет список команд для сборки и установки нового ядра.

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

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

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

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

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

1) set -euo pipefail — скрипт переходит в строгий режим, в случае ошибок скрипт завершается с ошибкой. Является хорошим тоном, при написании bash скриптов. Скрипт проверяет запущен ли он под рут, если запущен под рут, то выдает ошибку и завершается. Загружается настройки пользователя из файла $/.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 .

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

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

Ядерная физика для домохозяек v.3

Достаточно давно была написана отличная статья, послужившая верой и правдой многим линуксоидам, кто самостоятельно собирал своё ядро. Называлась она « Ядерная физика для домохозяек, версия 2 » . Ранее, когда деревья были выше, небо голубее, а настольные компьютеры не столь производительны, сборка ядра под своё железо могла внести весомый вклад в увеличение производительности железного друга. Теперь это уже не столь важно и в большинстве случаев даже не нужно, ибо прирост будет незначительным. Да и среднестатистический линуксоид как-то обмельчал, « скуксился » что ли.

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

Вступление или подготовка к сборке ядра

Для сборки можно использовать ядро с kernel.org. Если вам удобнее собрать ядро, поставляемое с вашим дистрибутивом, вы можете смело пропустить этот шаг.

Пройдите по указанной выше ссылке и скачайте ядро Latest Stable Kernel . Должен скачаться файл примерно с таким наименованием: linux-3.6.11.tar.bz2 .

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

Рекомендация по собственно сборке ядра одна на все дистрибутивы, что естественно. А вот инструмент для сборки вполне возможно, что придётся доустановить. Для gentoo это пакет gentoo-sources (если предполагается сборка дистрибутивного ядра). Для дебиана понадобится установить целую пачку пакетов, для арча понадобится эта инструкция.

Перед сборкой неплохо сесть и подумать какое же ядро собрать. Ядро может быть:

— монолитным

такое ядро полностью грузится при старте системы и остаётся в оперативной памяти до выключения машины. Его компоненты нельзя изменить, невозможно подгружать и выгружать модули благодаря чему ядро становится нечувствительным к различным троянским программам, направленным на подмену оригинальных модулей своими — это просто невозможно. Но с другой стороны монолитность ядра привносит и некоторые минусы, такие как невозможность установить стороннюю прошивку или проприетарный драйвер для видеокарты (ведь его модуль нельзя будет подгрузить!). То есть для домашних машин лучше не использовать монолитные ядра, а вот для серверов — самое оно.

— модульным

это ядро напротив позволит включать многие компоненты не жёстко, а модульно (соответственно своему названию), что уменьшит размер ядра и сделает возможным. да, загрузку и выгрузку нужных модулей. В готовых дистрибутивах для создания такого ядра используется initramfs (раньше — initrd). Но при сборке под себя можно обойтись и без него, достаточно лишь жёстко встроить поддержку файловой системы и контроллёра HD корневого раздела для того, чтобы система смогла определить их и загрузиться.

в чём разница между initrd и initramfs прочитать.

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

Итак, вы скачали ядро и заплатки. Переместите их в каталог /usr/src/ и сами перейдите в него. Теперь следует распаковать исходники ядра и архивы с заплатками, наложить заплатки:

При наложении заплаток есть лишь один нюанс: сначала накладывается заплатка для обновления версии ядра ( patch-$VERSION.bz2 как дано выше) и уже затем все остальные.

Обратите внимание на вывод команды patch . Если заплатка идеально подходит к ядру, то в выводе должны быть только строчки patching file . . Строка Hunk #1 succeeded at. означает что заплатка наложена успешно, но место наложения сдвинуто на несколько строк. Если же вы увидите слово Failed — заплатка не подходит. Лучше удалить каталог linux-3.6.11/ и начать все сначала уже без этой заплатки.

Далее могут выполнены следующие команды:

  • make mrproper — очистит каталог от мусора предыдущей сборки
  • make menuconfig — запустит окно настроек ядра
  • [ * ] — опция включена жёстко
  • [M] — опция включена модульно
  • [ ] — опция отключена

Вы можете воспользоваться поиском по параметрам ядра, для этого нажмите "/" (слеш) и введите искомое. Также не забывайте о справке: остановитесь на параметре, подробное описание которого вам хотелось бы видеть, и выбирайте "Help" внизу экрана.

General setup

Содержит общие настройки

gen

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

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

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

Поддержка ядром своп-файла. Включаем.

System V IPC — механизм связи между процессами. Набор библиотечных функций и вызовов ядра, позволяющий процессам обмениваться информацией. Некоторые программы требуют этого механизма.

POSIX Message Queues — очередь для сообщений формата POSIX с использованием приоритетов. Часть механизма связи между процессами. Нужно, если запускать программы написанные под этот формат, например с ОС Solaris.

BSD Process Accounting — поддержка дополнительных сведений о процессах (время запуска, владелец, командная строка запуска, использование памяти). Полезно для контроля процессов.

Auditing support — включение механизма проверки ядра. Например используется системой SELinux (система расширенной безопасности для Linux).

Enable system-call auditing support — включение системных вызовов для механизма проверки ядра.

Сохранять настройки ядра в нем самом. Это полезно, если у Вы удалите папку с исходниками ядра, а потом захотите немного изменить ядро.

Если эта опция включена, вы сможете получать параметры текущего ядра из /proc/config.gz

Рекомендуется включить. Пригодится.

Поддержка группирования процессов. Используется такими подсистемами как CPUSETS, CFS, контроль памяти или устройства изоляции.

Позволяет двум процессам в разных виртуальных средах иметь один и тот же pid . Эта возможность делает реальными такие сценарии, как апгрейд сервера без необходимости его перезагрузки.

Включает поддержку интерфейса некоторых файловых систем (таких как debugfs). Предназначена для эффективного механизма передачи больших объёмов данных из пространства ядра в пользовательское пространство.

Если собирается ядро без оных, следует отключить опцию.

Оптимизация кода ядра по размеру. Может быть полезно для создания загрузочных дискет. В обычных случаях не требуется.

Включение расширенной поддержки профилирования (например, OProfile). Обычно не нужно.

Enable loadable module support

loadable

Создание модульного ядра. Module unloading — возможность выгрузки модулей.

Forced module unloading — возможность принудительной выгрузки модуля, даже если оно еще нужно ядру

Enable the block layer

block

Поддержка блочных устройств. Если эта опция отключена, некоторые файловые системы станут недоступны (например, ext3), SCSI и USB устройства не смогут распознаться.

Следует выбрать из списка типы разделов, поддержка которых вам необходима. PC BIOS для машин с обычным BIOS (на разделах MBR), EFI GUID — EFI BIOS (на разделах GPT). В общем, ясно из названий.

Processor type and features

processors

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

Повысит отзывчивость десктопных приложений. Как отметил в комментариях UlvHare в плане запуска таких приложений как Firefox Low-Latency Desktop Preemptible Mode хуже, чем Voluntary.

Для старых систем SMP, которые не имеют надлежащей поддержки ACPI.

Поддержка платформ, отличных от PC.

Поддержка паравиртуализации (например, для Xen).

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

Включение технологии Hyperthreading.

Для процессоров Intel Core, AMD Athlon64/Phenom.

Для поддержки UEFI. В данном примере она отключена.

Power management and ACPI options

power

Поддержка Suspend to RAM — сохранение состояния операционной системы в оперативной памяти.

Поддержка Suspend to Disk — иначе говоря, режим гибернации. Потребуется включение swap-раздела. В Default resume partition можно прописать путь к swap. Или оставить пустым с последующим внесением параметра resume в строку загрузчика. Лучше прописать к загрузчику.

Поддержка интерфейса управления конфигурацией и питанием (ACPI).

Управление настройками частоты процессора: 'performance' governor обеспечивает наибольшую производительность, 'powersave' governor будет стараться снижать частоту процессора, чем увеличит работу от батареи, 'ondemand' — нечто среднее. Рекомендуется выбрать 'ondemand' в качестве "умолчательного" в Default CPUFreq governor .

Bus options (PCI etc.)

bus

PCI support обеспечивает поддержку шины PCI.

Поддержка карт PCMCIA. Чаще всего встречаются на ноутбуках.

"Горячее" (на лету) подключение PCI-устройств. Позволяет добавлять и удалять PCI-устройства, даже когда машина включена и работает. В принципе, можно и отключить, поскольку чаще всего эта возможность не используется.

Executable file formats / Emulations

exec

Поддержка формата исполняемых файлов ELF. Обязательна к включению.

Networking support

net

В подпунктах включается поддержка протокола TCP/IP, в частности возможность включения/отключения IPv6. Поскольку автор не является специалистом в данной области, детально раздел не рассматривается. Сетевые администраторы, безусловно, найдут для себя множество полезных опций. Для домашнего же использования рекомендуется оставить опции по-умолчанию.

Скорее всего включать не понадобится. Обеспечивает поддержку инфракрасного модуля.

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

Bluetooth device drivers позволит выбрать из списка поддержку определённого устройства.

Для ноутбуков, где, как правило, радиопередатчик wifi-чипа включается нажатием клавиши "Kill Switch". Если эта клавиша не нажата и передатчик не включен, wi-fi не заведётся. Кстати, если параллельно у вас установлена Windows, обязательно оставьте под ней включенной кнопку wi-fi. В противном случае в linux при попытке включить интерфейс wlan вам будут объяснять, что Kill Switch отключен и включать его будет бесполезно.

Поддержка стандарта 802.11 для беспроводных сетей.

Device Drivers

device

Maintain a devtmpfs filesystem to mount at /dev — Монтировать файловую систему tmpfs.

Select only drivers that don't need compile-time external fir — выбирать лишь те драйверы, которые не требуют прошивки. В зависимости от вашего оборудования эту опцию, возможно, придётся отключить.

Include in-kernel firmware blobs in kernel binary — включить прошивку в ядро.

External firmware blobs to build into the kernel binary — требуется для указания пути к блобам.

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

Первое уже вряд ли нужно. Но если у вас есть устройства ( раньше это были все принтеры ), требующие подключения по параллельному порту — включите опцию.

Plug and Play включаем.

Блочные устройства. Loopback device support включить обязательно.

RAM block device support нужен при сборке ядра с initrd, в противном случае — отключить: "выбирайте Y, если хотите использовать часть оперативной памяти как блочное устройство. В этом устройстве вы сможете создавать файловую систему, и использовать ее как обыкновенное блочное устройство (такое как жесткий диск). Обычно его используют для загрузки и сохранения минимальной копии корневой файловой системы при загрузке с флоппи диска, CD-ROM при установке дистрибутива, или на бездисковых рабочих станциях."

Просмотреть и принять решение включать или не включать то или иное устройство. У автора данный раздел вообще пуст.

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

Поддержка устройств SATA. AHCI (Advanced Host Controller Interface) — механизм, позволяющий устройствам SATA пользоваться расширенными функциями.

Опции, обеспечивающие использование логических томов и программных RAID-массивов.

В Ethernet driver support следует выбрать поддержку устройства вашей сетевой карты Ethernet. PPP может понадобиться тем, кто подключается к интернету с использованием соответствующего протокола. USB Adapters — при наличии у вас поднобного адаптера для выхода в сеть. Wireless LAN — для использования беспроводных сетей стандарта IEEE 802.11. Здесь нужно выбрать соответствующий вашему оборудованию драйвер.

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

Поддержка видео в Linux.

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

Включение поддержки AGP. В примере для видеокарт Intel и Radeon.

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

Включить DRM — Direct Rendering Manager. Современная вещь, рекомендуется.

Управление поддержкой фреймбуфера. EFI-based Framebuffer Support нужен для систем с UEFI.

Поддержка кадрового буфера в консоли. Включаем.

Включаем пингвинов при загрузке системы 😉

Включение поддержки звуковых устройств. Выбор своего железа из списка.

Аналогично, только для USB-устройств.

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

Firmware Drivers

firmware

Для включения в ядро сторонних прошивок. Если вы не уверены, что вам нужны какие-либо опции, рекомендуется оставить вариант по-умолчанию.

File systems

filesys

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

Kernel hacking

kern_hack

Если компьютер завис и не реагирует на команды переключения консоли. Вы можете нажать Alt-PrintScreen-s для записи кеша дисков или Alt-PrintScreen-i (Убить все процессы за исключением init). Механизм нажатия такой: — Нажать Alt — Нажать PrintScreen — Отпустить Alt — Нажать нужную кнопку — Отпустить все.

Когда эта опция включена, можно монтировать debugfs в /etc/fstab . Таким образом мы получим директорию /sys/kernel/debug , что очень небесполезно в частности для обладателей двух видеокарт.

Security options

secur

Позволяет увеличить защищенность системы. Можно, например, запретить запуск программ с привилегиями root без специального ключа или с помощью системы SELinux ограничить возможности доступа к файлам самого root. Изменяйте эти опции только если вы знаете что делаете.

Cryptographic API

cryp

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

Virtualization

virt

Нужно включить, если планируется использовать виртуализацию (конкретно: VirtualBox или QEMU). В противном случае не отмечайте ничего.

Library routines

lib

Используется для предоставления модулям функций CRC32 CRC32c. Можете включить

Послесловие

Итак, настройка ядра закончена. Теперь коснёмся вопроса о сборке. Процесс сборки и установки ядра можно выполнить одной командой:

Когда ядро будет собрано, у Вас должны появиться следующие файлы:

и каталог модулей

И последним шагом подправим строки загрузчика, чтобы можно было загрузиться с новым ядром (пример для grub-legacy):

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

Единственное, что там не указано: как в этом случае будут выглядеть настройки загрузчика. В них больше не будет указания на initrd — последней строки — и ram0:

Если сборка не первая, вы увидите в /boot старое ядро, оно будет выглядеть как vmlinuz-$KERNEL-VERSION.old . В случае неудачной сборки, вы всегда можете загрузиться со старым ядром.

P.S: при указанном способе сборки в gentoo автоматически не появится initrd. Если он вам нужен, наиболее простой способ: после сборки ядра использовать для его создания genkernel :

P.S2: не забудьте добавить своего пользователя в соответствующие группы. Если нет звука, прежде всего проверьте, добавлен ли пользователь в группу audio , если не заводится камера — в группу video .

Да, надо бы ещё отметить, что при необходимости можно обратиться к документации ядра. Располагаются эти файлы в каталоге /usr/src/linux/Documentation . Вот, вроде бы, и всё.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *