![92d9d87b3a83cc191aff11c55bfee95d.png](https://img-blog.csdnimg.cn/img_convert/92d9d87b3a83cc191aff11c55bfee95d.png)
原文:https://manybutfinite.com/post/kernel-boot-process/
翻译:RobotCode俱乐部
如果你熟悉类似C的语法,那么源代码是非常易读的,即使你错过了一些细节,你也能大致了解正在发生的事情。主要的障碍是缺少对代码的上下文环境的了解,比如它什么时候运行,为什么运行,或者机器的底层特性。这里我希望提供一些背景知识。
在Intel x86引导的故事中,此时处理器是在实模式下运行的,能够处理1 MB的内存,RAM对于现代Linux系统是这样的:
![ab86bd82357d6a011caa6531752daeb1.png](https://img-blog.csdnimg.cn/img_convert/ab86bd82357d6a011caa6531752daeb1.png)
内核镜像已经由BIOS中的引导加载程序中的I/O服务加载到内存中。此镜像是包含内核文件的副本,例如/boot/vmlinuz-2.6.22-14-server。镜像被分成两部分:一小部分包含实模式内核代码,加载在640K以下;内核的大部分在保护模式下运行,加载在第一个兆字节内存之后。
该操作从上面所示的实模式内核头部开始。这个内存区域用于在 引导加载程序 和 内核 之间实现Linux引导协议。其中一些值是引导加载程序在执行其工作时读取的。比如包含内核版本的可读字符串,也包含其他重要信息,比如实模式内核块的大小。引导加载程序还将值写入该区域,例如用户在引导菜单中给出的命令行参数的内存地址。引导加载程序完成后,它已经填充了内核头部所需的所有参数。现在是跳到内核入口点的时候了。下图显示了内核初始化的程序流程,以及源目录、文件和行号: