系统初启

系统初启
当打开计算机电源以后,计算机就开始初启过程。初启过程的细节与机器的体系结构有关,但对所有的机器来说,初启的目的是共同的:将操作系统的副本读入内存中,建立正常的运行环境。对于Intel i386系列来说,引导过程分为硬件检测、加载引导程序、初始化内核和实现用户登录。
1.硬件检测
当PC启动时,首先CPU进入实模式,开始执行ROM-BIOS起始位置的代码。BIOS首先执行加电自检程序(POST),完成硬件启动,然后对系统中配置的硬件(如内存、硬盘及其它设备)进行诊断检测,确定各自在系统中存在,并且处于正常状态。自检工作要经历2~3分钟时间。自检工作完成后,按照预先在系统CMOS中设置的启动顺序,ROM-BIOS搜索软盘、硬盘,以及CD-ROM等设备的驱动器,读入系统引导区,通常都是磁盘上的第一个扇区,并将系统控制权交给引导装入程序。
2.加载引导程序
整个硬盘的第一个扇区是整个硬盘的引导扇区,加电后从这个扇区引导,所以它称作主引导记录块MBR。MBR中含有磁盘分区的数据和一段简短的程序,总共512字节。其中的程序并不直接引导操作系统,而是依据盘区划分的信息找到“活动”分区,再从活动分区中读入其引导扇区到内存,执行该引导扇区中的程序,再由该程序从硬盘中读入其它几个更为复杂的程序,并由它们加载操作系统的内核。
引导扇区中的程序及其辅助程序(不包括LILO)采用汇编语言编写,共有三个汇编程序:
(1)bootsect.S,Linux引导扇区的源代码,汇编后不能超过512字节。
(2)setup.S,辅助程序的一部分。
(3)video.S,另一部分辅助程序,用于引导过程中的屏幕显示。
当BIOS引导一个系统时,总是把引导扇区读到内存的低端(即640KB的基本内存),然后由bootsect_helper子程序将低端内存的内核复制到高端内存上,并将低端内存复位。这样做就能满足Linux核心中驱动程序大量增长的需求,以便适应不同的系统配置。内核映像一般都是经过压缩的,它与引导扇区和引导辅助程序的映像拼接在一起,称为内核的“引导映像”。大小超过508KB的引导映像称为“大内核”,其文件名为bzImage。解压缩以后的内核映像总是放在地址为0x100000(1MB)的地方。
内核加载完毕,系统跳转到setup.S的开始位置执行。setup.S是在实模式下运行,其主要功能是设置系统参数(包括内存、磁盘等,由BIOS返回)、检测和设置显示器及显示模式,并为进入保护模式做准备。最后,进入保护模式,并转入内核映像的头部开始执行,从而以后不再使用BIOS调用了。
另外,也可以使用Linux引导程序LILO来引导操作系统,LILO也存放在引导扇区(或者放在MBR区,或者在某一磁盘分区的第一个扇区)中。LILO可以让用户从磁盘上的多个操作系统映像中选择引导哪一种操作系统。LILO在系统安装阶段建立一个操作系统映像在磁盘上存储位置的对照表。启动时,LILO利用该表引导BIOS装入指定的操作系统。实际上,除了从软盘上引导以外,Linux一般都是通过LILO引导的。
3.系统初始化
辅助程序setup为内核映像的执行做好了准备(包括解压缩)以后,就跳转到0x100000开始内核本身的执行,下面就是内核的初始化过程。初始化过程可以分为三个阶段:第一个阶段主要是CPU本身的初始化,例如页式映射的建立;第二阶段主要是系统中一些基础设施的初始化,例如内存管理和进程管理的建立和初始化;最后是对上层部分初始化,如根设备的安装和外部设备的初始化等。
在初始化的第一阶段,首先设置内核页表,并启动页面映射机制。然后建立系统的第一个进程init_task。接着,初始化内核的bss(Block Started by Symbol)段,其中是一些全局变量或者静态变量;设置初始状态的中断向量表;把命令行和引导参数复制到内核中一个内容为全0的页面中。
在第二阶段调用函数start_kernel( ),继续进行内核的初始化,甚至可以说这才真正开始内核初始化,这是在较高层次上的初始化。start_kernel( )就好像一般可执行程序中的主函数main( ),它初始化系统内核的各个部分,包括设置内存边界、初始化内存页面;设置各种入口地址,如异常事件处理程序入口、系统调用入口、调用门等;初始化IRQ中断处理机制;初始化信号机制;读取实时时间,重新设置时钟中断的中断服务程序入口等;初始化控制台、显示器;初始化核心模块结构;计算并初始化虚拟内存;对cache初始化;定义系统中最大进程数目;对IPC、磁盘配额等机制进行初始化;最后调用kernel_thread( )创建init内核线程,进行系统配置。init内核线程占用进程向量数组的第一项,由它来创建其它完成系统初始化工作的进程。
在第三阶段,内核线程init首先锁定内核,然后调用过程来初始化外部设备及加载驱动程序(对外设的初始化包括PCI总线的初始化、网络初始化、一系列其他设备的初始化等);创建第二个内核线程keventd,由它充当“代理人”角色,使得某些函数在它的上下文中执行;设置“初始化代码段”和“初始化调度段”等;初始化文件系统,并加载它。
当内核初始化工作完成后,系统中存在着五个运行实体:init线程为系统中的一个线程,它当前处于用户态,由它创建下述四个核心进程:kflushd核心线程、kupdate核心线程、kswapd核心线程和keventd核心线程。
至此,系统初始化已完成。下面的工作就由用户态初始化进程/sbin/init完成系统运行的设置工作。例如,设置操作系统启动时缺省的执行级(通常是3-多用户模式,或者是5-X图形登录方式);激活交换分区、检查磁盘、加载硬件模块;执行相应的脚本文件,建立用户工作环境;显示登录界面及提示信息,接受用户登录。
4.用户登录
在用户态初始化阶段init程序在每个tty端口上创建一个进程,用来支持用户登录。每个进程都运行一个getty程序,它监测tty端口等待用户使用。一旦用户开始使用这个端口,getty进程就运行login程序,提示用户输入账号和口令信息。login程序接受用户输入的信息,然后用系统文件/etc/passwd校验用户信息。/etc/passwd中每一行都记录一个用户的信息,其格式如下:
root:x:0:0:root:/root:/bin/bash
其中各项之间以冒号隔开,各项依次表示用户名、加密口令(x表示口令密码存放在/etc/shadow文件中)、用户ID号、所属用户组号、主目录,以及登录时启动的Shell程序。
如果是合法的用户,则输入正确的信息后可通过验证。login进程将用户的主目录作为当前目录,并执行指定的Shell。这样,用户就登录进入了系统,可以使用Shell交互地执行用户命令。当用户退出系统时,终止该用户的Shell进程。该终端的login进程开始等待下一次用户登录

posted on 2011-01-04 19:36  阿杜的世界  阅读(328)  评论(0编辑  收藏  举报

导航