版本

kexec_load()系统调用首先出现在Linux 2.6.13中。 kexec_file_load()系统调用首先出现在Linux 3.17中。

说明

系统调用kexec_load()会加载一个新内核,稍后可通过reboot(2)执行该内核。

flags参数是控制呼叫操作的位掩码。可以在标志中指定以下值:

KEXEC_ON_CRASH(since Linux 2.6.13)
在系统崩溃时自动执行新内核。此"崩溃内核"被加载到保留内存区域,该区域在启动时使用crashkernel内核命令行参数确定。该保留内存的位置通过/ proc / iomem文件在标记为"崩溃内核"的条目中导出到用户空间。用户空间应用程序可以解析此文件,并准备将此保留内存指定为目标的段列表(请参见下文)。如果指定了此标志,则内核将检查在段中指定的目标段是否在保留区域内。
KEXEC_PRESERVE_CONTEXT(since Linux 2.6.27)
在执行新内核之前,请保留系统硬件和软件状态。这可以用于系统挂起。仅当内核配置了CONFIG_KEXEC_JUMP时,此标志才可用;仅当nr_segments大于0时,此标志才有效。

标志的高阶位(对应于掩码0xffff0000)包含要执行的内核的体系结构。指定(OR)常数KEXEC_ARCH_DEFAULT以使用当前体系结构,或以下体系结构常数之一KEXEC_ARCH_386KEXEC_ARCH_68KKEXEC_ARCH_X86_64KEXEC_ARCH_PPCKEXEC_ARCH_PPC64KEXEC_ARCH_IA_64,KEXEC_ARCH_ARCH_IPS,KEXEC_ARCH_IPS,KEXEC_ARCH_S,该体系结构必须在系统的CPU上可执行。

entry参数是内核映像中的物理入口地址。 nr_segments参数是段指针所指向的段数。内核对段数施加(任意)16个限制。 segments参数是kexec_segment结构的数组,这些结构定义内核布局:

struct kexec_segment {
    void   *buf;        /* Buffer in user space */
    size_t  bufsz;      /* Buffer length in user space */
    void   *mem;        /* Physical address of kernel */
    size_t  memsz;      /* Physical address length */
};

由段定义的内核映像将从调用进程复制到常规内存或保留内存中(如果设置了KEXEC_ON_CRASH的话)。内核首先对分段中传递的信息执行各种完整性检查。如果这些检查通过,则内核将段数据复制到内核内存。段中指定的每个段都将复制如下:

*
buf和bufsz标识了调用者的虚拟地址空间中作为副本源的存储区域。 bufsz中的值不能超过memsz字段中的值。
*
mem和memsz指定作为副本目标的物理地址范围。在两个字段中指定的值必须是系统页面大小的倍数。
*
bufsz字节从源缓冲区复制到目标内核缓冲区。如果bufsz小于memsz,则将内核缓冲区中的多余字节清零。

如果是正常的kexec(即未设置KEXEC_ON_CRASH标志),则将段数据加载到任何可用内存中,并在kexec重新启动时将其移动到最终目标位置(例如,使用以下命令执行kexec(8)命令) -e选项)。

如果kexec处于紧急状态(即设置了KEXEC_ON_CRASH标志),则在调用时将段数据加载到保留的内存中,并且在崩溃后,kexec机制只是将控制权传递给该内核。

仅当内核使用CONFIG_KEXEC配置时,kexec_load()系统调用才可用。

kexec_file_load()

系统调用kexec_file_load()与kexec_load()类似,但是它使用了一组不同的参数。它从文件描述符kernel_fd引用的文件中读取要加载的内核,并从文件描述符initrd_fd引用的文件中读取initrd(初始RAM磁盘)。 cmdline参数是指向包含新内核命令行的缓冲区的指针。 cmdline_len参数指定缓冲区的大小。缓冲区中的最后一个字节必须为空字节(aq \ 0aq)。

flags参数是一个位掩码,可修改调用的行为。可以在标志中指定以下值:

KEXEC_FILE_UNLOAD
卸载当前加载的内核。
KEXEC_FILE_ON_CRASH
将新内核加载到为崩溃内核保留的内存区域中(与KEXEC_ON_CRASH相同)。如果当前正在运行的内核崩溃,则会启动该内核。
KEXEC_FILE_NO_INITRAMFS
加载initrd / initramfs是可选的。如果未加载initramfs,请指定此标志。如果设置了此标志,则忽略initrd_fd中传递的值。

添加了kexec_file_load()系统调用,以提供对" kexec"加载应仅限于已签名内核的系统的支持。仅当内核配置有CONFIG_KEXEC_FILE时,此系统调用才可用。

语法

#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包装器。请参阅注释。

返回值

成功时,这些系统调用将返回0。错误时,将返回-1并将errno设置为指示错误。

错误说明

EADDRNOTAVAIL
指定了KEXEC_ON_CRASH标志,但段条目之一的mem和memsz字段指定的区域超出了为崩溃内核保留的内存范围。
EADDRNOTAVAIL
段条目之一中的mem或memsz字段中的值不是系统页面大小的倍数。
EBADF
kernel_fd或initrd_fd不是有效的文件描述符。
EBUSY
另一个崩溃内核已经在加载中,或者已经在使用崩溃内核。
EINVAL
标志无效。
EINVAL
段条目之一中的bufsz字段的值超过了相应memsz字段中的值。
EINVAL
nr_segments超过KEXEC_SEGMENT_MAX(16)。
EINVAL
两个或多个内核目标缓冲区重叠。
EINVAL
cmdline [cmdline_len-1]中的值不是aq \ 0aq。
EINVAL
kernel_fd或initrd_fd引用的文件为空(长度为零)。
ENOEXEC
kernel_fd没有引用打开的文件,否则内核无法加载该文件。当前,该文件必须是bzImage并包含一个x86内核,该内核可在内存中加载高于4GiB(请参阅内核源文件Documentation / x86 / boot.txt)。
ENOMEM
无法分配内存。
EPERM
调用者不具有CAP_SYS_BOOT功能。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

遵循规范

这些系统调用是特定于Linux的。

名称

kexec_load,kexec_file_load-加载新内核以供以后执行

KEXEC_LOAD - Linux手册页

Linux程序员手册 第2部分
更新日期: 2019-03-06

另外参见

重新启动(2),系统调用(2),kexec(8)

内核源文件Documentation / kdump / kdump.txt和Documentation / admin-guide / kernel-parameters.txt

备注

当前,这些系统调用没有glibc支持。使用syscall(2)调用它们。

日期:2019-08-20 17:58:55 来源:oir作者:oir