加电自检-读取BIOS-读取MBR-bootloader-运行kernal-运行init-运行其他程序。
(1)加电自检,检测硬件设备,检测cpu,内存,主板,显卡,CMOS等设备是否有故障。
(2)读取BIOS,加电自检完成读取的第一个地方就是BIOS,BIOS定义了一个计算机引导启动的设备顺序。里面记录了主板的芯片与各种设置,比如说cpu与接口设备的通信频率,硬盘大小与类型,系统时间,外部总线等,所以BIOS读取要放在第一位。
(3)读取主引导记录MBR,它是位于磁盘上的第一个扇区中。 MBR 中的主引导加载程序是一个 512 字节大小的映像,其中包含程序代码和一个小分区表(参见图 2)。前 446 个字节是主引导加载程序,其中包含可执行代码和错误消息文本。接下来的 64 个字节是分区表,其中包含 4 个分区的记录(每个记录的大小是 16 个字节)。MBR 以两个特殊数字的字节(0xAA55)结束。这个数字会用来进行 MBR 的有效性检查。
(4)bootloader,GRUB是最常用的bootloader,作用是加载linux内核映像以及可选的初始RAM磁盘,grub加载到内存中之后就可以对文件系统进行查询。详细过程可以查看/boot/grub/下的各阶段的加载程序。
(5)kernal加载
内核映像通常是一个被压缩过之后的zlmage(压缩映像)。
内核映像文件被调用时,执行顺序如下:
通过调用 start_kernel,会调用一系列初始化函数来设置中断,执行进一步的内存配置,并加载初始 RAM 磁盘。最后,要调用 kernel_thread(在 arch/i386/kernel/process.c 中)来启动 init 函数,这是第一个用户空间进程(user-space process)。最后,启动空任务,现在调度器就可以接管控制权了(在调用 cpu_idle 之后)。通过启用中断,抢占式的调度器就可以周期性地接管控制权,从而提供多任务处理能力。在内核引导过程中,初始 RAM 磁盘(initrd)是由阶段 2 引导加载程序加载到内存中的,它会被复制到 RAM 中并挂载到系统上。这个 initrd 会作为 RAM 中的临时根文件系统使用,并允许内核在没有挂载任何物理磁盘的情况下完整地实现引导。由于与外围设备进行交互所需要的模块可能是 initrd 的一部分,因此内核可以非常小,但是仍然需要支持大量可能的硬件配置。在内核引导之后,就可以正式装备根文件系统了(通过 pivot_root):此时会将 initrd 根文件系统卸载掉,并挂载真正的根文件系统。initrd 函数让我们可以创建一个小型的 Linux 内核,其中包括作为可加载模块编译的驱动程序。这些可加载的模块为内核提供了访问磁盘和磁盘上的文件系统的方法,并为其他硬件提供了驱动程序。由于根文件系统是磁盘上的一个文件系统,因此 initrd 函数会提供一种启动方法来获得对磁盘的访问,并挂载真正的根文件系统。在一个没有硬盘的嵌入式环境中,initrd 可以是最终的根文件系统,或者也可以通过网络文件系统(NFS)来挂载最终的根文件系统。
(6)init进程,init进程是内核被加载之后调度的第一个进程,用于初始化系统环境,并产生其他用户进程。它帮助用户完成每次启动系统都必须完成的一些重复性任务,如加载文件系统、各类网络服务等等程序;它还有一个重要用途,让用户自定义系统运行环境,只启动需要的进程,关闭不用的进程,释放内存和处理器资源,让系统运行得更快更稳等等。 仅仅将内核运行起来是毫无实际用途的,必须由 init 系统将系统代入可操作状态。比如启动 shell 后,便有了人机交互,启动nginx后就可以提供web服务等。
而完成这一系列任务的系统被称之为init系统。不同发行版的init系统是不一样的。例如传统的sysvinit,新的upstart系统和systemd系统。
关于init系统的详细说明可以参考:
https://www.ibm.com/developerworks/cn/linux/1407_liuming_init1/