Руководство по самостоятельной компиляции ядра Linux

Вы можете быть заинтересованы в самостоятельной компиляции ядра Linux по многим причинам:

  • Пробуем более новое ядро, чем то, которое предоставляет ваш дистрибутив Linux
  • Собираем ядро с другим набором конфигурационных опций или драйверов
  • Любопытство.

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

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

Предварительные условия

Для сборки чего-либо (в контексте программного обеспечения):

  1. Исходный код
  2. Зависимости для сборки

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

Основные сведения о версиях Linux

На данный момент существует 4 «версии» ядра Linux.

Эти «версии» Linux, в порядке убывания потока разработки, следующие:

  1. Дерево linux-next: Любой код, подлежащий слиянию в кодовую базу Linux, сначала сливается в дерево linux-next. Это самое новое, но и «наименее стабильное» состояние ядра Linux. Большинство разработчиков и тестировщиков ядра Linux используют его для улучшения качества кода, который впоследствии будет использоваться Линусом. Будьте осторожны!
  2. RC/Mainline релизы: Линус берет из дерева linux-next и создает начальный релиз. Бета-версия этого релиза называется RC-релизом (Release Candidate). После выпуска RC-релиза Торвальдс принимает только исправления ошибок и исправления, связанные с регрессией производительности. Линус продолжает выпускать RC-версию ядра каждую неделю до тех пор, пока не будет удовлетворен кодом (с учетом отзывов пользователей). Суффикс -rc, за которым следует число, добавляется для обозначения версии RC-релиза.
  3. Стабильные релизы: Как только Линус считает, что последний RC-релиз был стабильным, он выпускает финальный, «публичный» релиз. Стабильный релиз поддерживается еще несколько недель. Это то, что используют такие передовые дистрибутивы Linux, как Arch Linux и Fedora Linux. Я рекомендую сначала попробовать этот вариант перед linux-next или любым RC-релизом.
  4. LTS-релизы: Последний стабильный релиз данного года поддерживается еще несколько лет. Обычно это более старый выпуск, но он активно поддерживается с исправлениями безопасности. Стабильный выпуск Debian использует LTS-выпуск ядра Linux.

Для целей данной статьи я буду использовать последний доступный стабильный релиз. На момент написания статьи это 6.5.5.

Подготовка системы

Поскольку ядро Linux написано на языке программирования C, для компиляции ядра Linux необходим, как минимум, компилятор C. Существуют и другие подобные зависимости, которые могут присутствовать или отсутствовать на вашем компьютере. В этом руководстве мы рассмотрим компиляцию ядра Linux с помощью GNU C Compiler (GCC):

sudo pacman -S base-devel bc coreutils cpio gettext initramfs kmod libelf ncurses pahole perl python rsync tar xz

Команда установки для пользователей Debian и его производных:

sudo apt install bc binutils bison dwarves flex gcc git gnupg2 gzip libelf-dev libncurses5-dev libssl-dev make openssl pahole perl-base rsync tar xz-utils

Команда установки для Fedora и ее производных:

sudo dnf install binutils ncurses-devel \ /usr/include/{libelf.h,openssl/pkcs7.h} \ /usr/bin/{bc,bison,flex,gcc,git,gpg2,gzip,make,openssl,pahole,perl,rsync,tar,xz,zstd}

Получение исходных кода ядра Linux

Перейдите на сайт kernel.org и на странице найдите первый стабильный релиз. Вы не сможете его пропустить, так как это самый большой желтый квадрат ;)

Вы можете скачать tarball, щелкнув на большом желтом квадрате. Пока вы находитесь здесь, загрузите и соответствующий файл PGP-подписи. Он пригодится, когда мы будем проверять tarball в дальнейшем. Он имеет расширение .tar.sign.

Проверка подлинности tar

Как узнать, поврежден ли только что скачанный tar-архив или нет? На индивидуальном уровне поврежденный tarball просто потратит ваше драгоценное время, но если это делается для организации, вы можете облегчить задачу злоумышленнику.

