重庆建设空调网站,陕煤化工建设集团网站,怎样做站长建网站,唐尧文化 网站建设工作总结文章目录Kexec和Kdump设计的区别kexeckdumpKdump的执行流程kexec的实现用户空间kexec内核空间vmcoreKdump的实现可以分为两部分#xff1a;内核和用户工具。内核提供机制#xff0c;用户工具在这些机制上实现各种转储策略#xff0c;内核机制对用户工具的接口是一个系统调用…
文章目录Kexec和Kdump设计的区别kexeckdumpKdump的执行流程kexec的实现用户空间kexec内核空间vmcoreKdump的实现可以分为两部分内核和用户工具。内核提供机制用户工具在这些机制上实现各种转储策略内核机制对用户工具的接口是一个系统调用kexec_load()其被用来加载捕获内核和传递一些相关信息。Kdump是一种先进的基于kexec的内核转储机制用来捕获kernel crash内核崩溃的时候产生的crash dump。当内核产生错误系统崩溃、死锁或者死机时kdump会将内存导出为vmcore保存到磁盘。Kdump是kexec机制工作的kexec是一个快速启动机制允许通过已经运行的内核的上下文启动一个Linux内核不需要经过BIOS。Kexec和Kdump设计的区别
kexec
Kexec的设计是用新内核去覆盖原内核位置Kexec的实现包括两部分
一是内核空间的系统调用kexec_load()负责在生产内核first kernel启动时将捕获内核capture kernel加载到指定地址。二是用户空间的工具kexec-tools他将捕获内核的地址传递给生产内核从而在系统崩溃的时候能够找到捕获内核的地址并运行。没有kexec就没有kdump。先有kexec实现了在一个内核中可以启动另一个内核才让kdump有了用武之地。内核空间kexec_load()kexec 在 kernel 里以一个系统调用 kexec_load()的形式提供给用户。这个系统调用主要用来把另一个内核和其 ramdisk 加载到当前内核中。在 kdump中捕获内核只能使用事先预留的一小段内存。生产内核的内存镜像会被以 /proc/vmcore 的形式提供给用户。这是一个 ELF格式的文件它的头是由用户空间工具 kexec 生成并传递来的。在系统崩溃时系统最后会调用machine_kexec()。这通常是一个硬件相关的函数。它会引导捕获内核从而完成 kdump 的过程。 用户空间kexec_toolskdump 的很大一部分工作都是在用户空间内完成的。与 kexec相关的集中在一个叫“kexec-tools”的工具中的“kexec”程序中。该程序主要是为调用 kexec_load()收集各种信息然后调用之。这些信息主要包括 purgatory 的入口地址还有一组由 struct kexec_segment描述的信息。 Kexec设计原理图如下
kdump
kdump机制的实现需要两个不同目的的内核生产内核和捕获内核。生产内核是捕获内核服务的对像。捕获内核会在生产内核崩溃时启动起来与相应的ramdisk一起组建一个微环境用以对生产内核下的内存进行收集和转存。第一个内核保留了内存的一部分给第二内核启动用。由于kdump利用kexec启动捕获内核绕过了 BIOS所以第一个内核的内存得以保留。这是内核崩溃转储的本质。为了在生产内核崩溃时能顺利启动捕获内核捕获内核以及它的ramdisk是事先放到生产内核的内存中的。生产内核的内存是通过/proc/vmcore这个文件交给捕获内核的。为了生成它用户工具在生产内核中分析出内存的使用和分布等情况然后把这些信息综合起来生成一个ELF头文件保存起来。捕获内核被引导时会被同时传递这个ELF文件头的地址通过分析它捕获内核就可以生成出/proc/vmcore。有了/proc/vmcore这个文件捕获内核的ramdisk中的脚本就可以通过通常的文件读写和网络来实现各种策略了。Kdump的设计是预留一块内存来加载第二个内核(和相关数据)发送Crash后第二个内核在原位置运行(不然就达不到相关目的了)收集第一个内核的相关内存信息。 kudmp的设计原理图 捕获内核运行所需的内存一开始就被保留在系统内核崩溃时被加载也不会影响系统内核本身的内存。并且在由于崩溃引起的重起中新内核只会用到很少的内存比如仅仅 16 兆字节剩下的内存不会被用到可以转储出来。新内核被启动后转储过程的下一个阶段是提供写转储文件到目标设备的接口。在新内核中有两个部分来获取要转储的内容。第一个部分用来处理内存被对待的方式第二个部分用来处理用户空间怎样获取转储文件。第一部分被设计成把新内核未用的内存前面出问题的内核的当成高端内存设备。本质上在第二次启动中系统等价于一个有很大数值的高端内存的机器。在转储的过程中在这个区域的页被映射成一个页表项用这种方式去读要转储的内容的话转储文件会被抽象成在/proc 下的一个文件比如/proc/vmcore。用户 仅仅需要像拷贝一个通常的文件一样拷贝转储文件。相似的/proc/vmcore 也将对内核页转储起同样的作用。这个方法的另一个好处是转储文件会被自动存成 ELF格式像 gdb 和 crash 等工具能够被直接用来分析转储出来的文件。
Kdump的执行流程
Kdump的执行流程如下图所示 基本流程为
First kernel生产内核正常运行运行过程中系统出现异常也可以是模拟通过sysrq触发panic在系统崩溃时系统最后会调用 machine_kexec()触发并启动Sencond kernel捕获内核传递ELF头文件的地址捕获内核与相应的ramdisk一起组建一个微环境获取ELF头文件的地址并生成出/proc/vmcore文件捕获内核的ramdisk中的脚本开始执行将/proc/vmcore文件中的数据通过文件读写和网络来实现对生产内核下的内存进行收集和转存通过gdb、crash等工具对收集到的vmcore文件镜像分析。
kexec的实现
Kexec的实现包括用户空间和内核空间。
用户空间kexec
本质上是一个系统调用主要做的事情有
获取reserved内存块读取/proc/iomem中Crash kernel字段的信息 把指定的内核放到自己定义的变量中名字为struct kexec_info包含代码段和加载地址还有其他信息如设备树、启动参数cmdline等。指定的加载地址空间来自reserved内存块。设置vmcore的生成开关—elfcorehdr。
内核空间
内核层会完成kexec_info接收设置新内核实体。 Kexec会陷入系统调用
SYSCALL_DEFINE4kexec_load,unsigned long,entry,unsigned long,nr_segments,struct kexec_segment __user *,segments,unsigned long,flags其主函数为do_kexec_load::
static int do_kexec_load(unsigned long entry, unsigned long nr_segments,struct kexec_segment __user *segments, unsigned long flags)
{struct kimage **dest_image, *image;unsigned long i;int ret;if (flags KEXEC_ON_CRASH) {//新内核 kexec_crash_imagedest_image kexec_crash_image; if (kexec_crash_image)arch_kexec_unprotect_crashkres();} else {dest_image kexec_image;}if (nr_segments 0) {/* Uninstall image */
//卸载内核kimage_free(xchg(dest_image, NULL));return 0;}if (flags KEXEC_ON_CRASH) {//清除新内核内容kimage_free(xchg(kexec_crash_image, NULL));}//将kexec_info 读进来存到image中ret kimage_alloc_init(image, entry, nr_segments, segments, flags);if (ret)return ret;if (flags KEXEC_PRESERVE_CONTEXT)image-preserve_context 1;ret machine_kexec_prepare(image);if (ret)goto out;ret kimage_crash_copy_vmcoreinfo(image);if (ret)goto out;//将各个段存到指定的加载地址使用kmap本质上就是从加载地址获取一个page转为地址然后存到该地址//如果预留内存不足返回-ENOMEMfor (i 0; i nr_segments; i) {ret kimage_load_segment(image, image-segment[i]);if (ret)goto out;}kimage_terminate(image);/* Install the new kernel and uninstall the old *///安装新内核并卸载老内核image xchg(dest_image, image);
out:if ((flags KEXEC_ON_CRASH) kexec_crash_image)arch_kexec_protect_crashkres();kimage_free(image);return ret;
}各个段的存放地址是在reserved中… Panic后会加载新内核__crash_kexec: 读取新内核信息然后热重启重启与架构有关。Arm64会执行cpu_soft_restart然后调用到汇编。
vmcore
Vmcore的生成是initcall函数自动完成的: