北在北方

太白枝头看,花开不计年,杯中浮日月,楼外是青天。

导航

Linux引导流程

Posted on 2012-12-12 22:54  CN.programmer.Luxh  阅读(788)  评论(0编辑  收藏  举报

系统引导流程:

  固件firmware(CMOS/BIOS)   ——>  POST加电自检

      

  自举程序BootLoader(GRUB)  ——>  载入内核

      

  载入内核Kernel          ——>  驱动硬件

      ↓

    启动init进程

      

  读取执行配置文件/etc/inittab 

 

1、init进程

  在UNIX系统中,init是第一个可以存在的进程,它的PID恒为1,但它也必须向一个更高级的功能负责:PID为0的内核调度器(kernel scheduler),从而获得CPU时间。

 

2、inittab 配置文件

[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:3:initdefault:
[root@localhost ~]#

  1)运行级别:

    0  -  关机(如果运行级别设置为0,就会开不了机,因为init进程读取到配置文件inittab的运行级别为0就关机了

    1  -  单用户模式 (没有图形界面,只有root用户可以登录)

    2  -  不带图形界面,多用户模式,不带NFS(NFS,用于linux系统之间的文件共享)

    3  -  不带图形界面,多用户模式

    4  -  未使用,用户可以自己定义

    5  -  linux的图形化多用户模式

    6  -  重启(如果运行级别设置为6,开机后系统就会不停的重启,因为init进程读取到配置文件inittab的运行级别为6就重启了)

  2)查看当前的运行级别:命令runlevel

[root@localhost ~]# runlevel
N 3
[root@localhost ~]#

   如果之前切换过运行级别,运行runlevel命令,还会显示之前的运行级别。例如执行init 2命令切换运行级别后再查看当前的运行级别,会把之前的运行级别也显示出来

[root@localhost ~]# init 2
[root@localhost ~]# runlevel
3 2
[root@localhost ~]#

  3)运行级别切换:init[0123456]

  如切换运行级别为2

[root@localhost ~]# init 2

  4)在inittab文件中,所有条目采取以下格式:

id:run-level:action:process

    id:标志符,一般为两位字母或数字

    run-level:制定运行级别,可以指定多个

    action:指定运行状态

    process:指定要运行的脚本/命令

    -----------------------------------------------------

    action常用取值:

    initdefault:指定系统缺省启动的运行级别

    sysinit:系统启动执行process中指定的命令

    wait:执行process中指定的命令,并等其结束再运行其他命令

    once:执行process中指定的命令,不等待其结束

    ctrlaltdel:按CTRL+ALT+DEL时执行process指定的命令

    如inittab中的:

id:3:initdefault:

    使用initdefault这个action指定系统缺省运行级别

#System initialization
si::sysinit:/etc/rc.d/rc.sysinit

    系统启动时执行: /etc/rc.d/rc.sysinit这个脚本,这个脚本完成系统服务程序启动,如系统环境变量设置、设置系统时钟、加载字体、检查加载文件系统、生成系统启动信息日志文件等

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

    根据默认运行级别,调用/etc/rc.d/rc脚本,执行相应运行级别目录中的服务程序,完成相应运行级别的初始化设置。

[root@localhost ~]# ls /etc/rc.d
init.d  rc0.d  rc2.d  rc4.d  rc6.d     rc.sysinit
rc      rc1.d  rc3.d  rc5.d  rc.local
[root@localhost ~]# 

    如当前的默认运行级别为3,就会执行/etc/rc.d/rc3.d目录中的服务程序,完成初始化。

[root@localhost ~]# ls /etc/rc.d/rc3.d
K01smartd      K75quota_nld     S10network      S22messagebus    S80postfix
K10psacct      K87restorecond   S11auditd       S24avahi-daemon  S82abrt-ccpp
K10saslauthd   K89rdisc         S11portreserve  S25cups          S82abrtd
K15httpd       K99rngd          S12rsyslog      S25netfs         S82abrt-oops
K20tomcat6     S01sysstat       S13cpuspeed     S26acpid         S90crond
K50netconsole  S02lvm2-monitor  S13irqbalance   S26haldaemon     S95atd
K74ntpd        S08ip6tables     S15mdmonitor    S26udev-post     S99local
K75ntpdate     S08iptables      S20kdump        S55sshd
[root@localhost ~]# 

    我们看到在rc3.d目录中,有很多的文件。主要有两种文件,一种以大写字母S开头的文件,一种是以大写字母K开头的文件。如:

    S01sysstat

    S-start,启动服务;01-表示启动的顺序,数字越小,优先级越高;sysstat-要启动的脚本的名称

        如果不想启动一个服务,可将该服务文件的首字母S改成小写或其他字母即可,系统只会启动大写S开头的服务,如改成s01sysstat,这个服务就不会被启动

 

    K01smartd

    K-kill,关闭服务;01-表示关闭的顺序,数字越小,优先级越高;smartd-要关闭的脚本的名称

  5)通过以上文件我们可以看到,系统启动的大致流程:

    Firmware—>Bootloader—>Kernel—>init—>/etc/inittab—>initdefault—>/etc/rc.d/rc.sysinit—>/etc/rc.d/rc—>/etc/rc.d/rcN.d  (N=0-6)

  固件加电自检;加电自检没有问题后读取硬盘主引导记录(MBR)上的自举程序Bootloader;Bootloader载入内核,内核驱动硬件,启动init进程;init进程读取系统配置文件/etc/inittab文件,判断缺省运行级别initdefault,执行脚本/etc/rc.d/rc.sysinit,然后根据缺省运行级别执行相应的服务启动脚本/etc/rc.d/rcN.d(N=0-6);进入登录界面

 

