Как обновить ядро linux

Обновлено: 07.07.2024

APT в дистрибутивах ALT Linux и в Sisyphus автоматом не обновляет ядра вместе с обновлением системы (см. настройки hold в apt.conf), поскольку обновление такого критичного компонента системы может привести к нежелательным последствиям. Вместо этого в систему могут быть поставлены пакеты нескольких ядер и модулей к разным ядрам одновременно. И LiLo, и Grub можно настроить таким образом, что простая перезагрузка (в том числе по reset) будет возвращать старое ядро.

Содержание

Внимание! Запуск утилиты update-kernel должен производиться с правами root


Для обновления ядра предлагается использовать утилиту update-kernel , находящуюся в одноимённом пакете. Установка, если ещё не установлено:

Пример использования (не забываем про apt-get update , если индексы сегодня ещё не обновлялись):

или, если хотите обновить/установить другой тип ядра (например un-def):

Примечание: Ключ -t и тип ядра (std-def, un-def и т.п.) надо указывать только если вы решили обновить ядро другого типа, т.к. по умолчанию обновляется текущий тип ядра.


update-kernel обновляет и пакеты с модулями ядра, но исходя из списка установленных для текущего ядра пакетов. Следует понимать, что у ядер разных типов модули могут быть собраны по-разному, и, тогда, update-kernel может не доустановить нужное. Например, если у текущего ядра модуль собран в составе пакета с ядром, а у нового отдельно, то пакет с нужным модулем не будет доустановлен автоматически.

В некоторых дистрибутивах apt по умолчанию не содержит подключенных репозитариев. Для проверки и/или настройки можно воспользоваться утилитой apt-repo или просто проверить и отредактировать конфиги в /etc/apt/.

update-kernel обновляет и модули ядра, если в репозитории обновилось что-то из модулей без обновления ядра. Запуск как при обновлении ядра.

Иногда возникает необходимость доустановить модули. Сложностей нет, но есть ряд нюансов.

Частая ошибка пользователей -- установка модуля от более нового ядра. Проблема возникает, когда установлено более старое ядро, чем в репозитории, а пользователь устанавливает необходимый модуль ядра, не обновив ядро. В результате в систему устанавливается новое ядро с одним-единственным модулем, установка которого запрошена. Для того, чтобы не было такой проблемы, надо вначале обновить ядро, а потом доустанавливать необходимые модули ядра. Если необходимо установить модули именно для старого ядра, можно воспользоваться архивом репозитория аналогично ситуации с установкой старого ядра. Более редкая ошибка -- это установка модуля ядра другой сборочной ветки (std-def, un-def и т.п.) называемой в жаргоне флейвором (тип, вариант сборки ядра). Для предотвращения этого (если модуль есть только в другой ветке) надо перейти сначала на другую сборочную ветку с помощью команды update-kernel .

где <новый flavour> = std-def, un-def и т.п. См. kernel/Flavours

После этого уже можно обновлять модуль ядра. Например, мы хотим перейти на ветку un-def и установить модуль fglrx:

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

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

Поскольку Linux Mint основана на Ubuntu, то данная инструкция в полной мере применима и к дистрибутивам Linux Mint, кроме LMDE. Для LMDE (Linux Mint Debian Edition) смотрите статью «Как установить последние версии ядра Linux в Debian и основанные на Debian дистрибутивы».

Предупреждение перед обновлением ядра

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

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

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

Следует быть особенно осторожным владельцам старых дистрибутивов — настоятельно рекомендуется обновлять ядро только на последних версиях ОС.

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

mainline — репозиторий ядер Ubuntu

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

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

  • linux-headers-*-generic_*_amd64.deb
  • linux-headers-*_all.deb
  • linux-image-unsigned-*-generic_*_amd64.deb
  • linux-modules-*-generic_*_amd64.deb

И установить их командой:

Но процесс можно упростить ещё больше, используя утилиты для работы с ядрами.

mainline (продолжение бесплатной версии ukuu) — программа с графическим и консольным интерфейсом для обновления ядра

Если вы предпочитаете графический интерфейс, то используйте Mainline.

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

Для запуска графического интерфейса выполните:

Для запуска консольной версии выполните:

Использование графической версии не должно вызвать затруднений. При запуске будет получена информация о доступных ядрах, вы можете выбрать любое ядро и установить его, просто нажав на кнопку «Установка». Дополнительно доступны такие действия как удаление ядер и просмотр списков изменений для каждой версии ядра.


