当前位置:文档之家› linux系统引导过程

linux系统引导过程

linux系统引导过程简介首先,主板的BIOS会读取硬盘的主引导记录(MBR),MBR中存放的是一段很小的程序,他的功能是从硬盘读取操作系统核心文件并运行,因为这个小程序太小了,因此通常这个小程序不具备直接引导系统内核的能力,他先去引导另一个稍微大一点的小程序,再由这个大一点的小程序去引导系统内核.在linux系统中这样的小程序有LILO和GRUB.在这个项目中,我决定用LILO来做系统引导程序.在软盘上启动linux系统的过程和在硬盘上启动的过程相似.Linux系统内核被引导程序装入内核并运行后,linux内核会检测系统中的各种硬件.并做好各种硬件的初始化工作,使他们在系统正式运行后能正常工作.之后内核做的最后一个工作是运行/sbin下的init程序,init是英文单词initialization(初始化)的简称,init程序的工作是读取/etc/inittab 文件中描述的指令,对系统的各种软硬件环境做最初化设定.最后运行mingetty等待用户输入用户名登录系统.所有的工作就这么简单,虽然linux启动的时候有很多内容,看上去十分高深,但是都不过是对这个过程的扩充.明白了这个道理,你可以写一些脚本程序让他在系统启动的特定时间运行完成任务.事实上系统内核并不关心/sbin下的init是不是真的init,只要是放在/sbin下名叫init 的可执行程序他都可以执行.Red Hat Enterprise Linux在电脑的启动阶段,一共经历以下两个阶段:1.启动内核。

在这个阶段,内核装入内存并在初始化每个设备驱动器时打印信息。

2.执行程序init.(系统初始化).装入内核并初始化设备后,运行init程序。

init程序处理所有程序的启动,包括重要系统精灵程序和其它指定在启动时装入的软件。

开机---BIOS自检---载入启动程序---加载内核---启动init服务---加载/etc/inittab---Run level---rc.sysinit---rc--- mingetty---rc.local一.BIOS自检当电脑开机的时候,电脑会进入BIOS,在PC机中引导LINUX是从BIOS中的地址0xFFFF0处开始的.BIOS的第一个步骤是加电自检,即所谓的POST(Power On Self Test),BIOS的第二个步骤是进行本地设备的枚举和初始化,侦测电脑周边配套设备是否工作正常,如cpu的类型,速度,缓存等;主板类型,内存的速度,容量,硬盘的大小,类型和工作模式,风扇速度等,主要是为了检查这些设备在开机的时候是否能通过检测,说明电脑可以正常的工作.BIOS由两部分组成:POST代码和运行时的服务.当POST完成之后,它被从内存中清理了出来,但是,BOIS 运行时服务依然保留在内存中,目标操作系统可以使用这些服务二.载入启动程序BIOS自检完成后,BIOS会根据用户设置的启动顺序来由哪个设备启动电脑的操作系统,设备需是处于活动状态并且可以引导的,(引导设备可以是软盘,CD-ROM,硬盘上的某个分区,网络上的某个设备,甚至是USB闪存),对于linux这个设备一般是硬盘.也就是进入硬盘的MBR区域,(master boot record,位于磁盘上的第一个扇区中,0道0柱面1扇区),这个区域中有512个字节的大小,其中前446个字节中保存的就是启动程序,(446个字节包含可执行代码和错误消息文本,接下来的64个字节是分区表,其中4个分区的记录,每个记录的大小是16个字节,MBR以两个特殊数字的字节0xAA55结束,这个数字用来进行MBR的有效性检查,当MBR被加载到RAM中之后,BIOS就会将控制权交给MBR),然后由这个小程序来加载存储在其他位置的操作系统,也就是启动grub程序.(grub不像lilo一样使用裸扇区,而是可以从ext2或ext3文件系统中加载LINUX内核).要看MBR的内容,请使用下面的命令#从/dev/sda上读取前512个字节的内容,并将其写入mbr.bin文件中[root@localhost ~]# dd if=/dev/sda of=mbr.bin bs=512 count=1#以十六进制和ASCII码格式打印这个二进制文件的内容[root@localhost pam.d]# od -xa mbr.bingrub程序的这个配置文件是保存在:/boot/grub/grub.conf这个文件中,如果修改这个文件后,设置会立刻生效.使用cat /boot/grub/grub.conf,就会出现这个文件的内容,最前面是注释。

可以将这个文件逻辑上分为两个部分,第一个部分是基本设定,第二个部分是区分开多个操作系统的设定。

第一个部分中的defaule=0,是指第一组操作系统开机。

如果有两组操作系统的开机设定,而defaule=1,那么预设使用第二组操作系统开机。

所谓第一组和第二组程序就是指的是title开始的部分,这里是区分操作系统的部分。

如何知道要使用那一个系统呢,可以看到在title开始的部分的下一行有:root (hd0,0)hd0,表示第一个硬盘0:指的是硬盘的第一个分区,在括号中的那个0和defaule=0是一一对应的。

这就可以知道是启动的是那一个操作系统。

