admin 管理员组

文章数量: 1086019


2024年6月9日发(作者:excel函数公式大全讲解百度云)

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

t---rc---

一.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个字节的内容,并将其写入文件中

[root@localhost ~]# dd if=/dev/sda of= bs=512 count=1

#以十六进制和ASCII码格式打印这个二进制文件的内容

[root@localhost pam.d]# od -xa

grub程序的这个配置文件是保存在:/boot/grub/这个文件中,如果修改这个文件后,

设置会立刻生效.

使用cat /boot/grub/,就会出现这个文件的内容,最前面是注释。

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

作系统的设定。

第一个部分中的defaule=0,是指第一组操作系统开机。如果有两组操作系统的开机设定,

而defaule=1,那么预设使用第二组操作系统开机。

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

何知道要使用那一个系统呢,可以看到在title开始的部分的下一行有:

root (hd0,0)

hd0,表示第一个硬盘

0:指的是硬盘的第一个分区,

在括号中的那个0和defaule=0是一一对应的。这就可以知道是启动的是那一个操作系统。

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

开机。如果在这个时间没有作出选择那么,那么就使用defaule的设定

splashimage=是开机使用的背景图案。

hd0,表示第一个硬盘

0:指的是硬盘的第一个分区,和上面的一样,

/grub/就是开机使用的背景图案的文件名称

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 by

Symbol(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 /

[Linux-initrd @ 0x5f13000, 0xcc199 bytes]

grub> boot

Ok, booting the kernel.

如果不知道要引导的内核的名称,只需使用/然后按下Tab键,就会显示内核和initrd映像

列表

对grub命令行进行加密

a)使用命令/sbin/grub-md5-crypt来产生grub使用的密码

[root@localhost pam.d]# /sbin/grub-md5-crypt

Password:

Retype password:

$1$3YbPF$zFVRY6J8VxNR9Ok4fXRkr1

b)修改/etc/加入password --md5 $1$3YbPF$zFVRY6J8VxNR9Ok4fXRkr1 一

定要放在title之前

这样重启系统时在grub的启动grub菜单时,想再按e命令进行编辑时,必须先按p键后

输入密码才成.

四.启动init服务

加载完成内核之后,Kernel会启动init这个程序,init进程是所有进程的起点,也是Linux

内核启动后的第一个动作,所以这个程序的PID是永远是1,也是Red Hat Enterprise Linux

中执行的第一个程序,这个程序会根据Run Level来执行一些相关的程序程序。利用init程

序可以方便地定制启动其间装入哪些程序。init进程是所有进程的发起者和控制者,init的任

务是启动新进程和退出时重新启动其它进程,例如在大多数Linux系统中,启动时最初装入

六个虚拟的控制台进程,退出控制台窗口时,进程死亡,然后init启动新的虚拟登录控制台,

因而总是提供六个虚拟登陆控控制台进程.

init进程有以下两个作用。

init进程的第一个作用是扮演终结父进程的角色。因为init进程永远不会

被终止,所以系统总是可以确信它的存在,并在必要的时候以它为参照。如果某

个进程在它衍生出来的全部子进程结束之前被终止,就会出现必须以init为参

照的情况。此时那些失去了父进程的子进程就都会以init作为它们的父进程。

init的第二个作用是在进入某个特定的运行级别时运行相应的程序,以此对

各种运行级别进行管理。它的这个作用是由/etc/inittab文件定义的。

启动init服务的目的就是为了用来初始化Linux的环境。也就代表了Linux已经顺利的加载

了内核,这个时候的系统启动就进入了另外的一个阶段:系统初始化阶段

init程序其实是去读取/etc/inittab配置文件的配置,根据配置来决定作什么工作,可以使用cat

/etc/inittab指令,就可以看到这个文件的内容,里面设置了init需要作哪些系统初始化工作,

如设置键盘、字体、装载模块,设置网络等。

1.决定要使用那个run level

Linux有个运行级系统,运行级是表示系统当前状态和init应运行哪个进程并保持在这种系

统状态中运行的数字。run level可以从0到6分成7种,一般是为了执行不同的程序或环

境而设置的

run level可以从0到6分成7种,一般是为了执行不同的程序或环境而设置的

run level 0:是作关机,所以不能设置initdefault中,也就是id:5:initdefaule的设置。否者

一开机就会作关机的动作。

run level 1:是Single user mode模式,只允许root账号登录,主要是作一些系统维护的

工作。

run level 2:可以使所有的用户登录,但不会启用NFS working,也就是没有网络功能

run level 3:可以使所有用户登录,并拥有完整的功能。包含run level 2没有的功能,但是

开机后是用文本模式

run level 4 :使用者自己定义,但是默认情况下和run level 3完全相同,

run level 5:和run level 3几乎一样,唯一的不同是开机后是图形界面,

