Linux系统启动过程笔记

  Linux启动过程可以分为4个阶段:

1.BIOS引导阶段。2.Bootloader阶段。3.kernel加载阶段。4.Init初始化阶段

BIOS引导阶段:  

  首先,BIOS引导阶段。BIOS,基本输入输出系统。系统上电开机后,计算机会首先加载BIOS信息,计算机必须在最开始就找它。BIOS之所以这么重要,是因为BIOS包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、pnp特性等。

  BIOS的第一个步骤就是加电自检POST。POST的工作是对硬件进行检测。BIOS的第二个步骤是进行本地设备的枚举和初始化。给定BIOS功能的不同用法之后,BIOS由两部分组成:POST代码和运行是服务。当POST完成之后,它被从内存中清理了出来,但是BIOS运行时服务依然保留在内存中,目标操作系统可以使用这些服务。

  要 引导一个操作系统,BIOS会按照CMOS设置定义 的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是CD-ROM、硬盘、网络设备、甚至是USB闪存。通常,Linux都是从硬盘上引导的。BIOS复制读取并执行MBR中的代码,当MBR被加载到实模式地址0x7c00上,BIOS就会将控制权交给MBR。

BootLoader引导阶段:

  BootLoader就是在操作系统内核运行之前 运行的一段小程序。通过这段小 程序可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带动一个合适的状态,以便于为最终调用操作系统内核做好的一切准备。通常,BootLoader是严重地依赖于硬件而实现的,不同体系结构的系统存在不同的BootLoader,系统读取BootLoader配置信息,并依照此配置信息来启动不同的操作系统。Linux系统默认的BootLoader是Grub,下面就以Grub为例说明BootLoader引导过程。

  总所周知,硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,他的大小是512字节,里面存放了预启动信息 ,分区表信息。其中,第一部分引导区占了446字节;第二部分,分表区有64字节,记录硬盘4个分区的记录,每个记录的大小是16字节;第三部分是两个特殊 数字的字节0xAA55,通常用来进行MBR的有效性检查。

  由于MBR的引导区只有446字节,而Grub往往会大于446字节 ;所以Grub的启动分为3个阶段stagel1、stagel1.5、stagel2.

  stagel1:通常仿真MBR的前446字节,它的作用很简单,就是在系统启动时用于装载stagel2并将控制权交给它。注意 ,千万不能将stagel1文件覆盖MBR的分区表,否则会造成分区出错,以致无法开机。

stagel2:通常存放在各分区的Bootsector中,是Grub的核心程序,能让用户以选项方式将操作系统加载、新增参数、修改选项,这些全都是stagel2的功能。对Grub来说,stagel2除了不能自己激活 外,剩下的事情全部由stagel2完成。

stagel1.5:介于stagel1和stagel2之间,是它们的桥梁。因为stagel2较大,通常都是放在一个文件系统当中的,但是stagel1并不能识别文件系统格式,所以才需要stagel1.5来引导位于某个文件系统当中的stagel2。根据文件系统格式的不同,stagel1.5也需要相应的文件,如e2fs_stagel1_5、fat_stagel1_5,分别用于识别ext和fat的文件系统格式。stagel1.5是存在硬盘最前面的32KB中(需要跳过MBR),当stagel1调用stagel1.5的时候,则 直接去该区域将stagel1.5调用。

kernel加载阶段:

   Linux内核映像并不是一个可执行的内核,而是一个压缩过的内核镜像,通常它是一个一个zImage(小于512KB)或一个bzImage(大于512KB),按照bootsect.S、setup.S、vmlinux这样的顺序在磁盘上连续存放。

  在arch/i386/boot目录下,bootsect.S是生成BootLoader的汇编源码,它首先将自己复制到0x90000上,然后将紧接其后的setup.S复制到0x90200,将真正的内核代码vmlinux复制到0x100000。

  bootsect.S完成加载动作后直接跳转到0x90200,这里正是setup.S程序的入口。setup.S的主要功能就是将系统参数(包括内存、磁盘等,由BIOS返回)复制到0x90000-0x091FF,这个地方正是bootsect.S存放的地方,这时它将被系统参数覆盖。以后这些参数将由保护模式下的代码来读取。除此之外,setup.S还将video.S的代码包含进来,检测和设置显示器和显示模式。

  当setup.S执行完后,系统转到保护模式,并跳转到0x100000开始执行vmlinux内核引导代码。我们从arch/i386/boot/head.S的start汇编例程开始执行,建立堆栈并解压内核镜像文件,然后再执行arch/i386/boot/head.S,初始化数据区BBS、中断描述表IDT、段描述表GDT、页表和寄存器等。

  最好进入init/main.c中的start_kernel()模块。start_kernel()函数的作用是打印了一些信息、内核工作需要的模块的初始化被依次调用(譬如内存管理、调度系统、异常处理···)。此时系统运行在内核模式下,start_kernel()调用了一系列初始化函数,进行内核的初始化工作。要注意的是,在初始化之前系统中断 仍然是被屏蔽的,另外内核也处于被锁定的状态,以保证只有一个CPU用于Linux系统的启动。最后调用kernel_thread()启动init进程。

