第二幕:Limine的魔法
序
limine bootloader 为我们提供了一个简便的,带领我们的处理器进入64位长模式的方式,同时为我们提供了简洁易用的接口,用于探测内存、提供屏幕输出等操作。
Limine 的接力
上一幕我们简要介绍了 BIOS 的启动流程,从上电后的 POST 到载入 MBR 开始第一阶段的初始化,我们的Limine也终于入场了。
书接上回,在我们的 RIP 跳转到 MBR 的那部分 bootloader 之后,它的要完成一个很简单的任务,那就是:找到 Limine 的第二阶段 bootloader,然后跳转过去。
之后,这个阶段的 bootloader 要找到第三阶段被压缩过的 bootloader,加载并解压出来,然后跳转过去,继续进行引导。
现在我们来到了第三阶段。这一阶段,Limine 会读取/boot/limine.cfg,了解它要引导什么系统,系统路径在哪里,以及引导参数。之后就会显示一个图形菜单,让用户自行选择要引导哪个系统。
确认之后,Limine 就会按照 limine.cfg 记录的启动项来进行系统引导。
请求——响应握手机制
Limine 协议的核心与精髓就是它的请求——响应机制。它允许内核“按需索取”自己需要的信息。
发起请求: 在编译内核时,我们可以将需要的信息以“请求结构体”的形式嵌入到最终的二进制文件中。
填充响应: 当 Limine 将内核加载到内存后,它不会立刻跳转,而是按照请求将对应的数据填充到对应的段中,然后把对应数据的指针放到response的指针字段。
有了这个灵活的请求——响应机制,我们可以快速地搭建起我们的内核,从而能够进行内存管理、屏幕显示等操作。
内核初始化与权限移交
在完成这些填充后,Limine 会按照协议来进行CPU状态的初始化,最后会跳转到内核入口点,将控制权正式交给内核。不出意外的话,我们会得到:
一个处于64位长模式的CPU,并且分页已经启用,且通用寄存器已清零,中断处于关闭状态。
准备好了一个 64 KiB 的内核栈,可以让我们直接使用。
至此,Limine 的使命已经完成,接下来的所有冒险——内存管理、进程调度、文件系统——都将由我们的内核独自面对。