Использование консольной версии следующее:

Справка по опциям и командам:

(1) Строка версии должна браться из вывода --list

(2) Одна или более строк версий (разделённые запятыми) берутся из вывода --list

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

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


и выберите желаемую версию из установленных ядер.


Утилита ubuntu-mainline-kernel.sh

Последнюю версию ядра на Ubuntu и Linux Mint также можно установить с помощью утилиты командной строки ubuntu-mainline-kernel.sh.

Загружаем и устанавливаем скрипт ubuntu-mainline-kernel.sh:

Справка по ubuntu-mainline-kernel.sh

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

Проверяем текущую версию ядра:


Ядро имеет версию 5.11.

Проверяем, какая версия ядра является последней:


Чтобы вывести список доступных для установки версий ядер выполните команду:

Например, мы хотим установить ядро версии v5.12.11, тогда команда следующая (префикс «v» указывать не надо):

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


Вам будет задан вопрос, хотите ли вы продолжить, введите «y»:

Программа завершила работу — чтобы изменения вступили в силу, требуется перезагрузка.


Опять проверяем версию ядра:


Как восстановить Linux после установки ядра

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


Затем выберите предыдущую версию ядра и нажмите Enter:


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

Если вы не видите меню GRUB2, нажмите и удерживайте клавишу Shift или несколько раз нажмите клавишу Esc (это может варьироваться в зависимости от загрузки BIOS или UEFI и от используемой вами версии Ubuntu/Linux Mint) при загрузке GRUB. Должно появиться меню Grub, позволяющее выбрать предыдущую версию ядра.

Как вы думаете насколько реально зайти на машину по ssh, обновить систему, загрузить новое ядро и при этом оставаться в той же ssh сессии. Сейчас есть модное движения по обновлению ядра на лету (ksplice, KernelCare, ReadyKernel, etc), но у этого способа есть много ограничений. Во-первых, он не позволяет применять изменения, которые меняют структуру данных. Во-вторых, объекты в памяти могут уже содержать неверные данные, которые могут вызвать проблемы в дальнейшем. Здесь будет описан более «честный» способ обновить ядро. На самом деле, сам способ уже давно известен [1], а ценность этой статьи в том, что мы разберем все в деталях на реальном примере, поймем, насколько это просто или сложно, и чего стоит ждать от подобных экспериментов.

Travis CI — одна из популярных систем непрерывной интеграции, которая хорошо работает с Github. Сервис быстро развивается и если несколько лет назад он предоставлял только контейнеры с не очень свежими дистрибутивами, то сегодня там есть выбор между контейнерами и вмками, есть поддержка не только Linux систем и многое другое.

Мы начали использовать Travis-CI в нашем проекте CRIU (checkpoint/restrore in userspace) несколько лет назад и всегда брали от сервиса максимум. Начинали с проверки компиляции на x86_64, а сегодня Travis-CI запускает наши тесты, проверяет компиляцию на всех архитектурах, с разными компиляторами и даже тестирует совместимость с новыми ядрами, в том числе и самой нестабильной и передовой веткой Linux-Next.

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

А теперь к делу, господа…

Но сегодня я хочу рассказать совсем не о том, как мы тестируем CRIU, а об одном интересном варианте его использования. Представьте, что на входе у нас есть виртуальная машина, в которой через ssh запущен процесс. Как нам загрузить свое ядро так, чтобы процесс этого не заметил? Это ровно та ситуация, которую мы имеем в Travis-CI.

Внешнего доступа к виртуалке мы не имеем, и если процесс Travis по какой-то причине умирает (завершается), то сервис завершает задачу и удаляет ВМ. Согласитесь, задачка, прямо скажем, непростая. Мы даже сделали внизу голосование – просигнальте, пришло ли вам сразу в голову решение или нет.

Но мы поступили следующим образом: берем CRIU, дампим ssh-сессию Travis, загружаем новое ядро, восстанавливаем процессы и бежим дальше. Примерно так я думал, когда решил немного развлечься после обеда и показать, как все это взлетит.

Решение

Обновление системы — меньшая из бед, решается парой команд:


Но дальше становится намного веселее. Во-первых, возникает опрос: откуда начинать дампить? Во-вторых, как будем восстанавливать? Если что-то пойдет не так, как мы узнаем, что именно? От замороженного Travis помощи ждать не приходится.