Для проверки целостности нашего tarball нам нужен сам tarball. На данный момент он сжат с помощью алгоритма сжатия XZ. Поэтому для распаковки архивного файла .tar.xz я буду использовать утилиту unxz (это всего лишь псевдоним xz --decompress).

unxz --keep linux-*.tar.xz

После распаковки мы получим открытые ключи GPG, которые используют Линус Торвальдс и Грег Кейч. Эти ключи используются для подписи tarball.

gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org

Вы должны получить результат, аналогичный тому, что я получил на своей машине:

$ gpg2 —locate-keys torvalds@kernel.org gregkh@kernel.org
gpg: /home/pratham/.gnupg/trustdb.gpg: trustdb created
gpg: key 38DBBDC86092693E: public key «Greg Kroah-Hartman « imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: key 79BE3E4300411886: public key «Linus Torvalds « imported
gpg: Total number processed: 1
gpg:               imported: 1
pub   rsa4096 2011-09-23 [SC]
      647F28654894E3BD457199BE38DBBDC86092693E
uid           [ unknown] Greg Kroah-Hartman 
sub   rsa4096 2011-09-23 [E]

pub   rsa2048 2011-09-20 [SC]
      ABAF11C65A2970B130ABE3C479BE3E4300411886
uid           [ unknown] Linus Torvalds 
sub   rsa2048 2011-09-20 [E]

После импорта ключей Грега и Линуса целостность tarball можно проверить с помощью флага --verify; примерно так:

gpg2 --verify linux-*.tar.sign

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

$ gpg2 --verify linux-*.tar.sign
gpg: assuming signed data in 'linux-6.5.5.tar'
gpg: Signature made Saturday 23 September 2023 02:46:13 PM IST
gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
gpg: Good signature from "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

Прошу не продолжать, если вы не видите сообщения с текстом gpg: Good signature!

Вы можете смело игнорировать предупреждение, которое гласит: WARNING: This key is not certified with a trusted signature! Нет никаких признаков того, что подпись принадлежит владельцу. Мы получили ключи из писем Линуса и Грега, и нам нет нужды беспокоиться об этом предупреждении.

Распаковка tar

Если вы находитесь здесь, это означает, что проверка целостности вашего tar-архива завершилась успешно. Теперь настало время извлечь из него исходный код ядра Linux.

Это довольно просто, просто выполните tar -xf на tarball, например, так:

tar -xf linux-*.tar

Опция -x используется для задания извлечения, а tar информируется об имени файла tarball с помощью опции -f.

Извлечение займет несколько минут.

Конфигурирование ядра Linux

Процесс сборки ядра Linux ищет файл .config. Как следует из названия, это конфигурационный файл, в котором указаны все возможные параметры конфигурации ядра Linux. Необходимо иметь такой файл.

Два способа получения этого .config файла для ядра Linux:

  1. Использование конфигурации вашего дистрибутива Linux в качестве базовой (рекомендуется)
  2. Использование стандартной, общей конфигурации

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

Использование конфигурации, предоставляемой дистрибутивом

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

Файл конфигурации ядра Linux вашего дистрибутива будет находиться в одном из двух мест:

  • Большинство дистрибутивов Linux, таких как Debian и Fedora, и их производные будут хранить его по адресу /boot/config-$(uname -r).
  • Некоторые дистрибутивы Linux, такие как Arch Linux имеют его встроенным в само ядро Linux Поэтому он будет доступен по адресу /proc/config.gz.

Если у вас есть оба места назначения, предпочтите использовать /proc/config.gz, поскольку он находится в файловой системе, доступной только для чтения, и, следовательно, не подвержен вмешательству. Войдите в каталог, содержащий распакованный tarball.

cd linux-*/

Затем скопируйте конфигурационный файл вашего дистрибутива Linux:

