标签:linux启动流程
CentOS6系统启动流程图
启动第1步加载BIOS
当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了。在BIOS将系统的控制权交给硬盘第一个扇区之后,就开始由Linux来控制系统了。
启动第2步读取MBR
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,可里面却存放了预启动信息、分区表信息。可分为两部分:第一部分为引导(PRE-BOOT)区,占了446个字节;第二部分为分区表(PARTITION PABLE),共有66个字节,记录硬盘的分区信息。预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。
系统找到BIOS所指定的硬盘的MBR后,就会将其到0×7c00地址所在的物理内存中。其实被到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了。
启动第3步Boot Loader
Boot Loader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。通常,Boot Loade是严重地依赖于硬件而实现的,不同体系结构的系统存在着不同的Boot Loader。
启动第4步加载内核
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel”。系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
start_kenrel()定义在init/main.c中,它就类似于一般可执行程序中的main()函数,系统在此之前所做的仅仅是一些能让内核程序最低限度执行的初始化操作,真正的内核初始化过程是从这里才开始。函数start_kerenl()将会调用一系列的初始化函数,用来完成内核本身的各方面设置,目的是最终建立起基本完整的Linux核心环境。
在start_kenrel()的结尾,内核通过kenrel_thread()创建出第一个系统内核线程(即1号进程),该线程执行的是内核中的init()函数,负责的是下一阶段的启动任务。最后调用cpues_idle()函数,进入了系统主循环体口,默认将一直执行default_idle()函数中的指令,即CPU的halt指令,直到就绪队列中存在其他进程需要被调度时才会转向执行其他函数。此时,系统中唯一存在就绪状态的进程就是由kerne_hread()创建的init进程(内核线程),所以内核并不进入default_idle()函数,而是转向init()函数继续启动过程。
启动第5步用户层init依据inittab文件来设定运行等级
内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。Linux的运行等级设定如下:
0:关机
1:单用户模式
2:无网络支持的多用户模式
3:有网络支持的多用户模式
4:保留,未使用
5:有网络支持有X-Window支持的多用户模式
6:重新引导系统,即重启
启动第6步init进程执行rc.sysinit
在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。如果你有兴趣,可以到/etc/rc.d中查看一下rc.sysinit文件。
启动第7步启动内核模块
具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。
启动第8步执行不同运行级别的脚本程序
根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。
启动第9步执行/etc/rc.d/rc.local
你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用一目了然:
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don’t
# want to do the full Sys V style init stuff.
rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。你可以把你想设置和启动的东西放到这里。
启动第10步执行/bin/login程序,进入登录状态
此时,系统已经进入到了等待用户输入username和password的时候了,你已经可以用自己的帐号登入系统了。
------------------------------------------------------------------------------------------------------------------
以下为开机启动详细步骤
--------------------------------------------------------------------------------------------------------------------
按下电源开关,电脑会首先启动BIOS(基本输入输出系统),BIOS一般是集成在主板上的。
BIOS主要做如下工作:
1、检测连接硬件,比如显卡,内存,磁盘等等,检测的目的是以后把这些设备信息提供给操作系统;
2、寻找启动磁盘,可以在BIOS开机启动菜单菜单里设置以哪个设备启动系统。比如:光驱,硬盘,网络等等,这个菜单可以设置多个选项,依照设置次序在设备上寻找启动信息;
3、找到了启动硬盘,接着BIOS就会在磁盘上找启动扇区,再找到内核启动系统。
a、先试着寻找第一个扇区,也就是主引导记录MBR(Master Boot Record)
b、如果第一个扇区上没有没有存在操作系统,再去寻找标记为BOOT的分区。
但不论是MBR还是BOOT分区,存储操作系统的空间都只有446字节。如果没有在上面提到的位置找到操作系统的内核,那么BIOS就无法继续启动工作。
那么问题来了,我们的内核往往都会大于446个字节,存放在磁盘的其他位置上,既然446装不下内核,又为了能顺利的找到放在其他位置上的内核,人们想出了一个办法就在446字节里写了一个小程序,当BIOS试着启动操作系统时就会执行这个小程序,然后再由小程序来载入其他位置的内核。这个小程序就是启动载入器(boot loader) ,下面来讲讲这个boot loader是个什么鬼。
linux的boot loader常见的有两种:lilo和grub。
因为lilo存在着一个1024柱面的限制,并且更改了磁盘上的启动信息文件后需要重新启动系统才能同步446字节的内容,因为lilo的缺陷,已经被grub所取代,因为grub没有这些限制。现在的绝大多数类linux系统都采用grub做boot loader,既然如此咱们不用再管lilo了,下面主要讲grub。
grub能修改系统文件的启动内容就可以立刻与446内容同步。下面看看grub里面到底是什么,它存放在在于 /boot/grub中。
GRUB有几个重要的文件,STAGE1、STAGE1_5、STAGE2
STAGE1:它只有512字节,通常放在MBR中,它的作用就是在系统启动时用于装载STAGE2,并且将控制权交给它。
STAGE2:它是GRUB的核心,所有的功能都是由它实现。
STAGE1_5:介于STAGE1和STAGE2之间,是连接它们的桥梁,由于STAGE2较大,通常都是放在一个文件系统当中的,但是STAGE1并不能识别文件系统格式,所以才需要STAGE1_5来引导位于某个文件系统当中的STAGE2。根据文件系统格式的不同,STAGE1_5也需要相应的文件,如:e2fs_stage1_5,fat_stage1_5,分别用于识别ext和fat的文件系统格式。它存放于1-63的柱面之间。
GRUB启动时会在 /boot/grub中寻找一个名字为grub.conf的设置文件,如果找不到此设置文件则不进入菜单模式而直接进入命令行模式。
配置文件中选项含义如下:
title:一个操作系统引动的标头,可以使多个
root:指明所需文件存在于哪个磁盘哪个分区上 (hd0,0)表示第一个硬盘,第一个分区,可参考/boot/grub/device.map
kernel:内核文件的名字,并且会有一些加载内核时的参数 or代表以只读方式加载
initrd:包含一些附加的驱动程序
default=num默认启动第num +1行选项,也就说default=0,则默认启动菜单第1行的操作系统,default=1,则启动第2行的系统,如此类推。
timeout=num搜索设置在num秒之后引导默认的操作系统。CentOS默认是timeout=5,也就是说5秒之内如果没有其他命令就启动系统。如果设成 -1,则 GRUB 会一直等待直到用户选择一个选项为止。
splash pathname/filename指出开机画面的文件所存放的路径和文件名,如splashimage=(hd0,0)/grub/splash.xpm.gz是指用在/boot/grub路径下的splash.xpm.gz文件作为开机画面。感兴趣的可以自己修改下试试。
title OSname, title后面的字符串就是在菜单项上所看见的选项,可以写上操作系统的名字和描述,如title CentOS (2.6.32-431.el6.x86_64)代表这一选项的话,是引导CentOS (2.6.32-431.el6.x86_64)这个系统。
下面使用实例讲解
root (hd0,0)是指第一个硬盘的第一个分区,,可参考/boot/grub/device.map。
kernel /vmlinuz-2.6.32-431.el6.x86_64 是指Linux内核的路径是/boot/vmlinuz-2.6.32-431.el6.x86_64。
ro:表示只读加载kernel
rhgb:表示图形方式启动
为了加速引导启动进程,可以指定磁盘是否加密、语言环境、不启用LVM、RAID、键盘等等,节省dracut查找的时间,如一下几个选项:
rd_NO_LUKS:指定磁盘不加密
LANG:指定语言环境
rd_NO_LVM:禁用LVM
rd_NO_DM:禁用RAID
KEYTABLE:指定字体显示
crashkernel:为启动捕获内核预留指定内存,默认为crashkernel=auto,可自行设定如crashkernel=256M
quiet:表示不输出启动信息
initrd:包含一些附加的驱动程序
内核启动后会向bios查询电脑的所有硬件信息,然后自己接手管理这些设备,以便提供给linux使用
内核会试着驱动这些设备,这些设备的驱动一部分包含在内核中,叫做静态驱动,一部分以模块的方式(动态)存放文件系统中,由于此时还未挂载任何文件系统,因此还不能使用文件系统中的模块,这里只能驱动在内核中存在的硬件驱动程序的对应设备。想驱动内核中未包含的硬件驱动就需要加载文件系统。
内核会尝试挂载根文件系统,根文件系统至少包含 /etc,/bin,/sbin,/lib,/dev这5大目录。缺一不可,否则都会导致系统无法启动。
根文件系统挂载是以只读方式挂载的,因为这时linux还在启动阶段,并不稳定,避免破坏系统文件。
顺利的挂载了根文件系统后,就会启动init服务。内核会按/sbin/init,/etc/init,/bin/init顺序寻找init程序,如果找不到则内核报错,这里存在一个参数init=/bin/sh如果启动时指定了则最后执行/bin/sh而不会产生内核报错。也被称为快速启动,因为它忽略了很多启动初始化工作。
启动init的目的就是为了初始化系统环境,启动了init就证明了内核已经顺利启动,接下来就由init服务来建立linux使用环境
init会根据 /etc/inittab 文件的信息来进行初始化工作。会执行三个脚本 /etc/rc.d/rc.sysinit,/etc/rc.d/rc,/etc/rc.d/rc.local
rc.sysinit 主要的功能用来建立系统的基本环境
启动udev,selinux子系统
udev负责产生/dev中的文件,selinux负责增强系统的安全性
设定核心参数sysctl -p 加载/etc/sysctl.conf
设定系统时间,将硬件时间设定为系统时间
加载键盘和交换分区swapon -a -e
设置主机名,挂载文件系统,并将根重新挂载为可读写的。
加载动态驱动模块USB设备、RAID 和 LVM
卸载/initrd/目录
rc脚本设置启动级别 linux中有许多不同的启动级别,不同的启动级别会制定不同的服务
根据指定rc的参数会对应执行 /etc/rc.d/rc[0-6].d/ 中的连接脚本文件以S开头的则启动
rc.local如果我们想在启动过程中放置一些其他程序,应该使用rc.local脚本中,因为S99local软链接存在于rc[2-5].d中,并指向rc.local文件。
三个rc脚本执行完毕后,就会建立虚拟主控制台执行/bin/login就提供了用户登陆界面了,如果是图形 L5级别的话,会启动Xwindow登录界面。
至此所有的启动就都已经完毕,以上脚本可以自己直接打开查看。
用户环境初始化
输入用户名和密码系统验证,然后会执行一下这些文件:
/etc/profile
/etc/profile.d/*.sh $HOME/.bash_profile
/etc/bashrc
$HOME/.bashrc
系统启动级别:
runlevel 0 关机
runlevel 1 单用户模式,仅root用户可登
runlevel 2 多人模式,无网络
runlevel 3 命令行模式
runlevel 4 保留
runlevel 5 图形模式
runlevel 6 重新启动
查看启动级别
[root@ju grub]# runlevel
N 5
切换启动级别
[root@ju grub]# init 3
标签:linux启动流程
原文地址:http://574076359.blog.51cto.com/10651705/1696191