Так что начнем разбираться своими силами. Смотрим на дерево процессов и понимаем, что дампить надо начинать с процесса SSHD, который обрабатывает нашу SSH-сессию.


Идем по всем родителям, начиная с себя, и берем второй процесс sshd от init-а:


Теперь мы знаем кого дампить и надо решить кто будет этим заниматься. Стоит учесть, что CRIU не позволяет «пилить сук, на котором сидит», так что придется создать сторонний процесс:


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


Если перевести ее на русский язык, это команда звучит примерно так: “CRIU, сделай нам дамп поддерева начиная с процесса $pid, все данные сложи в директорию /imgs, логи сохрани в файле dump.log, рассказывай подробно обо всем что делаешь, а также разрешаем тебе сохранить tcp-сокеты, unix-сокеты, связанные с внешним миром, файловые локи и дескрипторы на удаленные файлы”.

Кажется, тут все понятно, кроме удаленных файлов — откуда они возьмутся? Но достаточно вспомнить, что мы установили мажорный update на систему, а это значит, что обновилось почти все, в том числе библиотеки и запускаемые файлы. При этом наш процесс не перезапускался и по прежнему использует старые версии этих файлов. Именно для них мы и указываем опцию --link-remap.

Тут же возникает и еще одна проблема. Между сохранением и восстановлением процессов сетевой трафик должен быть заблокирован, иначе нет никакой гарантии, что TCP соединения переживут эту операцию. CRIU добавляет для этого пару правил iptables, и наша задача — эти правила восстановить после загрузки нового ядра, но до того как произойдет настройка сети. Здесь мне пришлось немного погуглить, но в целом также задача решилась не слишком сложно.

Восстановление

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


Кажется все готово и можно взлетать. Ключ на старт.

Полетели!

Так мы взлетели, но, как и SpaceX, с первого раза сесть не смогли. А не смогли мы, потому что посадочная платформа была кем-то уже занята. А если серьезно, то проблема в том, что CRIU позволяет восстанавливать процессы только с теми же идентификаторами, что у них были на момент дампа. Мы же перезагрузились в новую систему, где systemd (. ) и процессов стало немного больше. Эта проблема уже давно изучена наукой, и тут нам помогут контейнеры, точнее говоря, только их маленькая часть, называемая пространством имен процессов (pid namespace).


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


Фактически мы сделали свой собственный патч для CRIU. Это можно было решить более элегантно с помощью плагинов, но так было быстрее. Снова заливаем наши изменения и ждем очередного падения. На этот раз возникает проблема с псевдотерминалами: нужные нам номера уже кем-то используются. Мы могли бы монтировать devpts с newinstance, но эта опция с недавнего времени не работает.

- The newinstance mount option continues to be accepted but is now
Ignored. // Eric W. Biederman


Опять запускаем и ждем. Время уже давно послеобеденное, и вся эта затея явно сильно затянулась. Привычно получаем ошибку — на этот раз о том, что какие-то fifo файлы из /run/systemd/sessions не могут быть восстановлены. Разбираться, что это за файлы, нет никакого желания, поэтому перед восстановлением просто создадим их и побежим дальше.


Опять падаем, и на этот раз похоже налетаем на баг в CRIU. Видим, что sys_prctl(PR_SET_MM, PR_SET_MM_MAP, …) возвращает EACCES, лезем в ядро и находим, что виной тому восстановление ссылки на запускаемый файл. Ядро видит, что мы передаем ссылку на файл, у которого нет соответствующего бита. Вы же помните, что мы обновили систему целиком, и теперь эта ссылка из процесса указывает на удаленный файл. Оказывается, что перед тем как удалить файл, dpkg снял с него права на запуск.


Кажется, достаточно сделать еще один патч к CRIU, и золотой ключик будет у нас в кармане.

Заключение

Что мы этим доказали? Во-первых, решили пару прикладных задач, а во-вторых показали, что CRIU — это очень низкоуровневый инструмент и даже простая задача может потребовать глубоких знаний системы. Зато старания компенсируются мощностью, гибкостью и широкими возможностями. Хотя никто не гарантирует, что вам не придётся повоевать с багами.

Эта статья описывает шаги необходимые для обновления ядра Linux.

Contents

Установка

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

Конечно, исходный код ядра можно установить напрямую, используя команду (замените gentoo-sources на любую версию ядра, которую используете):

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

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

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

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

