鉴于个人水平有限,本文仅以直观的角度,简单阐述从通电到用户登录界面出现的启动过程。
从宏观来看,该过程可分为4个阶段:
1,开机上电
2,运行BIOS
3,启动引导程序
4,操作系统初始化
一、开机上电
机器上电后,如果电源系统工作正常,会发送低电平的"Power Good"到复位电路接口的#RES端,产生时钟同步的复位正脉冲RESET送到CPU的RESET引脚,脉冲的下降沿触发CPU执行初始化程序,设置CS和IP寄存器,进入实地址模式。而根据CS和IP的值得到的物理地址就是CPU执行的第一条指令地址。虽然知道了物理地址,但是内存还没有初始化,因此改物理地址指向BIOS ROM。
对于386前后,该物理地址是不同的,但都在内存的最高地址段。
386以前的CPU寻址范围为1M,即0x00000H~0xFFFFFH。此时CS=0xF000H,IP=0xFFF0H,段地址左移4位后,加上偏移地址得到物理地址0xFFFF0H。
而386的可寻址范围为4GB即 0x00000000H~0xFFFFFFFFH。如果以0x000FFFF0H作为BIOS地址的话,系统内存不连续,因此,386使用硬件置1的方式将A20~A31地址线置1,就变成0xFFFFFFF0H,并以此作为BIOS地址。
二、运行BIOS
找到BIOS地址后,BIOS的第一条指令就是跳转,其跳转到BIOS的程序入口处,开始运行。比如jmp
F000:E05B,跳到0xFE05BH处执行。
在1M的地址空间中,0x00000H~0x9FFFF为RAM,0xA0000H~0xBFFFFH为图形卡映射区,0xC0000H~0xFFFFFH为BIOS例程。其中0xA0000H~0xFFFFFH被称作Shadow RAM,BIOS在运行中会将自身从ROM中拷贝到RAM,以提高系统效率。
BIOS第一步是自检,即进行所谓的POST(Power On Self Test),对硬件进行检测。第二步是进行本地设备的枚举和初始化。根据其不同功能,BIOS由两部分组成:POST代码和运行时服务。当POST完成之后,它被从内存中清理了出来,但是BIOS运行时服务依然保留在内存中,目标操作系统可以使用这些服务。
引导操作系统时,BIOS运行时会按照CMOS的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备,甚至是USB闪存。通常,Linux都是从硬盘上引导的,其中主引导记录(MBR)中包含主引导加载程序。MBR是一个512字节大小的扇区,位于磁盘上的第一个扇区中(0道0柱面1扇区)。当MBR被加载到RAM(0x07C00H)中之后,BIOS就会将控制权交给MBR。
三、启动引导程序
MBR就是主引导记录(Master Boot Record),包括0柱0头1扇区的512个字节,它的任务是完成BIOS到操作系统的交接。0000H~01BDH为MBR代码区,负责装载并允许系统引导程序;01BEH~01FDH为分区表信息;01FEH~01FFH的2个字节值为结束标志55AA,如果该标志错误系统就不能启动。
在单一的MBR中只能存储一个操作系统的引导记录,当需要多个操作系统时就会出现问题,所以需要更灵活的引导加载程序。Linux下常见的引导程序有GRUB和LILO。LILO将操作系统位置信息写到MBR中,而GRUB的操作系统位置信息是配置在文件系统中的配置文件里。这里以GRUB为例,进行引导。
GRUB根据其启动过程的文件stage1、xxx_stage1_5、stage2,可分为三个过程。
stage1的大小为512字节,使用grub命令设置启动盘时,会将stage1写入到MBR中,用于引导xxx_stage1_5或stage2。
xxx_stage1_5的前缀为文件系统类型,其功能为确保识别到启动磁盘的文件系统类型。
stage2为GRUB引导的主要阶段,它读取/boot/grub/menu.list(实际指向grub.conf)文件并提供交互界面,根据用户选择和相关配置加载内核。
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /vmlinuz-2.6.18-1.2798.fc6 ro
root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.18-1.2798.fc6.img
这是FC8中menu.list的配置,每一项的内容不再一一解释,只对initrd作相关说明。
initrd(boot loader initialized RAM disk)就是由boot loader初始化的内存盘。在内核启动前,GRUB将存储介质中的initrd文件加载到内存,内核启动时会在访问真正的根文件系统前先访问该内存中的initrd文件系统。在GRUB配置了initrd的情况下,内核启动被分成了两个阶段,第一阶段先执行initrd文件系统中的“某个文件”,完成加载驱动模块等任务,第二阶段才会执行真正的根文件系统中的/sbin/init进程。第一阶段启动的目的是为第二阶段的启动扫清一切障碍,最主要的是加载根文件系统存储介质的驱动模块。initrd有cpio-initrd和image-initrd这两种格式,前者的制作方式和处理流程都更为清晰。
内核加载完成以后会启动/sbin/init,至此进入操作系统加载过程。
四、操作系统初始化
init进程是系统所有进程的起点,进程号是1。init进程是所有进程的发起者和控制者。init进程有两个作用。一是扮演终结父进程的角色。二是根据/etc/inittab来执行相应的脚本进行系统初始化。
inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式:
id:runlevel:action:process
其中id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。
通过inittab的内容,初始化过程为:
首先寻找initdefault,设置默认的启动级别,如果没有设置initdefault项,init将在控制台上请求输入runlevel。
运行脚本/etc/rc.d/rc.sysinit。该阶段主要进行各个运行级别中相同的初始化工作。完成后进入选定的运行级别中停止或运行相应的服务。
以ttyn为参数运行/sbin/mingetty,打开ttyn终端用于用户登录。如果进程退出则再运行mingetty。
至此,进入用户登录界面。启动完毕。
引用文献: