linux操作系统启动流程 & grub简述
CentOS 5 启动流程
1.POST:通电自检
2.BIOS:BOIS自检,加载硬盘
3.读取MBR,进行MBR引导
4.bootloader:grub引导菜单
5.加载内核 Kernel(ramdisk)
6.启动init进程,依据inittab文件设定运行级别
7.init进程,执行rc.sysinit文件
8.启动内核模块,执行不同级别的脚本程序
9.执行/etc/rc.d/rc.local
10.启动mingetty,进入系统登陆界面。
1.BIOS
打开计算机电源,计算机会首先加载BIOS信息。BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。开机时将ROM中的指令映射到RAM的低地址空间,CPU读取到这些指令,硬件的健康状况进行检查,按照BIOS中设置的启动设备来启动。
2.MBR
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,可里面却存放了预启动信息、分区表信息。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。被复制到物理内存的内容就是Boot Loader,那就是lilo或者grub了。
3.bootloader
Boot Loader 就是在操作系统内核运行之前运行的一段小程序。bootloader供一个菜单,允许用户选择要启动的系统或不同的内核版本; 把用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权移交给内核。
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的。
grub简介
grub启动三阶段:
- stage1: 引导安装在MBR中的引导程序(bootloader)
- stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;
- stage2:读取存放在磁盘上的grub(存放位置:/boot/grub),grub的配置文件:/boot/grub/grub.conf,在etc目录下有此文件的连接文件:/etc/grub.conf
注意:stage2及内核通常放置于同一个磁盘分区。
grub stage2功用:
- 提供菜单、并提供交互式接口
e: 编辑模式,用于编辑菜单;
c: 命令模式,交互式接口; - 加载用户选择的内核或操作系统
允许传递参数给内核
可隐藏此菜单 - 为菜单提供了保护机制
为编辑菜单进行认证
为启用内核或操作系统进行认证
grub的命令行接口
help: 获取帮助列表
help KEYWORD: 详细帮助信息
find (hd#,#)/PATH/TO/SOMEFILE:
root (hd#,#)
kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数;
例如:init=/path/to/init, selinux=0
initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk;
boot: 引导启动选定的内核;
手动在grub命令行接口启动系统:
grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE
grub> initrd /initramfs-VERSION-RELEASE.img
grub> boot
如何识别设备
(hd#,#)
hd#: 磁盘编号,用数字表示;从0开始编号
#: 分区编号,用数字表示; 从0开始编号
grub配置文件
[root@localhost ~]# cat /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/sda2
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-696.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=d420f98e-b665-44d9-a4fd-e0e1503ea87c rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-696.el6.x86_64.img
参数:
default=#: 设定默认启动的菜单项;落单项(title)编号从0开始;
timeout=#:指定菜单项等待选项选择的时长;
splashimage=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;
hiddenmenu:隐藏菜单;
password [--md5] STRING: 菜单编辑认证;
title TITLE:定义菜单项“标题”, 可出现多次;
root (hd#,#):grub查找stage2及kernel文件所在设备分区;为grub的“根”;
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核
initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;
password [--md5] STRING: 启动选定的内核或操作系统时进行认证;
实例:手动恢复grub
1>.屏幕上出现grub的启动项选择菜单时按c键也是可以进入grub>状态的
2>.输入“ root (hd ” ,然后按两次 TAB 键; /* 这会列出你电脑上可能的磁盘设备,硬盘为 hd0/hd1 或 sd0/sd1 等 */
然后,选择你的安装 Linux 系统的硬盘,比如 hd0 ,输入 “ root (hd0, ” 再按两次 TAB 键; /* 这会列出你的第一块硬盘上的分区情况,你会知道哪个是 swap 交换分区, 0x82 ,哪个是 Linux 分区 0x83 */
3>.cat指令是用来查看文件内容的,有时我们不知道Linux的/boot分区,以及/根分区所在的位置,要查看/etc/fstab的内容来得知
这时,我们就要用到cat (hd[0-n],y)/etc/fstab 来获得这些内容;注意要学会用tab键命令补齐的功能;
4>.root (hd[0-n,y) 指令来指定/boot所在的分区
选择你认为可能的 /boot 目录所在的分区:第一块硬盘第一个分区
5>.kernel 指令,用来指定Linux的内核,及/所在的分区
如果/boot有自己独立的分区,kernel格式如下;
kernel /vmlinuz在这里按tab键来补齐,就看到内核全称了 ro root=/dev/hd[a-z]X
6>.initrd 命令行来指定initrd文件
如果/boot是独立的一个分区,格式如下:
grub> initrd /init在这里tab 来补齐;
7>.boot 引导系统
前面的几个步骤都弄好 。就进入引导
4.加载内核
Kernel,内核,Kernel是Linux系统最主要的程序,实际上,Kernel的文件很小,只保留了最基本的模块,并以压缩的文件形式存储在硬盘中,当GRUB将Kernel读进内存,内存开始解压缩内核文件。
initrd(Initial RAM Disk),它在stage2这个步骤就被拷贝到了内存中,这个文件是在安装系统时产生的,是一个临时的根文件系统(rootfs)。因为Kernel为了精简,只保留了最基本的模块,因此,Kernel上并没有各种硬件的驱动程序,也就无法识rootfs所在的设备,故产生了initrd这个文件,该文件装载了必要的驱动模块,当Kernel启动时,可以从initrd文件中装载驱动模块,直到挂载真正的rootfs,然后将initrd从内存中移除。
Kernel会以只读方式挂载根文件系统,当根文件系统被挂载后,开始装载第一个进程(用户空间的进程),执行/sbin/init,之后就将控制权交接给了init程序。
总结
- 探测可识别到的所有硬件设备;
- 加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
- 以只读方式挂载根文件系统:rootfs;
- 运行用户空间的第一个应用程序:/sbin/init
5. init:依据inittab文件设定运行级别
内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。Linux的运行等级设定如下:
[root@localhost ~]# cat /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
7个级别:
0:关机, shutdown
1:单用户模式(single user),root用户,无须认证;维护模式;
2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;
3、多用户模式(mutli user),完全功能模式;文本界面;
4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
5、多用户模式(multi user), 完全功能模式,图形界面;
6、重启,reboot
默认级别:3, 5
级别切换:init #
级别查看:
who -r
runlevel
配置文件/etc/inittab
每行定义一种action以及与之对应的process
id:runlevels:action:process
id:一个任务的标识符,用于唯一标识每个登记项,不能重复
runlevels:系统的运行级别,表示process的action要在哪个级别下运行,该段中可以定义多个运行级别,各级别之间直接写不用分隔符;如果为空,表示在所有的运行级别运行
action:表示对应登记项的process在一定条件下所要执行的动作。
process:任务;
action:
wait:等待切换至此任务所在的级别时执行一次;
respawn:一旦此任务终止,就自动重新启动之;
initdefault:设定默认运行级别;此时,process省略;
sysinit:设定系统初始化方式,只有系统开机或重新启动的时候,这个process才会被执行一次,此处一般为指定/etc/rc.d/rc.sysinit脚本;
例子:
id:3:initdefault:
表示我们默认的运行级别是3,也就是说我们默认开机启动会进入命令行模式。
si::sysinit:/etc/rc.d/rc.sysinit
所所有的运行级别下,init依赖/etc/rc.d/rc.sysinit这个脚本对系统进行初始化
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
.....
l6:6:wait:/etc/rc.d/rc 6
l0:标识
0:动作在0级别下运行
wait:是指在切换至0级别时执行后面的process(/etc/rc.d/rc 0),并且init进程会等待直到这些进程终止。/etc/rc.d/rc 0 这是一个脚本,后面的0是传递进去的参数 ,传递进去0就代表着要去启动或关闭/etc/rc.d/rc0.d/目录下的服务脚本所控制服务;
K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的;
S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖的服务先启动,而依赖的服务后启动
[root@localhost rc1.d]# cd /etc/rc.d/rc0.d
[root@localhost rc0.d]# ls
K01smartd K16abrt-ccpp K60crond K75ntpdate K87irqbalance K92ip6tables K99sysstat
K05atd K16abrtd K61nfs-rdma K75quota_nld K87restorecond K92iptables K99vmware-tools
K05wdaemon K25sshd K73winbind K75udev-post K88auditd K92pppoe-server S00killall
K10cups K30postfix K74acpid K83bluetooth K88rsyslog K95firstboot S01halt
K10psacct K30spice-vdagentd K74haldaemon K84NetworkManager K89netconsole K95rdma
K10saslauthd K43vmware-tools-thinprint K74ntpd K84wpa_supplicant K89portreserve K99cpuspeed
K15htcacheclean K50dnsmasq K75blk-availability K85mdmonitor K89rdisc K99lvm2-monitor
K15httpd K50kdump K75netfs K85messagebus K90network K99rngd
6.系统初始化脚本rc.sysinit
系统初始化脚本:/etc/rc.d/rc.sysinit
- 设置主机名;
- 设置欢迎信息;
- 激活udev和selinux;
- 挂载/etc/fstab文件中定义的所有文件系统;
- 检测根文件系统,并以读写方式重新挂载根文件系统;
- 设置系统时钟;
- 根据/etc/sysctl.conf文件来设置内核参数;
- 激活lvm及软raid设备;
- 激活swap设备;
- 加载额外设备的驱动程序;
- 清理操作;
7.启动内核模块,执行不同级别的脚本程序
执行/etc/inittab中脚本:
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
.....
l6:6:wait:/etc/rc.d/rc 6
8.执行/etc/rc.d/rc.local
/etc/rc.d/rc.local是给用户自定义启动时需要执行的文件。
9.启动mingetty,进入系统登陆界面
tty1:2345:respawn:/usr/sbin/mingetty tty1
... ...
tty6:2345:respawn:/usr/sbin/mingetty tty6
(1)mingetty会调用login程序;
(2)打开虚拟终端的程序除了mingetty之外,还有诸如getty等;
CentOS6启动流程
1.POST:通电自检
2.BIOS:BOIS自检,加载硬盘
3.读取MBR,进行MBR引导
4.bootloader:grub引导菜单
5.加载内核 Kernel(ramdisk)
6.启动init进程,依据inittab文件设定运行级别 (inittab用于定义默认运行级别)
7.init进程,执行rc.sysinit文件
8.分别执行/etc/init/rcS.conf、/etc/init/rc.conf、/etc/init/start-ttys.confl来调用命令执行/etc/rc#.d/文件
里面定义的是各种服务的启动脚本,可以ls查看,S开头代表开机启动的服务,K开头的是关机要执行的任务。#代表数字,一个数字代表一个运行级别,共7个运行级别,这里就不多说了
9.执行/etc/rc.d/rc.local
10.执行/bin/login程序,等待用户登录
CentOS7启动流程
1.POST:通电自检
2.BIOS:BOIS自检,加载硬盘
3.读取MBR,进行MBR引导
4.bootloader:grub引导菜单
5.加载内核和inintamfs模块
6.内核开始初始化,使用systemd来代替centos6以前的init程序
7.执行initrd.target
包括挂载/etc/fstab文件中的系统,此时挂载后,就可以切换到根目录了
8.从initramfs根文件系统切换到磁盘根目录
entos7表面是有“运行级别”这个概念,实际上是为了兼容以前的系统,每个所谓的“运行级别”都有对应的软连接指向,默认的启动级别时/etc/systemd/system/default.target,根据它的指向可以找到系统要进入哪个模式
模式:
0 ==> runlevel0.target, poweroff.target
1 ==> runlevel1.target, rescue.target
2 ==> runlevel2.target, multi-user.target
3 ==> runlevel3.target, multi-user.target
4 ==> runlevel4.target, multi-user.target
5 ==> runlevel5.target, graphical.target
6 ==> runlevel6.target, reboot.target
9.systemd执行sysinit.target
10.systemd启动multi-user.target下的本机与服务器服务
11.systemd执行multi-user.target下的/etc/rc.d/rc.local
12.Systemd执行multi-user.target下的getty.target及登录服务
getty.target是启动终端的systemd对象。如果到此步骤,系统没有被指定启动图形桌面,到此就可以结束了,如果要启动图形界面,需要在此基础上启动桌面程序
13.systemd执行graphical需要的服务
区别
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/100142