Scroll to navigation

KEXEC_LOAD(2) Руководство программиста Linux KEXEC_LOAD(2)

ИМЯ

kexec_load, kexec_file_load - загружает новое ядро для выполнения в будущем

СИНТАКСИС

#include <linux/kexec.h>
long kexec_load(unsigned long entry, unsigned long nr_segments,
                struct kexec_segment *segments, unsigned long flags);
long kexec_file_load(int kernel_fd, int initrd_fd,
                    unsigned long cmdline_len, const char *cmdline,
                    unsigned long flags);

Замечание: В glibc нет обёрточных функций для этих системных вызовов; смотрите ЗАМЕЧАНИЯ.

ОПИСАНИЕ

Системный вызов kexec_load() загружает новое ядро, которое можно запустить позже с помощью reboot(2).

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

Запускать новое ядро автоматически после аварии системы. Данное «аварийное ядро» загружено в область зарезервированной памяти, которая определена во время загрузки с помощью параметра командной строки ядра crashkernel. Область данной зарезервированной памяти экспортируется в пространство пользователя через файл /proc/iomem, в элемент с меткой «Crash kernel». Приложение в пользовательском пространстве может проанализировать этот файл и подготовить список сегментов (смотрите далее), которые определяют эту зарезервированную память в качестве приёмника. Если данный флаг установлен, то ядро проверяет входят ли сегменты назначения, указанные в segments, в зарезервированную область.
Сохранять аппаратное и программное состояния перед выполнением нового ядра. Может использоваться для перевода системы в состояние ожидания (suspend). Этот флаг доступен только, если ядро было собрано с параметром CONFIG_KEXEC_JUMP, и работает только, если значение nr_segments больше 0.

В старших битах (соответствуют маске 0xffff0000) flags задаётся архитектура, на которой будет выполняться ядро. Константой (через OR) KEXEC_ARCH_DEFAULT задаётся использование текущей архитектуры; также есть другие константы, описывающие архитектуры: KEXEC_ARCH_386, KEXEC_ARCH_68K, KEXEC_ARCH_X86_64, KEXEC_ARCH_PPC, KEXEC_ARCH_PPC64, KEXEC_ARCH_IA_64, KEXEC_ARCH_ARM, KEXEC_ARCH_S390, KEXEC_ARCH_SH, KEXEC_ARCH_MIPS и KEXEC_ARCH_MIPS_LE.Архитектура должна быть работоспособна на ЦП системы.

В аргументе entry задаётся физический адрес точки входа в образе ядра. В аргументе nr_segments задаётся количество сегментов, на которые указывает указатель segments; ядро введено (произвольно) ограничение в 16 сегментов. В аргументе segments задаётся массив структур kexec_segment, который определяет разметку ядра:


struct kexec_segment {

void *buf; /* буфер в пользовательском пространстве */
size_t bufsz; /* размер буфера в пользовательском пространстве */
void *mem; /* физический адрес ядра */
size_t memsz; /* размер ядра */ };

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

  • Значения buf и bufsz определяют область памяти в виртуальном адресном пространстве вызывающего, который является источником копирования. Значение bufsz может не превышать значение в поле memsz.
  • Значения mem и memsz определяют физическое адресное пространство — приёмник копии. Значения, задаваемые в обоих полях, должны быть кратны размеру системной страницы.
  • bufsz байт копируется из буфера источника в буфер назначения ядра. Если bufsz меньше чем memsz, то оставшиеся байты в буфере ядра заполняются нулями.

При обычной работе kexec (т. е., флаг не установлен KEXEC_ON_CRASH) сегмент данных загружен в любую доступную память и перемещение выполняется в конечное назначение во время перезагрузки kexec (например, при выполнении команды kexec(8) с параметром -e).

При панике kexec (т. е., флаг KEXEC_ON_CRASH установлен)сегмент данных загружен в зарезервированную память на момент вызова, и, после падения (crash), механизм kexec просто передаёт управление ядру.

Системный вызов kexec_load() доступен только, если ядро было собрано с параметром CONFIG_KEXEC.

kexec_file_load()

Системный вызов kexec_file_load() подобен kexec_load(), но имеет другой набор параметров. Он читает загружаемое ядро из файла, на который указывает файловый дескриптор kernel_fd, а initrd (начальный диск RAM) будет загружен из файла, на который указывает файловый дескриптор initrd_fd. Параметр cmdline является указателем на буфер, содержащий командную строку для нового ядра. В параметре cmdline_len указывает размер буфера. Последний байт буфера должен быть null ('\0').

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

Выгрузить загруженное в данный момент ядро.
Загрузить новое ядро в область памяти зарезервированную под аварийное ядро (как для KEXEC_ON_CRASH). Ядро запускается, если отказывает работающее в данный момент ядро.
Загрузка initrd/initramfs не обязательна. Установите данный флаг, если не нужно загружать initramfs. Если флаг установлен, то значение, передаваемое в initrd_fd игнорируется.

Системный вызов kexec_file_load() был добавлен для поддержки систем, где загрузка «kexec» должна быть ограничена только подписанными ядрами. Данный системный вызов доступен только, если ядро собрано с параметром CONFIG_KEXEC_FILE.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении эти системные вызовы возвращают 0. При ошибке возвращается -1, а в errno содержится код ошибки.

ОШИБКИ

Указаны флаги KEXEC_ON_CRASH, но область, заданная полями mem и memsz одного из элементов segments, находится за пределами диапазона памяти, зарезервированного для аварийного ядра.
Значение в поле mem или memsz в одном из элементов segments не кратно размеру системной страницы.
Значение kernel_fd или initrd_fd не является правильным файловым дескриптором.
Уже загружено другое аварийное ядро или аварийное ядро уже используется.
Значение flags неверно.
Значение поля bufsz одного из элементов segments превышает значение в соответствующем поле memsz.
Значение nr_segments превышает KEXEC_SEGMENT_MAX (16).
Два или более буфера назначения ядра перекрываются.
Значение в cmdline[cmdline_len-1] не равно '\0'.
Файл, на который ссылается kernel_fd или initrd_fd, пуст (нулевой длины).
Значение kernel_fd не указывает на открытый файл, или ядро не может загрузить этот файл. В настоящее время, файл должен быть в формате и содержать ядро x86, которое можно загрузить в память выше 4 ГиБ (смотрите файл исходного кода ядра Documentation/x86/boot.txt).
Невозможно выделить память.
Вызывающий не имеет мандата CAP_SYS_BOOT.

ВЕРСИИ

Системный вызов kexec_load() впервые появился в Linux 2.6.13. Системный вызов kexec_file_load() впервые появился в Linux 3.17.

СООТВЕТСТВИЕ СТАНДАРТАМ

Данные системные вызовы есть только в Linux.

ЗАМЕЧАНИЯ

В настоящее время в glibc нет поддержки данных системных вызовов. Вызывайте их через syscall(2).

СМ. ТАКЖЕ

reboot(2), syscall(2), kexec(8)

Файлы исходного кода ядра Documentation/kdump/kdump.txt и Documentation/admin-guide/kernel-parameters.txt

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alex Nik <rage.iz.me@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

6 марта 2019 г. Linux