3、在/etc/rc.d/init.d目录中包含各个运行级别的服务启动程序脚本

[root@localhost ~]# ls /etc/rc.d/init.d
abrt-ccpp     crond      irqbalance    netfs        rdisc        sshd
abrtd         cups       kdump         network      restorecond  sysstat
abrt-oops     functions  killall       ntpd         rngd         tomcat6
acpid         haldaemon  lvm2-lvmetad  ntpdate      rsyslog      udev-post
atd           halt       lvm2-monitor  portreserve  sandbox
auditd        httpd      mdmonitor     postfix      saslauthd
avahi-daemon  ip6tables  messagebus    psacct       single
cpuspeed      iptables   netconsole    quota_nld    smartd
[root@localhost ~]# 

   如果想手工启动或停止一个服务,可以执行相应的脚本命令:

   如启动ssh服务:

[root@localhost ~]# /etc/rc.d/init.d/sshd start

   如停止ssh服务:

[root@localhost ~]# /etc/rc.d/init.d/sshd stop

 

4、设置自启动程序

  1)方式一:使用ln -s

  如写了一个简单的脚本msg.script

date >> /root/msg.today
who >> /root/msg.today
free >> /root/msg.today

  把msg.script放到/etc/rc.d/init.d目录下

  现在想让这个脚本在运行级别3能自动执行:

  1.1)给这个脚本可执行权限

[root@localhost ~]# chmod u+x /etc/rc.d/init.d/msg.script

  1.2)使用ln -s生成软链接,并放到运行级别3的服务启动目录中

[root@localhost ~]# ln -s /etc/rc.d/init.d/msg.script /etc/rc.d/rc3.d/S100msg.script

    S100msg.script  S-start;100-启动顺序;msg.script-要启动的脚本

 

  2)方式二:使用chkconfig设置自启动程序

    使用chkconfig --list命令可以查看系统服务在各个运行级别的启动状态,0-6表示运行级别

[root@localhost ~]# chkconfig --list
abrt-ccpp       0:关闭  1:关闭  2:关闭  3:启用  4:关闭  5:启用  6:关闭
abrt-oops       0:关闭  1:关闭  2:关闭  3:启用  4:关闭  5:启用  6:关闭
abrtd           0:关闭  1:关闭  2:关闭  3:启用  4:关闭  5:启用  6:关闭
acpid           0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
atd             0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
auditd          0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
avahi-daemon    0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
cpuspeed        0:关闭  1:启用  2:启用  3:启用  4:启用  5:启用  6:关闭
crond           0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
cups            0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
haldaemon       0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
httpd           0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
ip6tables       0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
iptables        0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
irqbalance      0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
kdump           0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
lvm2-monitor    0:关闭  1:启用  2:启用  3:启用  4:启用  5:启用  6:关闭
mdmonitor       0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
messagebus      0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
netconsole      0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
netfs           0:关闭  1:关闭  2:关闭  3:启用  4:启用  5:启用  6:关闭
network         0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
ntpd            0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
ntpdate         0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
portreserve     0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
postfix         0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
psacct          0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
quota_nld       0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
rdisc           0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
restorecond     0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
rngd            0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
rsyslog         0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
saslauthd       0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
smartd          0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
sshd            0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
sysstat         0:关闭  1:启用  2:启用  3:启用  4:启用  5:启用  6:关闭
tomcat6         0:关闭  1:关闭  2:关闭  3:关闭  4:关闭  5:关闭  6:关闭
udev-post       0:关闭  1:启用  2:启用  3:启用  4:启用  5:启用  6:关闭
[root@localhost ~]#

  查看单个服务在各个运行级别的启动状态:

[root@localhost ~]# chkconfig --list sshd
sshd            0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
[root@localhost ~]# 

  比如现在想让sshd服务在运行级别2345也是关闭的,可以按如下设置

[root@localhost ~]# chkconfig --levels 2345 sshd off

  sshd在所有运行级别都关闭后,想让sshd服务只在运行级别3启动,可按如下设置