timeout=5是指进入GRUB的画面后,会有5秒的时间让使用者选择使用那个操作系统开机。

如果在这个时间没有作出选择那么,那么就使用defaule的设定splashimage=是开机使用的背景图案。

hd0,表示第一个硬盘0:指的是硬盘的第一个分区,和上面的一样,/grub/splash.xpm.gz就是开机使用的背景图案的文件名称hiddenmenu指令是隐藏开机的选单。

title:开机选单的标题名称。

root (hd0,0):0表示下面要介绍的档案位于那个目录中。

(hd0,0)同样是指/boot目录kernel:存放内核的位置,由于(hd0,0)指的是/boot目录,所以这个文件在boot目录中。

ro root=LABEL=/就是设根目录的位置,ro表示read only,所以有这行的设定,才能读取根目录。

rhgb:red hat图形界面启动,取代以前的文本界面。

如果要使用文本界面的形式启动,只要将rhgb删除即可。

quite:在开机过程中不要显示错误的信息。

如果要显示错误信息,只要删除quite即可。

initrd:将initrd映像文件加载到内存。

这个文件里面存放的都是驱动程序。

三.加载内核正确的启动了启动程序之后,接下来的工作就是载入操作系统的内核.内核主要作用是取得BIOS所检测到的硬件设备的信息,然后将这些硬件设备自己来管理,这样才能够提供给Linux系统使用。

接手了硬件设备后,然后就要加载这些设备的驱动程序。

以便于控制电脑上的设备如何正确的工作。

加载完硬件的驱动程序后,接下来就加载文件系统了,也就是加载开机所需要的库文件,程序等,所以/etc /bin /sbin /dev /lib这些目录的根目录必须是同一个分区,否则会造成Linux 的开机失败。

上面在grub中有“ro root=LABEL=/”这样的信息,是以只读的方式来加载所需要的文件,程序,这是为什么呢?是因为Linux的内核在启动的过程中,不知道将会发生什么故障,可能不是很稳定,如果以可读可写的方式来加载,那么启动的过过程组中如果出现异常或者是断电,那么就有可能破坏,为了避免这些问题的发生,就采取只读的方式来挂载文件系统。

LINUX内核一般是压缩保存的,因此,它首先要进行自身的解压缩。

内核映象前面的一些代码完成解压缩。

内核映像并不是一个可执行的内核,而是一个压缩过的内核映像,它通常是一个zlmage(压缩映像,小于512kb)或一个bzlmage(大于512kb),它是提前使用zlib进行压缩过的.在这个内核映像前面是一个例程,它实现少量硬件设置,并对内核映像中包含的内核进行解压,然后将其放入高端内存中,如果有初始RAM磁盘映像,就会将它移动到内存中,并标明以后使用,然后此例程会调用内核,并开始启动内核引导的过程当bzlmage被调用时,(以i386为例),我们从./arch/i386/boot/head.S的start汇编例程开始执行,这个例程会执行一些基本的硬件设置,并调用./arch/i386/boot/compressed/headS中的startup_32例程,此例程会设置一个基本的环境(堆栈等),并清楚Block Started bySymbol(BSS),然后调用一个叫做decompress_kernel的C函数(在./arch/i386/boot/compressed/misc.c中)来解压内核.当内核被解压到内存中之后,就可以调用它了.这是另外一个startup_32函数,但是这个函数在./arch/i386/kernel/head.S中.在这个新的startup_32函数(也称为清楚程序或进程0)中,会对页表进行初始化,并起用内存分页功能.然后会为任何可选的浮点单元(FPU)检测CPU的类型,并将其存储起来供以后使用,然后调用start_kernel函数(在init/main.c中),它会将您带入与体系结构无关的Linux内核部分.实际上,这就是Linux内核的main函数.通过调用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)来挂载最终的根文件系统.在GRUB命令中,我们可以使用initrd映像引导一个特定的内核,方法如下:grub> kernel /bzImage-2.6.14.2[Linux-bzImage, setup=0x1400, size=0x29672e]grub>initrd /initrd-2.6.14.2.img[Linux-initrd @ 0x5f13000, 0xcc199 bytes]grub> bootUncompressing Linux... Ok, booting the kernel.如果不知道要引导的内核的名称,只需使用/然后按下Tab键,就会显示内核和initrd映像列表对grub命令行进行加密a)使用命令/sbin/grub-md5-crypt来产生grub使用的密码[root@localhost pam.d]# /sbin/grub-md5-cryptPassword:Retype password:$1$3YbPF$zFVRY6J8VxNR9Ok4fXRkr1b)修改/etc/grub.conf加入password --md5 $1$3YbPF$zFVRY6J8VxNR9Ok4fXRkr1 一定要放在title之前这样重启系统时在grub的启动grub菜单时,想再按e命令进行编辑时,必须先按p键后输入密码才成.四.启动init服务加载完成内核之后,Kernel会启动init这个程序,init进程是所有进程的起点,也是Linux 内核启动后的第一个动作,所以这个程序的PID是永远是1,也是Red Hat Enterprise Linux 中执行的第一个程序,这个程序会根据Run Level来执行一些相关的程序程序。

相关主题