## Debian and Fedora's derivatives:
cp /boot/config-"$(uname -r)" .config
## Arch Linux and its derivatives:
zcat /proc/config.gz > .config

Обновление конфигурации

После этого настало время «обновить» конфигурационный файл. Существует большая вероятность того, что конфигурация, которую предоставляет ваш дистрибутив, старше, чем ядро Linux которое вы собираете.

Это относится и к таким передовым дистрибутивам Linux, как Arch Linux и Fedora. Ни один из них не выпускает обновления только потому, что доступна новая версия. Они проводят QA, на что требуется время. Поэтому даже самое свежее ядро, предлагаемое вашим дистрибутивом, будет отставать от того, что вы получите с сайта kernel.org. Для обновления существующего файла .config используется команда make с целевым olddefconfig. В более подробном виде это olddefault configuration.

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

Оригинальный файл .config переименовывается в .config.old в качестве резервной копии, а новые изменения записываются в .config.

make olddefconfig

Следующий результат получен на моей машине:

$ file .config
.config: Linux make config build file, ASCII text
$ make olddefconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/menu.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
.config:8593:warning: symbol value 'm' invalid for USB_FOTG210_HCD
.config:8859:warning: symbol value 'm' invalid for USB_FOTG210_UDC
#
# configuration written to .config
#

Для пользователей Debian и его производных

Debian и его производные используют сертификат для подписи модулей ядра. По умолчанию этот сертификат на вашем компьютере отсутствует.

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

./scripts/config --file .config --set-str SYSTEM_TRUSTED_KEYS ''
./scripts/config --file .config --set-str SYSTEM_REVOCATION_KEYS ''

Невыполнение этой команды приведет к сбою сборки в дальнейшем, когда вы будете собирать ядро Linux Вы были предупреждены.

Использование пользовательской конфигурации

Если вы изучаете сборку ядра Linux для целей обучения разработке ядра, то вам следует следовать именно этому пути.

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

  • defconfig: Конфигурация по умолчанию.
  • allmodconfig: Основываясь на текущем состоянии системы, собирать элементы как загружаемые модули (вместо встроенных), когда это возможно.
  • tinyconfig: Крошечное ядро Linux

Поскольку цель tinyconfig будет собирать только несколько элементов, время сборки, естественно, будет быстрее. Лично я использую его по следующим причинам:

  1. Проверка корректности изменений, внесенных в код/цепочку инструментов, и компиляция кода.
  2. Тестирование только нескольких избранных функций в виртуальной машине.
    При сборке ядра Linux для машин ARM или RISC-V вам, скорее всего, понадобятся DTB (двоичные файлы дерева устройств). Цель tinyconfig не позволит включить опцию сборки DTB, и ядро, скорее всего, не запустится. Также можно использовать QEMU для загрузки ядра Linux без DTB. Но в данной статье это не рассматривается. Возможно, вы прокомментируете и дадите мне знать, чтобы я рассказал об этом как-нибудь позже Вы должны использовать цель defconfig, если не знаете точно, что делаете. Ниже показано, как это выглядит на моем компьютере:
    $ make defconfig
      HOSTCC  scripts/basic/fixdep
      HOSTCC  scripts/kconfig/conf.o
      HOSTCC  scripts/kconfig/confdata.o
      HOSTCC  scripts/kconfig/expr.o
      LEX     scripts/kconfig/lexer.lex.c
      YACC    scripts/kconfig/parser.tab.[ch]
      HOSTCC  scripts/kconfig/lexer.lex.o
      HOSTCC  scripts/kconfig/menu.o
      HOSTCC  scripts/kconfig/parser.tab.o
      HOSTCC  scripts/kconfig/preprocess.o
      HOSTCC  scripts/kconfig/symbol.o
      HOSTCC  scripts/kconfig/util.o
      HOSTLD  scripts/kconfig/conf
    *** Default configuration is based on 'defconfig'
    #
    # configuration written to .config
    #

