概述
这儿我们以x86-64为例,通常情况下我们使用的都是压缩内核,也就是经过压缩的内核,内核外面被添加了一段自解压程序。对于压缩内核,从引导程序引导后首先运行的是那段字节压程序,其入口为arch/x86/boot/compressed/head_64.S中的startup_32。从那儿开始,将会配置解压内核所需要的环境并解压和跳转到内核。
Grub引导到内核启动各阶段CPU的控制寄存器状态如下表:
阶段 |
CR0 |
CR3 |
CR4 |
EFER |
GRUB到自解压前 |
0x60000011 |
0x000000000000 |
0x00000000 |
0x00000000 |
自解压程序配置环境后 |
0x80000011 |
0x000002328000 |
0x00000020 |
0x00000500 |
自解压跳转到内核后 |
0x80000011 |
0x000002328000 |
0x00000020 |
0x00000500 |
内核配置新环境后 |
0x80050033 |
0x000001df6000 |
0x000000a0 |
0x00000d01 |
Grub引导到内核启动各阶段CPU的控制寄存器状态如下表:
阶段 |
CS |
DS |
gdtr |
idtr |
ldtr |
GRUB到自解压前 |
0x0010 |
0x0018 |
0x00000000000010b0 |
0x0000000000000000 |
0x0000 |
自解压程序配置环境后 |
0x0010 |
0x0018 |
0x0000000001639400 |
0x0000000000000000 |
0x0000 |
自解压跳转到内核后 |
0x0010 |
0x0000 |
0x0000000001639400 |
0x0000000000000000 |
0x0000 |
内核配置新环境后 |
0x0010 |
0x0000 |
0xffffffff81d74000 |
0x0000000000000000 |
0x0000 |
从上表可知,kernel引导经历了几次CPU模式配置,自解压前的配置是为了满足解压内核代码的环境要求,内核启动后由对页表和CPU模式进行了新的配置,以满足内核在虚拟地址下的运行需求。我们接下来具体看一下它是怎么完成这些的。
CPU模式的配置
引导程序完成了对内核的加载与跳转,同时还进行了一些必要的