1. Linux 启动过程
1.1 引导加载程序(bootloader)
在计算机启动时,首先读取硬盘的主引导扇区(MBR),其中包含了引导加载程序(bootloader)。常见的Linux引导加载程序有GRUB、LILO等。引导加载程序负责加载内核镜像到内存中,并将控制权交给内核。
1.2 内核初始化(Kernel Initialization)
内核初始化阶段分为主内核初始化和次内核初始化。主内核初始化主要包括以下几个步骤:
a. 设置体系结构相关的初始化
set_arch_param();
setup_arch();
这些函数主要负责设置和初始化与计算机体系结构相关的参数,例如CPU类型、内存布局等。
b. 初始化执行环境
init_setup();
start_kernel();
这些函数负责初始化与内核执行环境相关的变量和数据结构,为接下来的内核工作做准备。
c. 初始化页表和标志
paging_init();
enable_mmu();
这些函数负责初始化分页机制及相关标志,建立虚拟地址与物理地址的映射关系。
次内核初始化是在主内核初始化完成后进行的,主要包括以下几个步骤:
a. 初始化进程调度器
sched_init();
这个函数负责初始化进程调度器,为后续的进程管理做准备。
b. 初始化中断和异常处理
trap_init();
这个函数负责初始化中断和异常处理机制,为后续的中断处理做准备。
1.3 用户空间初始化(User Space Initialization)
用户空间初始化是在内核初始化完成后进行的,它负责用户空间的初始化和启动用户程序。其中的重要步骤包括:
a. 初始化系统调用
syscall_init();
这个函数负责初始化系统调用机制,为用户程序提供访问内核功能的接口。
b. 启动用户程序
init();
这个函数启动用户程序,通常是一个名为init的用户程序,它是用户空间的第一个进程。
2. 内核加载
2.1 内核映像(Kernel Image)
Linux内核以二进制文件的形式存在,通常位于/boot目录下。内核映像由编译器将源代码编译为机器可执行的形式生成,包含了内核的代码和数据。
2.2 内核加载过程
内核加载过程是由引导加载程序负责的。引导加载程序从硬盘的引导分区中读取内核映像的内容,并将其加载到内存中。加载的过程包括以下几个步骤:
a. 读取内核映像
read_kernel_image();
引导加载程序通过磁盘驱动程序读取硬盘上的内核映像文件。
b. 解压缩内核映像
decompress_kernel_image();
在加载内核映像之前,需要对其进行解压缩,以获得真正的内核代码和数据。
c. 加载内核映像
load_kernel_image();
将解压缩后的内核映像加载到指定的内存地址。
d. 跳转执行内核代码
jump_to_kernel();
将控制权交给内核代码,进入内核初始化阶段。
总结
本文讨论了Linux启动过程及内核加载过程。在启动过程中,引导加载程序负责加载内核镜像到内存中,并将控制权交给内核。内核初始化阶段主要包括主内核初始化和次内核初始化两个步骤,其中主内核初始化负责设置体系结构相关的参数和初始化执行环境,次内核初始化负责初始化进程调度器和中断异常处理机制。用户空间初始化负责用户空间的初始化和启动用户程序。内核加载过程是由引导加载程序负责的,包括读取内核映像、解压缩内核映像、加载内核映像和跳转执行内核代码等步骤。