Изменение конфигурации

Вы создали файл .config каким-то способом. Либо вы использовали тот, который используется в вашем дистрибутиве Linux, и обновили его, либо вы создали его с помощью defconfig.

В любом случае, вы ищете, как изменить его. Наиболее надежным способом является использование menuconfig или nconfig target.

Обе цели делают одно и то же, но имеют разный интерфейс. Это единственное различие между ними. Я предпочитаю использовать цель menuconfig, но в последнее время склоняюсь к nconfig, так как она более интуитивна в поиске опций.

Начните с выполнения команды make с целью menuconfig:

$ make menuconfig
  HOSTCC  scripts/kconfig/mconf.o
  HOSTCC  scripts/kconfig/lxdialog/checklist.o
  HOSTCC  scripts/kconfig/lxdialog/inputbox.o
  HOSTCC  scripts/kconfig/lxdialog/menubox.o
  HOSTCC  scripts/kconfig/lxdialog/textbox.o
  HOSTCC  scripts/kconfig/lxdialog/util.o
  HOSTCC  scripts/kconfig/lxdialog/yesno.o
  HOSTLD  scripts/kconfig/mconf

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

Существует два типа переключаемых опций:

  • Опции с булевым состоянием: Опции, которые можно только выключить ([ ]) или включить, как встроенные ([*]).
  • Опции с тремя состояниями: Опции, которые могут быть выключены (< >), встроены (<*>) или встроены как загружаемый модуль (<M>).

Чтобы получить более подробную информацию о той или иной опции, перейдите к ней с помощью клавиш со стрелками вверх/вниз, затем нажимайте клавишу TAB, пока не будет выбрана опция Help, расположенная внизу. Затем нажмите клавишу Enter, чтобы выбрать ее. На экране появится справочное меню по данному элементу конфигурации.

Пожалуйста, будьте осторожны при изменении опций.

После настройки нажимайте клавишу TAB до тех пор, пока не будет выделена опция Save в нижней части экрана. Затем нажмите клавишу Enter, чтобы выбрать его. Снова нажмите клавишу Enter (без изменения имени файла), чтобы сохранить обновленную конфигурацию в файле .config.

Сборка ядра Linux

Сборка ядра Linux очень проста. Но перед этим давайте пометим нашу пользовательскую сборку ядра. В качестве метки я буду использовать строку -pratham, а для этого воспользуюсь переменной LOCALVERSION. Настроить ее можно с помощью следующей команды:

./scripts/config --file .config --set-str LOCALVERSION "-pratham"

Это означает, что опция CONFIG_LOCALVERSION конфигурации в файле .config будет установлена на строку, которую я укажу в конце, в моем случае это -pratham. Не чувствуйте себя обязанными использовать мое имя ;)

Опция LOCALVERSION используется для установки «локальной» версии, которая добавляется к обычной схеме версий x.y.z и сообщается при выполнении команды uname -r.

Поскольку я собираю ядро 6.5.5 со строкой LOCALVERSION, установленной на -pratham, для меня это будет 6.5.5-pratham. Это сделано для того, чтобы собранное мной пользовательское ядро не конфликтовало с ядром, поставляемым дистрибутивом.

Теперь давайте соберем само ядро. Ниже приведена команда для этого:

make -j$(nproc) 2>&1 | tee log

Этого достаточно для 99% пользователей.

Опция -j используется для указания количества параллельных заданий компиляции. А команда nproc возвращает число, обозначающее количество доступных вычислительных единиц (сюда входят и потоки). Таким образом, -j$(nproc) означает «использовать столько заданий параллельной компиляции, сколько потоков процессора у меня есть».

Команда 2>&1 перенаправляет STDOUT и STDIN в один и тот же дескриптор файла, который передается команде tee, которая сохраняет вывод в файл log, а также выводит тот же текст на консоль. Это необходимо на случай, если вы столкнетесь с ошибкой сборки и захотите посмотреть в журнал, чтобы выяснить, что именно пошло не так. В этом случае можно просто выполнить команду grep Error log.

Пользовательские цели „make“

Существует несколько пользовательских целей, которые можно использовать с помощью команды make для выполнения различных операций в каталоге исходных текстов ядра Linux. Они приведены в качестве справочного материала для разработчиков. Если Вы хотите установить более новое ядро Linux чем то, которое предлагает Ваш дистрибутив, Вы можете пропустить эту часть ;)

Цели сборки

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

Цели сборки следующие:

  • vmlinux: Голое ядро Linux
  • modules: Загружаемые модули.
  • dtbs: Двоичные файлы деревьев устройств (в основном для архитектур ARM и RISC-V).
  • all: Собрать все [что помечено звездочкой * (из вывода make help)].

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

В зависимости от архитектуры вашего компьютера, имя собираемого образа ядра Linux (которое хранится в /boot) будет отличаться.

Для x86_64 имя образа ядра Linux [по умолчанию] – bzImage. Поэтому, если вы хотите собрать ядро Linux только для его загрузки, вы можете указать bzImage в качестве цели, например, так:

## For x86_64
make bzImage

«А как мне найти имя цели для вызова make на моей архитектуре?»

Есть два способа. Либо можно выполнить make help и найти первый вариант в разделе «Architecture specific targets», перед которым стоит звездочка *.

Либо, если вы хотите автоматизировать процесс, вы можете получить полный (относительный) путь к изображению, используя цель image_name. Для сохранения полезности вывода можно добавить флаг -s.

Ниже приведены результаты работы трех моих компьютеров: одного x86_64, другого AArch64 и третьего riscv:

## x86_64
$ make -s image_name
arch/x86/boot/bzImage
## AArch64
$ make -s image_name
arch/arm64/boot/Image.gz
## RISC-V
$ make -s image_name
arch/riscv/boot/Image.gz

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

make $(make -s image_name | awk -F '/' '{print $4}')

Цели для очистки

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

  • clean: Удаляет почти все, кроме файла .config.
  • mrproper: Все, что делает make clean, но также удаляет файл .config.
  • distclean: Все, что делает make mrproper, но также удаляет все файлы патчей.

Установка

После того как ядро Linux скомпилировано, настало время установить некоторые вещи. «Несколько _вещей?» Да. Мы собираем по крайней мере 2 разных вещи, 3, если вы на ARM или RISC-V. Я буду объяснять по ходу дела.

Хотя я и расскажу вам о различных способах установки, особенно об изменении пути установки по умолчанию, не рекомендуется делать это, если вы не знаете, что делаете! Пожалуйста, поймите, что если вы пойдете по собственному пути, вы будете сами по себе. Эти значения по умолчанию существуют не просто так ;)

Установка модулей ядра

В ядре Linux есть части, которые не нужны при загрузке. Эти части собраны в виде загружаемых модулей (т.е. загружаются и выгружаются при необходимости).

Так что давайте установим эти модули. Это можно сделать с помощью цели modules_install. Использование sudo необходимо, так как модули будут установлены в /lib/modules/<kernel_release>-<localversion>, а этот каталог принадлежит root, а не вашему пользователю.

Это позволит не только установить модули ядра, но и подписать их. Поэтому это займет некоторое время. Хорошей новостью является то, что вы можете распараллелить эту процедуру, используя ранее рассмотренную опцию -j$(nproc) ;)

sudo make modules_install -j$(nproc)

Примечание для разработчиков: Вы можете указать другой путь, где хранятся модули Linux (вместо /lib/modules/<kernel_release>-<localversion>), используя переменную INSTALL_MOD_PATH следующим образом:

sudo make modules_install INSTALL_MOD_PATH=<path>

Другое примечание для разработчиков: Вы можете использовать переменную INSTALL_MOD_STRIP, чтобы указать, должны ли модули быть очищены от отладочных символов или нет. Отладочные символы не удаляются, если они не определены. При установке значения 1 они удаляются с помощью опции --strip-debug, которая затем передается утилите strip (или llvm-strip, если используется Clang).

Установка заголовочных файлов ядра Linux

Если вы собираетесь использовать это ядро с модулями вне дерева, такими как ZFS или Nvidia DKMS, или попытаетесь написать собственные модули, вам, скорее всего, понадобятся заголовочные файлы, предоставляемые ядром Linux.

Заголовки ядра Linux можно установить с помощью цели headers_install, например, так:

sudo make headers_install

Использование sudo необходимо, поскольку заголовки устанавливаются в каталог /usr. Дочерние каталоги include/linux также создаются внутри /usr, а заголовки устанавливаются в /usr/include/linux.

Примечание для разработчиков: Путь установки заголовков ядра Linux можно переопределить с помощью переменной INSTALL_HDR_PATH.

Установка DTB (только для ARM и RISC-V)

Если вы работаете на x86_64, то этот шаг можно пропустить!

Если вы собирали для ARM или RISC-V, то вполне вероятно, что выполнение make также собрало двоичные файлы дерева устройств. Вы можете проверить это, проверив наличие файлов .dtb в arch/<machine_architecture>/boot/dts.

У меня есть хак для проверки этого:

## For AArch32
$ find arch/arm/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for ARM32 were built"
## For AArch64
$ find arch/arm64/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for ARM64 were built"
## For RISC-V
$ find arch/riscv/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for RISC-V were built"

Если вы получите сообщение «DTBs for were built», переходите к установке DTBs. Это делается с помощью цели dtbs_install.

Использование sudo необходимо, так как он будет установлен в /boot/dtb-<kernel_release>-<localversion>, который принадлежит root.

sudo make dtbs_install

Примечание для разработчиков: Как и при установке модулей, вы можете указать собственный путь к месту установки двоичных файлов дерева устройств с помощью переменной INSTALL_DTBS_PATH.

Установка ядра Linux

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

sudo make install

Использование sudo необходимо здесь потому, что ядро Linux устанавливается в /boot, куда обычный пользователь не имеет права писать.

Как правило, цель install также обновляет загрузчик, но если это не удается, это означает, что у вас, вероятно, неподдерживаемый загрузчик. Если вы не используете GRUB в качестве загрузчика, пожалуйста, прочитайте руководство к вашему загрузчику.

Примечание для разработчиков: На этот раз ничего удивительного; переменная INSTALL_PATH используется для указания места установки ядра Linux, а не пути по умолчанию, который находится в /boot.

Для пользователей Arch Linux

Если вы пытались выполнить команду make install, то могли заметить, что получили ошибку. Она выглядит следующим образом:

sudo make install INSTALL /boot
Cannot find LILO.

Чтобы установить ядро Linux в Arch Linux нам необходимо вручную скопировать образ ядра Linux. Не волнуйтесь, если вы используете Arch Linux вы, вероятно, привыкли делать все вручную. ( ͡° ͜ʖ ͡°)

Это можно сделать с помощью следующей команды:

sudo install -Dm644 "$(make -s image_name)" /boot/vmlinuz-<kernel_release>-<localversion>

Поскольку я скомпилировал ядро 6.5.5, я выполню следующую команду, скорректируйте ее в соответствии с вашими потребностями:

sudo install -Dm644 "$(make -s image_name)" /boot/vmlinuz-6.5.5-pratham

Это не обязательно, но вы должны также скопировать файл System.map, и пока вы это делаете, скопируйте файл .config

sudo cp -vf System.map /boot/System.map-<kernel_release>-<localversion>
sudo cp -vf .config /boot/config-<kernel_release>-<localversion>

Создание начального ramdisk

Вы могли столкнуться с утилитой mkinitcpio при установке Arch Linux Мы собираемся использовать ее для создания начального ramdisk.