[root@localhost ~]# chkconfig --level 3 sshd on

 

  3)方式3,使用ntsysv,ntsysv提供更直观的菜单选择的方式

  如要设置在运行级别3下各个服务的启动设置,可以输入如下命令:

[root@localhost ~]# ntsysv --level 3

  回车后弹出如下界面

    * 表示是要启动的,没有*表示不启动,用空格键选择是否要启动

 

5、使用dmesg检查引导期间的错误

   比如想查看在启动的时候是否识别到网卡:

[root@localhost ~]# dmesg | grep eth0
eth0: registered as PCnet/PCI II 79C970A
eth0: link up
eth0: no IPv6 routers present
[root@localhost ~]#

  查看系统是否识别了硬盘

[root@localhost ~]# dmesg | grep sda
sd 2:0:0:0: [sda] 41943040 512-byte logical blocks: (21.4 GB/20.0 GiB)
sd 2:0:0:0: [sda] Write Protect is off
sd 2:0:0:0: [sda] Mode Sense: 61 00 00 00
sd 2:0:0:0: [sda] Cache data unavailable
sd 2:0:0:0: [sda] Assuming drive cache: write through
sd 2:0:0:0: [sda] Cache data unavailable
sd 2:0:0:0: [sda] Assuming drive cache: write through
 sda: sda1 sda2 sda3 sda4 < sda5 >
sd 2:0:0:0: [sda] Cache data unavailable
sd 2:0:0:0: [sda] Assuming drive cache: write through
sd 2:0:0:0: [sda] Attached SCSI disk
EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: 
dracut: Mounted root filesystem /dev/sda1
SELinux: initialized (dev sda1, type ext4), uses xattr
EXT4-fs (sda5): mounted filesystem with ordered data mode. Opts: 
SELinux: initialized (dev sda5, type ext4), uses xattr
EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: 
SELinux: initialized (dev sda2, type ext4), uses xattr
Adding 2047992k swap on /dev/sda3.  Priority:-1 extents:1 across:2047992k 
[root@localhost ~]# 

  如果没有任何信息显示,说没系统没有识别

 

6、检查系统日志/var/log/messages,查找可能被dmesg忽略的应用程序错误

    如查看是否有关于sshd的错误信息

[root@localhost ~]# grep sshd /var/log/messages

 

7、GRUB

  GRUB的配置文件默认为:

/boot/grub/grub.conf
[root@localhost ~]# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/sda1
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-279.el6.i686)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.32-279.el6.i686 ro root=UUID=1782302e-7804-4b32-9e59-04aac3651342 nomodeset rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet
        initrd /boot/initramfs-2.6.32-279.el6.i686.img
[root@localhost ~]#

  default  定义缺省的启动系统

  timeout  定义缺省的等待时间

  splashimange  定义GRUB界面图片

  hiddenmenu  隐藏菜单

  title  定义菜单项目名称

  root  设置GRUB的根设备即内核所在位置

  kernel  定义内核文件所在位置

  initrd  加载镜像文件

 

8、单用户模式应用

  1)root密码忘记

    进入单用户模式重新设置root密码,方法如下:

    开机按Esc键进入GRUB界面,按e键进入编辑行模式,选中kernel行,再次按e键,在新的界面的最后一行输入1,即可进入单用户模式。

    GRUB界面如下:

  功能键:

    e  编辑当前的启动菜单项

    c  进入GRUB的命令行方式

    b  启动当前的菜单项

    d  删除当前行

    Esc  返回GRUB启动菜单界面,取消对当前单项所做的任何修改

  在GRUB界面按e键,进入如下界面

  选择第二行kernel,按e键,进入如下界面:

  我们要进入运行级别为1的单用户模式,在rhgb quiet后面输入空格,再输入1,然后回车,运行级别就会被保存

  回车后,出现以下界面

  然后按b键启动内核,就可以进入到单用户模式,单用户只有root可以登录,不需要密码

  进入到单用户模式,就可以进行系统修复,修改密码等操作,现在对root密码进行更改就行了

  最后我们切换到运行级别3,多用户模式,用新密码重新登陆系统。

 

  2)设置GRUB密码

    方式一:使用GRUB自带的grub-md5-crypt,输入密码就会得到密文

    方式二:在GRUB交互命令界面使用md5crypt,输入密码就会得到密文

    得到密文后,将密文复制到/etc/grub.conf文件中,放到title上面

 

  以后进入GRUB就需要输入密码了

  2)GRUB修复

    当开机进入grub界面但没有菜单,只剩下一个grub>提示符,解决办法可以尝试手动引导 

grub>cat /boot/grub/grub.conf (查看参数)
grub>root(hd0,0)
grub>kernel 参数
grub>initrd 参数
grub>boot

 

  3)光盘修复

    3.1)把安装盘放到光驱,然后重新启动机器,按F2键进入BIOS选择光驱启动

    3.2)等安装界面出来后,按F5键进入linux rescue模式,然后在boot下输入linux rescue,回车,然后按提示操作