run level 6:重启。所以run level 6也不会设置在initdefault中,否者开机后立刻重启

一般情况下我们使用最多的是1,3,5这三个run level,那么这三个有什么不同的呢,主

要差别在执行程序的数量不同。

可以使用init指令来定义使用那个run level,只要在命名提示符号的后面输入"init 3"就进入文

本界面,如果输入"init 6"那么电脑就会重启,如果是"init 0",那就关机

id:5:initdefault:表示当前默认运行级别是run level 5,是图形界面。

2.执行初始操作系统的程序

在init的配置文件中有如下一行:

si::sysinit:/etc/rc.d/t 表示启动时自动执行/etc/rc.d/t脚本(sysinit)

t是由init执行的第一个脚本,它主要完成一些系统初始化的工

作。t是每一个运行级别都要首先运行的重要脚本,它主要完成的工

作有:激活交换分区、检查磁盘、加载硬件模块以及其他一些需要优先执行的任

务。/etc/rc.d/t主要完成各个运行模式中相同的初始化工作,包括:

设置初始的$PATH变量;

配置网络;

为虚拟内存启动交换;

设置系统的主机名;hostname在/etc/sysconfig/network文件中

检查root文件系统,以进行必要的修复;

检查root文件系统的配额;

为root文件系统打开用户和组的配额;

以读/写的方式重新装载root文件系统;

清除被装载的文件系统表/etc/mtab;

把root文件系统输入到mtab;

使系统为装入模块做准备;

查找模块的相关文件;

检查文件系统,以进行必要的修复;

加载所有其他文件系统;

清除/etc/mtab、/etc/fastboot和/etc/nologin;

删除UUCP的lock文件;

删除过时的子系统文件;

删除过时的pid文件;

设置系统时钟;

激活交换分区;

初始化串行端口;

装入模块。

3.执行run level对应目录中的程序

用来决定启用那些服务,也就是执行rc程序

在t执行后,将返回init,继续执行/etc/rc.d/rc程序,对每一

个运行级别来说,在/etc/rc.d子目录中都有一个对应的下级目录。这些运行级

别的下级子目录的命名方法上rcX.d, 其中X就是代表运行级别的数字

在各个运行级别的子目录中,都建立有到/etc/rc.d/init.d子目录中命令

脚本程序的符号链接

如输入ls -l /etc/rc.d这个指令,就可以看到所有的run level所对应的

目录,在这些目录当中,都是内置一些要执行的一些程序。也就是要启动那些服

务。本例的run level是5,就会执行rc5.d这个目录中的程序。那么就会启动

这个目录中的服务.

输入ls -l /etc/rc.d/rc5.d可以查看这个目录中有哪些内容,这个文件夹

中的都是一些链接文件,这些名称链接的格式可以分为主要的三个小段:以K或S

开头。K=Kill表示停用,S=Start表示启用服务,并且K先执行,然后执行

S;中间是两位的数字,代表执行的先后顺序,数字越小,越先执行;是程序名称。

系统会按照这个目录中的程序,先关闭某些程序,然后启动某些需要的服务.一

般来说,这些脚本不需要编辑或改变,是系统缺省的。

以运行级别5为例,init将执行配置文件inittab中的以下内容:

l5:5:wait:/etc/rc.d/rc 5 当运行级别为5时,以5为参数运行/etc/rc.d/rc脚本,init将等待其返

回(wait)

这一行表示以5为参数运行/etc/rc.d/rc,/etc/rc.d/rc是一个shell脚本,

它接受5作为参数,去执行/etc/rc.d/rc5.d/目录下的所有的rc启动脚本,

/etc/rc.d/rc5.d/目录中的启动脚本实际上都是一些链接文件(用来呼叫

/init.d目录中程序,并带有一个启动或停止服务的参数),而不是真正的rc启

动脚本,真正的rc启动脚本实际上都在/etc/rc.d/init.d/目录下。而这些rc

启动脚本有着类似的用法,它们一般能接受 start、stop、restart、status等

参数。

/etc/rc.d/rc5.d/中的rc启动脚本通常是以K或S开头的链接文件,以S

开头的启动脚本将以start参数来运行。如果发现相应的脚本也存在K打头的链

接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将

首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做

是为了保证当init改变运行级别时,所有相关的守护进程都将重启。

至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig来自行

设定。常见的守护进程如下。

amd:自动安装NFS守护进程。

apmd:高级电源管理守护进程。

arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对应的数据库。

autofs:自动安装管理进程automount,与NFS相关,依赖于NIS。

crond:Linux系统下计划任务的守护进程。

named:DNS服务器。

netfs:安装NFS、Samba和NetWare网络文件系统。

network:激活已配置网络接口的脚本程序。

nfs:打开NFS服务。

