「Kernel」- 内核(Linux)

更新日期:2019年07月10日

内核的任务

内核接管所有操作系统进程,比如内存管理、任务调度、读入/写出、进程通信,以及整个系统的控制。

启动阶段

这分为两个阶段加载:第一阶段,内核被载入内存并解压,并设置某些基本功能(如内存管理)。第二阶段,控制权切换到主要的内核启动进程。一旦内核完全运作,内核便开始查找并运行初始化进程(init),分别设置用户空间、用户环境需要的进程、最后的登录界面。然后内核本身被允许进入空闲状态,受到来自其他进程的调用。

在某些平台上(比如ARM 64位),内核解压必须由引导加载程序完成。

第一阶段,内核加载

内核通常作为镜像文件被加载,使用zlib压缩为zImage或bzImage格式。

在内核头部的小段例程设置系统函数、进行最少的硬件初始化(例如重要的硬件和内存页)

解压镜像到高位内存,

并留意已配置RAM驱动器。

然后通过./arch/i386/boot/headstartup_32()进程执行内核启动。

第二阶段、内核启动

内核启动函数(swapper,process 0)建立内存管理(页表、内存页)、检测处理器类型及其附加功能(比如浮点处理),

然后调用start_kernel()切换到非特定架构内核功能,由start_kernel()执行范围广泛的初始化功能(终端,剩余内存管理,设备与驱动初始化)。它设置中断处理(IRQ),进一步配置内存,启动初始化进程(首个用户空间进程),通过cpu_idle()启动空闲任务。

值得注意的是,内核启动进程还会挂载initrd,它是作为临时根文件系统在启动阶段以前加载。initrd允许直接从内存中加载驱动模块,而不需要依赖其他设备(比如磁盘)及访问这些设备所需要的驱动(比如SATA驱动)。分离某些静态编译到内核的驱动,并且其他驱动从initrd加载,这允许内核更小。稍后通过pivot_root()切换文件系统,它卸载临时文件系统,并使用真正的文件系统替代(只要能够访问)。由临时文件系统使用的内存将会被回收。

因此,内核初始化设备,只读挂载由引导加载程序指定的根文件系统,然后运行初始进程(/sbin/init,PID=1)。当挂载文件系统时,通过内核打印消息,当启动初始进程时,通过初始化打印消息。在根文件系统挂载前,它还可以任选地运行initrd以允许进行设置,并处理设备相关的事情(RAM磁盘或类似东西)

根据RED HAT描述,因此在此阶段的详细内核进程可以概括如下:

在内核被加载后,(1)它立即初始化并配置计算机内存,并配置连接到系统的各种硬件(处理器,读写子系统,存储设备)。(2)然后在内存预定的位置查找压缩的initrd镜像,解压,挂载,加载驱动。(3)接下来,在卸载initrd磁盘镜像并释放它占用的内存前,初始化与文件系统相关的虚拟设备,例如LVM或软磁盘阵列。(4)然后内核创建根设备,已只读挂载根分区,并释放无用内存。(5)此时内核已经载入内存,并且可操作。然而,由于现在还没有允许有意义的输入进入系统的用户应用,没办法用它来完成什么。

initramfs样式的引导是相似的,但与initrd启动的描述不完全相同。

此时,中断可用,调度器可以控制系统的整体管理,以提供先发制人的多任务,并且留下初始进程在用户空间中继续启动用户环境。

早期用户空间

initramfs,早期用户空间,从Linux Kernle 2.5.46起,意图替换尽可能替换早期内核在启动阶段要执行的许多功能。早期用户空间的典型用途是检测需要加载哪些设备驱动来加载文件系统,并从临时文件系统加载这些驱动。

参考文献


ToC

内核的任务

启动阶段

第一阶段,内核加载

第二阶段、内核启动

早期用户空间

参考文献