Для этого нам сначала потребуется предустановка. Для этого добавьте в файл /etc/mkinitcpio.d/linux-<localversion>.preset следующее содержимое. Замените <kernel_release> и <localversion> по мере необходимости.

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-<kernel_release>-<localversion>"
PRESETS=('default' 'fallback')
default_image="/boot/initramfs-<kernel_release>-<localversion>.img"
fallback_options="-S autodetect"

После этого выполните следующую команду для создания начального ramdisk:

sudo mkinitcpio -p linux-<localversion>

Следующий результат получен на моем компьютере, на вашем он должен быть аналогичным!

$ sudo mkinitcpio -p linux-pratham
> Building image from preset: /etc/mkinitcpio.d/linux-pratham.preset: 'default'
> Using configuration file: '/etc/mkinitcpio.conf'
  -> -k /boot/vmlinuz-6.5.5-pratham -c /etc/mkinitcpio.conf -g /boot/initramfs-6.5.5-pratham.img
> Starting build: '6.5.5-pratham'
  -> Running build hook: [base]
  -> Running build hook: [udev]
  -> Running build hook: [autodetect]
  -> Running build hook: [modconf]
  -> Running build hook: [kms]
  -> Running build hook: [keyboard]
> WARNING: Possibly missing firmware for module: 'xhci_pci'
  -> Running build hook: [keymap]
  -> Running build hook: [consolefont]
> WARNING: consolefont: no font found in configuration
  -> Running build hook: [block]
  -> Running build hook: [filesystems]
  -> Running build hook: [fsck]
> Generating module dependencies
> Creating zstd-compressed initcpio image: '/boot/initramfs-6.5.5-pratham.img'
> Image generation successful
> Building image from preset: /etc/mkinitcpio.d/linux-pratham.preset: 'fallback'
> Using configuration file: '/etc/mkinitcpio.conf'
==> WARNING: No image or UKI specified. Skipping image 'fallback'

Начальный ramdisk был создан. Теперь пора переходить к обновлению загрузчика!

Обновление GRUB

Когда все необходимые файлы находятся в своих обычных местах назначения, пришло время обновить GRUB

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

sudo grub-mkconfig -o /boot/grub/grub.cfg

Если вы используете другой загрузчик, обратитесь к документации по нему в Arch Wiki.* Обновление GRUB не сделает новое ядро ядром по умолчанию. Пожалуйста, выберите его в меню загрузки во время загрузки.*

Вы можете выбрать более новую версию ядра Linux, зайдя в пункт меню „Advanced options for Arch Linux“, а затем выбрав пункт меню с надписью „Arch Linux, with Linux -„.

Перезагрузка

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

Убедитесь, что в загрузчике выбрана правильная версия ядра Linux. После загрузки выполните команду uname -r, чтобы убедиться, что вы загрузились с использованием предназначенного для этого ядра Linux.

Ниже приведен вывод с моего компьютера:

uname -r
6.5.5-pratham

Деинсталляция

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

Ну, make uninstall не существует, но это не значит, что всё потеряно.

Мы знаем, где установлены все файлы, поэтому удалить их будет проще.

## Remove kernel modules
$ rm -rf /lib/modules/<kernel_release>-<localversion>
## Remove device-tree binaries
$ rm -rf /boot/dtb-<kernel_release>-<localversion>
## Remove the Linux kernel itself
$ rm -vf /boot/{config,System,vmlinuz}-<kernel_release>-<localversion>

Заключение

Неплохое приключение, не правда ли? Но, наконец, оно завершено. Мы рассмотрели весь процесс ручной компиляции ядра Linux. Он включал в себя установку зависимостей, получение исходного кода, его проверку, извлечение, настройку ядра Linux, сборку ядра Linux и его установку.

Зарубин Иван Эксперт по Linux и Windows

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

Вдохновлен itsfoss.com

Похожие статьи

Комментарии (1)

  • Evgeny

    Статья на «Ять!»