portmap:RPC portmap管理器,它管理基于RPC服务的连接。

sendmail:邮件服务器sendmail。

smb:Samba文件共享/打印服务。

syslog:一个让系统引导时启动syslog和klogd系统日志守候进程的脚本。

xfs:X Window字型服务器,为本地和远程X服务器提供字型集。

Xinetd:支持多种网络服务的核心守护进程,可以管理wuftp、sshd、telnet等 服务。

这些守护进程启动完毕,rc程序也就执行完了,然后又将返回init继续下

一步。

4.再设定某个组合键

ca::ctrlaltdel:/sbin/shutdown -t3 -r now

当启动的过程中按下crtl+alt+del键会执行shutdown -t3 -r now这个指

令(重启系统)

5.定义UPS不间断电源系统

pf::powerfail:/sbin/shutdown -f -h +2 "Power Restored;Shutdown

Cancelled"

如果你的服务器有UPS,当电源发生问题或电源恢复的时候,执行这些程序,

当电源发生问题时,执行shutdown -f -h +2

当电源恢复工作时,执行shutdown -c 表示在关机前取消关机的操作,这个时候必须取

消关机操作。

由于UPS可以短暂的为linux服务器提供电力服务,但是UPS不会一直提供电力,到

UPS电力用完,可能会造成Linux不正常关机,而是UPS会通知电脑,电源发生问题,要

求linux正常的关机,避免内存的资料没有保存到硬盘上。以上的功能必须是UPS支持以

上的功能的是够才会发生这些动作,如果UPS不支持这些功能,这两条语句没有任何的作

用。

6.产生6个虚拟控制台。也就是tty1到tty6

#Run gettys in standard runlevels

1:12345:respawn:/sbin/minggetty tty1

2:2345:respawn:/sbin/minggetty tty2

3:2345:respawn:/sbin/minggetty tty3

4:2345:respawn:/sbin/minggetty tty4

5:2345:respawn:/sbin/minggetty tty5

6:2345:respawn:/sbin/minggetty tty6

使用mingetty指令分别产生tty1到tty6这6个虚拟控制台

在2.3.4.5级别上以ttyX为参数执行/sbin/mingetty程序,打开ttyX终端用于用户登陆,如果进

程退出则再次运行mingetty程序(respawn)

7.如果启用的是run level 5,就会初始化X Windows环境

#Run xdm in runlevel 5

x:5:respawn:/usr/bin/X11/xdm -nodaemon

在5级别上运行xdm程序,提供xdm图形方式登陆界面,并在退出时重新执行

(respawn),/etc/X11/prefdm -nodemon:就是初始化X Windows环境

五.执行/etc/ec.d/

(s99local -> ../) s后面的99表示最后执行的意思

RHEL 4中的运行模式2、3、5执行Run Level目录中相对的程序链接后,都把/etc/rc.d/

做为初始化脚本中的最后一个,所以用户可以自己在这个文件中添加一些需要在其他初始化

工作之后、登录之前执行的命令。在维护Linux系统时一般会遇到需要系统管理员对开机或

者关机命令脚本进行修改的情况。如果所做的修改只在引导开机的时候起作用,并且改动不

大的话,可以考虑简单地编辑一下/etc/rc.d/脚本。这个命令脚本程序是在引导过程

的最后一步被执行的。我们可以将需要开机执行的程序或者指令写入这个文件中.

六.执行/bin/login程序

login程序会提示使用者输入账号及密码,接着编码并确认密码的正确性,

如果账号与密码相符,则为使用者初始化环境,并将控制权交给shell,即等待

用户登录。

login会接收mingetty传来的用户名作为用户名参数,然后login会对用户

名进行分析。如果用户名不是root,且存在/etc/nologin文件,login将输出

nologin文件的内容,然后退出。这通常用来在系统维护时防止非root用户登

录。只有在/etc/securetty中登记了的终端才允许root用户登录,如果不存在

这个文件,则root可以在任何终端上登录。/etc/usertty文件用于对用户作出

附加访问限制,如果不存在这个文件,则没有其他限制。

在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的

其他信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,则将主目录默认

设置为根目录;如果没有指定shell,则将shell类型默认设置为/bin/bash。

login程序成功后,会向对应的终端再输出最近一次登录的信息(在

/var/log/lastlog中有记录),并检查用户是否有新邮件(在/usr/spool/mail/

的对应用户名目录下),然后开始设置各种环境变量。对于bash来说,系统首

先寻找/etc/profile脚本文件并执行它;然后如果用户的主目录中存

在.bash_profile文件,就执行它,在这些文件中又可能调用了其他配置文件,

所有的配置文件执行后,各种环境变量也设好了,这时会出现大家熟悉的命令行

提示符,至此整个启动过程就结束了。


本文标签: 程序 启动 内核 进程