init初始化阶段:

  init进程是非内核进程中第一个被启动运行的、系统所有进程的起点。linux完成内核引导以后就开始运行init程序,因此它的进程编号PID的值总是为1。我们在ubuntu下ps -aux可以看到当前系统运行的所有进程,可以看出进程号是从1开始的。为什么不从0开始,因为进程0不是一个用户进程,而属于内核进程。

进程0:进程0其实就是刚才讲过的idle进程,叫空闲进程,也就是死循环。

进程1:kernel_init函数就是进程1,这个进程被称为init进程。

进程2:kthreadd函数就是进程2,这个进程是linux内核的守护进程。这个进程是用来保证linux内核自己本身能正常工作的。

  内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据次文件来进行初始化。而/etc/inittab文件最主要的作用就是设定Linux的运行等级。runlevel是init所处的运行级别的标识,一般使用0~6及S或s。0、1、6运行级别被系统保留:其中,0作为shutdown动作,1作为重启至单用户模式,6为重启。在大多数的Linux发行版中,通常有7个runlevel:从0~6分别是停止系统、单用户模式、基本的多用户模式、多用户模式、使用GUI的多用户模式、重新启动系统。在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysconfig脚本程序,它做的工作非常多,包括设定PATH、设定网络配置文件/etc/sysconfig/network、启动swap分区、设定/proc等。当rc.sysconfig程序执行完毕后,则返回init继续下一步。然后依据/etc/modules.conf文件或者是/etc/modules.d目录下的文件来装载内核模块。根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应脚本程序来完成相应的初始化工作和启动相应的服务。/etc/rc.d/rc.local就是在一切初始化工作后Linux留给用户进行个性化的地方,我们可以把想设置和启动的东西放到里面。

  init进程完成了从内核态向用户态的转变。一个进程2种状态。init进程刚开始运行的时候是内核态,它属于一个内核线程,然后他自己运行了一个用户态下面的程序后把自己强行转成了用户态。因为init进程自身完成了从内核态到用户态的过度,因此后续的其他进程都可以工作在用户态下面了。内核态下做了什么?重点就做了一件事情,就是挂载根文件系统并试图找到用户态下的那个init程序。init进程要把自己转成用户态就必须运行一个用户态的应用程序(这个应用程序名字一般也叫init),要运行这个应用程序就必须得找到这个应用程序,要找到它就必须得挂载根文件系统,因为所有的应用程序都在文件系统中。

  内核源代码中的所有函数都是内核态下面的,执行任何一个都不能脱离内核态。应用程序必须不属于内核源代码,这样才能保证自己是用户态。也就是说我们这里执行的这个init程序和内核不在一起,他是另外提供的。提供这个init程序的那个人就是根文件系统。init进程大部分有意义的工作都是在用户态下进行的。init进程对我们操作系统的意义在于:其他所有的用户进程都直接或者间接派生自init进程。

  init进程在内核态下面时,通过一个函数kernel_execve来执行一个用户空间编译连接的应用程序就跳跃到用户态了。注意这个跳跃过程中进程号是没有改变的,所以一直是进程1.这个跳跃过程是单向的,也就是说一旦执行了init程序转到了用户态下整个操作系统就算真正的运转起来了,以后只能在用户态下工作了,用户态下想要进入内核态只有走API这一条路了。


猜你喜欢

转载自blog.csdn.net/haofeng_ma/article/details/80867564