日期:2014-05-16 浏览次数:20712 次
引导装入程序(Bootloader)是BIOS将操作系统内核映像装载到RAM中执行的第一个程序。
软盘启动与磁盘启动过程稍有不同,软盘启动时,BIOS将启动软盘的第一扇区指令装载到RAM中,由于通常现代内核都大于一个扇区大小(512B),因此第一扇区的指令通常是将包含内核映像的扇区加载到RAM中。
从硬盘启动时,硬盘的第一个扇区MBR中包含分区表和一小段程序,这段小程序用来装载被启动的操作系统所在分区的第一个扇区。Win98采用MBR中的小程序加载操作系统内核,而Linux在用一种更灵活的加载方式,bootloader。
Linux2.4及以前的版本,在第一个512字节有一个最小的引导程序,因此在第一扇区拷贝一个内核镜像就可以使软盘启动,但在2.6内核中不再有该引导程序,要想在软盘中启动,必须采用与磁盘类似的方式,在第一个扇区中装入一个引导程序。
Bootloader通常被安装在MBR上代替上面负责引导的小程序。Bootloader通常由于大于一个扇区,会被分为两部分,在BIOS将Bootloader的第一部分加载到RAM的0x00007c00处开始执行,bootloader自己加载到0x00096a00,建立实模式站(0x00098000~0x000969ff),并将bootloader的第二部分装入到0x00096c00开始的RAM中。
第二部分一次从此版读取操作系统映射表,提示给用户,用户可以选择要启动的系统,引动程序将相应分区的引导扇区拷贝到RAM中并执行,或直接将内核拷贝到RAM中。
Bootloader的主要执行过程:
setup()函数有汇编实现放在内核映像文件的偏移量0x200处,bootloader将其装载到0x00090200开始的RAM中。
setup()函数的主要工作是初始化计算机中的硬件设备,并为内核程序的执行建立环境。尽管BIOS已经完成大部分设备的初始化,但是Linux并不依赖与BIOS,而已自己的方式重新初始化设备,以增强可移植性和健壮性。
@TO-DO setup()过程
存在两个startup_32函数,setup()的最后是跳转执行的是arch/i386/boot/compressed/head.S中的startup_32(),此时startup_32已经被移动到0x00100000或0x00001000,对应于高装载或低装载。该函数的主要工作是解压内核。
解压完的内核映像从arch/i386/kernel/head.S开始执行。该文件中包含另一个startup_32函数。改startup_32为Linux的第一个进程(pid=0)建立执行环境。
@TO-DO startup_32()过程
startup_32函数最后回跳转执行start_kernel(),start_kernel完成内核初始化工作。start_kernel开始执行后会显示"Linux version 2.6.11..."
该函数中最主要的一个步骤是调用kernel_thread()为进程1创建内核线程。这个线程回创建其它线程并执行/sbin/init程序。该程序会在控制台输出初始化信息,直至最后出现登录提示符,或X登录窗口。通知用户内核已启动,正在运行。
(该部分只适用Redhat系,如RHEL,CentOS,Fedora等,Debian/Ubuntu启动过程与此不同,后期会有分析)
/sbin/init(进程1)会利用/etc/inittab获取运行级,并根据不同运行级的配置启动不同的服务项目。
inittab配置文件格式
[设置项目]:[run level]:[init的操作行为]:[命令项目] 设置项目:最多4个字符,表示init的主要目的,就是一个名字 run level:该条目的运行级别 init操作行为: 主要可选值如下: initdefault:表示默认的运行级别值 sysinit:系统初始化操作项目 ctrlaltdel:表示[ctrl+alt+del wait:表示必须等待后面的命令执行完才可以执行后续操作 respawn:表示后面的操作会重新启动 命令项目:执行该项目的命令,通常为一个脚本命令
ini