linux kexec内核引导
linux kexec 介绍
kexec的功能是用一个运行的内核去运行一个新内核,就像运行一个应用程序一样。这种机制因为跳过了bootloader,可以实现系统的快速重启。另外kdump也是基于kexec实现(示意如下)。
kexec的实现有几点难点:
- 在当前内核的上下文中,如何用新内核去替换现有内核?
- 正常复位启动过程中,设备会被复位(或初始化)到已知状态。跳过了复位阶段,那如何在新内核kexec启动时,保证设备状态的可靠?
kexec的使用示例如下,其分为2部分:kexec内核加载和kexec内核执行。
1 2 | kexec -l /bzImage --initrd= /initrd .img.gz --append= "ro nosmap loglevel=4 console=ttyS0,9600n8 acpi_rsdp=0x7b7fe014" kexec -e |
kexec 内核加载
- 将内核镜像文件、根文件系统、命令行参数等segment加载到用户态内存;
- 对segment sha256检查,确保内核数据没有被破坏;如果是kdump,备份相关数据到备份区(如i386,最开始的640K配置数据用于SMP内核启动,需要备份;或者powerpc,固定位置的异常向量等信息需要备份等)。这个环节又叫purgatory,其流程可以在用户态控制实现,也可以在内核态控制实现(如使能--kexec-file-syscall选项);
- 分配内核态页面,并将segment从用户态内存copy到内核态页面;如果使能--kexec-file-syscall选项,则跳过前面两步,直接将segment加载到内核页面,并进行purgatory。
- 分配页面并初始化image->control_code_page,对其建立页表,为下一步进行覆盖当前内核时代码寻址的页表映射。初始化LEVEL4/3/2/1 4层页表,并建立映射关系(如下图所示)。
kexec 内核运行
- 调用设备驱动shutdown接口关闭设备;
- 关闭中断,如IO-APIC, local irq, LAPIC;
- 关闭非0号CPU核;
- 清空TLB(此处以下代码为汇编实现,具体实现与arch相关,一般名叫relocate_new_kernel);
- 设置段寄存器、gdt、idt等;
- 建立一个新栈,并将新内核的入口地址压入栈中;
- 设置cr0寄存器:使能分页功能和页面保护功能;
- 设置cr4寄存器:使能扩展地址;
- 设置cr3寄存器,使cr3指向新的页表根目录;设置后,从此就与旧内核bye bye了;
- 将内核segment页面copy到指定位置,覆盖当前内核;
- 调用ret指令,从栈中弹出之前压栈的新内核bzImage入口地址,进入新内核引导;
kexec 调试注意事项
- kexec不会同步或卸载文件系统,此过程需要用户来保证;
- 从上面的流程中可以看出,kexec不会对cpu或设备进行复位,但系统重启过程中会调用reboot_notifier_list,所以register_reboot_notifier注册的接口不要有执行CPU复位等操作;
- 为了保证设备在kexec时处于稳定状态,kexec会调用设备驱动的shutdown接口来关闭,确保用户自己的设备驱动提供了正确的shutdown接口,或用户通过其他方式进行关闭;
--EOF--
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?