Создание резервной копии текущей конфигурации ядра

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

Очень просто создать резервную копию конфигурации текущего ядра:

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

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

Установка символьной ссылки на новый исходный код ядра

Символьная ссылка /usr/src/linux всегда должна указывать на каталог в котором находится исходный код используемого в настоящий момент ядра. Это может быть сделано одним из трех способов:

  1. Установка исходного кода ядра с USE="symlink"
  2. Настройка ссылки с помощью eselect
  3. Ручное обновление символьной ссылки

Установка исходного кода ядра с USE-флагом symlink

Это заставит /usr/src/linux ссылаться на свежеустановленный исходный код ядра.

Если необходимо, это можно изменить одним из двух методов.

Настройка символьной ссылки с помощью eselect

Для настройки символьной ссылки с помощью eselect :

Это вывод доступных исходных кодов ядра. Звездочка указывает на выбранный исходный код.

Для выбора исходного кода ядра, например, второго в списке, выполните:

Изменение символьной ссылки вручную

Для изменения символьной ссылки вручную:

Moving to the new folder

Now that the symbolic link has been modified, change the working directory to the new kernel folder.

Заметка
This command is still necessary even if the working directory was already /usr/src/linux when the symlink was modified. Until the new symlink is actually followed, the console will still be in the old kernel's directory.

Копирование предыдущей конфигурации ядра

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

  • В файловой системе procfs, если параметр ядра Enable access to .config through /proc/config.gz был включен в работающем на данный момент ядре:
  • Из старого ядра. Такое будет работать только в случае, если старое ядро было скомпилировано с CONFIG_IKCONFIG:
  • в каталоге /boot , если туда был установлен конфигурационный файл:
  • В каталоге ядра, которое работает на данный момент:
  • в каталоге /etc/kernels/ , если SAVE_CONFIG="yes" настроено в /etc/genkernel.conf и ядро было скомпилировано с помощью genkernel :

Файл .config

Чтобы использовать старую конфигурацию для нового ядра, ее нужно конвертировать. Конвертация может быть выполнена с помощью запуска make silentoldconfig или make olddefconfig . Используйте одну из них.

make silentoldconfig

Важно
make silentoldconfig был удален начиная с ядра linux версии 4.19 и заменен на make syncconfig .

Следующая конфигурация похожа на текстовый интерфейс из make config . Для новых опций она предоставляет выбор пользователю. Например:

(NEW) в конце строки отмечает эту опцию как новую. В левой части, в квадратных скобках, указаны возможные ответы: Yes, no, module или ? для справки. Рекомендуемый ответ (т.е. по умолчанию) написан большими буквами (здесь Y). В справке дано пояснение к опции или драйверу.

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

make olddefconfig

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

make help

Используйте make help для просмотра других доступных методов преобразования конфиг файла:

Компиляция

Важно
Когда установлены внешние модули ядра (например, nvidia или zfs), возможно, необходимо выполнить make modules_prepare , как написано ниже, перед тем, как собрать ядро. Некоторые модули не могут быть установлены или подготовлены до того, как будет собрано ядро. Важно
Не забудьте перенастроить загрузчик для нового ядра, и пересобрать initramfs, если он используется.

На этом шаге следуйте инструкциям статьи ручная конфигурация.

Автоматическая сборка и установка

It is possible to automatically build and install the newly emerged kernel using Portage hooks. While other approaches are also possible, the following is based on genkernel and gentoo-sources package. It requires the following prerequisites:

  1. genkernel all is able to build and install the kernel to which the /usr/src/linux symlink points into $BOOTDIR and the bootloader.
  2. The symlink use flag is set for the kernel ebuild.

If those are fulfilled, simply install a post_pkg_postinst Portage hook as shown below.

Файл /etc/portage/env/sys-kernel/gentoo-sources Automated kernel build and installation portage hook

Переустановка внешних модулей ядра

Заметка
The modules_prepare step is not required if building an entire kernel as this function is done as part of the standard process.

Все внешние модули ядра, такие как binary kernel modules, необходимо перекомпилировать для каждого нового ядра. Если ядро еще не собрано, оно должно сперва быть подготовлено для компиляции его внешних модулей:

Пакеты с модулями ядра можно пересобрать заново, используя набор @module-rebuild :

Решение проблем сборки

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

Читайте также: