linux系统启动的简单流程

1. 通电自检

    首先通电,然后cpu会自动加载主板上ROM芯片cmos中的代码BIOS,cpu为什么会这么做呢?因为cpu就是这么设计的。BIOS会完成周边硬件检测,并按次序查找各引导设备,第一个有引导程序的设备即为启动系统用到的设备。这就跟BIOS中的启动次序相关了,如果第一个设备上没有引导程序,BIOS会找下一个。如果找到后但引导失败了,BIOS是不会查找下一个的,因为设备已经启动了。

2. bootloader

    而所谓的引导程序就是磁盘0磁道0扇区MBR中的bootloader. 当BIOS找到bootloader以后,就将控制权全权交给bootloader,自己隐于幕后,等待下一次的开机。bootloader的作用就是加载选定的操作系统的内核至RAM中,并解压展开至固定的位置。多系统共存的场景中,还会提供一个选择菜单。内核引导成功后就开始运行,bootloader便功成身退。内核启动后第一件事就是启动自身初始化:探测可识别的所有硬件,并从磁盘中装载硬件设备的驱动程序。但这时就有问题了,没有驱动内核如何访问磁盘呢?不可能将所有的磁盘驱动都做进内核吧,那样一样内核得有多大啊?

2.1. bootloader的种类

  • NTloader:windows上的bootloader

  • LILO:Linux Loader,属于古老的bootloader,由于LILO只能引导小于1024柱面的磁盘上存放的内核,所以导致如今很少见到。但是它却并没有淘汰,由于它体积小,占用资源小的特点,在Android手机或一些其他地方被广泛的使用。

  • GRUB:GRand Unified Bootloader,取代LILO成为linux上使用最为广泛的bootloader. grub功能十分强大:首先它对磁盘的大小并没有限制;并且能够引导linux,windows,unix等操作系统;能够选择加载的内核以及提供菜单界面等功能。grub目前有两大版本:

    • grub 0.X:又称为grub legacy,使用于centos5和6上

    • grub 1.X:又称为grub2,相对于grub legacy,grub 2有着翻天覆地的变化。因为grub 2几乎是被重新改写,用于centos7

3. ramdisk 

    事实上,bootloader在加载内核的时候,顺便将一个名为ramdisk的映像设备加载进内存。此段内存空间便成为块设备,可以当硬盘来使用。里面存放的自然就是磁盘的驱动了。但是,ramdisk里面存放的驱动就一定能匹配当前的硬盘吗?我们的回答是肯定的。因为ramdisk是装系统时收集硬件信息做成的。当然也有极低的概率在安装系统时,识别不了硬盘,但如果系统都没装,还怎么引导啊,还怎么讲开机流程啊。在启动过程中,ramdisk会被当成根文件系统,直到找到根位置后才会切换,并以只读的方式挂载根文件系统。至于真根的位置grub的配置文件中会有定义。根文件系统挂载后,便开始启动用户空间的第一个应用程序:/sbin/init

3.1. ramdisk的命名

  • centos 5:initrd-VERSION.img

  • centos 6:initramfs-VERSION.img

    之所以有这样的改变,是因为如果内核访问的是块设备,它会将结果缓存至内存中。而initrd本来就在内存中,再缓存一份那不是多此一举吗?于是,将initrd做成文件系统,内核访问文件系统就不会缓存了

3.2. ramdisk的制作

  • CentOS 5:mkinitrd

  • CentOS 6:dracut,mkinitrd

  • 这里使用的是dracut

  • dracut [OPTION]... <image>  <kernel-version>

    • -m LIST: 模块列表

    • -d LIST: 驱动列表

    例如:# dracut /boot/initramfs-$(uname -r).img $(uname -r)

4. init

    init很有意思,在centos5,6,7上都各不相同。

  • CentOS 5: SysV init

    • 特点:sysV风格的很古老的应用程序。系统启动时,会启动很多服务,服务都是靠脚本启动的。脚本之间是会存在依赖关系的。在centos5上,如果有A脚本和B脚本之间存在依赖关系,B脚本会在A脚本启动完成之后才开始启动,属于串行启动,导致开机速度慢。并且脚本会启动很多进程。

    • 配置文件:/etc/inittab

  • CentOS 6: Upstart

    • 特点:守护进程间的通信依赖于D-Bus进行,因此,可基本实现类似并行启动。脚本B在脚本A刚启动的一瞬间便可以启动,不需要等待脚本A启动完成后。

    • 配置文件:/etc/inittab, /etc/init/*.conf 之所以有两个是为了保证和CentOS 5的兼容性,事实上CentOS 6上/etc/inittab已然形同虚设。

  • CentOS 7: Systemd

    • 特点:它开机不会启动任何服务,服务只有在第一次被访问到时才会真正启动起来,而由于启动服务不在依赖脚本,导致创建的进程很少。

    • 配置文件:/usr/lib/systemd/ 配置文件很多,这只是其中之一

4.1. init的运行级别

    init运行级别为系统维护的目的而设定,途径是设定启动或关闭服务实现。

  • init有0-6共7个级别,其中:

    • 0:关闭所有服务,关机

    • 1:维护模式,单用户模式,sigle模式。此级别可允许root用户直接登录而无须认证

    • 2:维护模式,多用户模式,需要用户认让,会启动网络功能,但不支持使用NFS

    • 3:正常级别,完全多用户模式,文本界面

    • 4:预留级别

    • 5:正常级别,完全多用户模式,图形界面

    • 6:关闭所有服务,重启

    默认级别为3或5


  • 切换级别:

    • init [0-6]

  • 查看级别:

    • runlevel

    • who –r

4.2. init的配置文件

    /etc/inittab(centos5)配置文件格式:每一行定义一个由init执行的action,以及对应的程序。action用于定义程序什么时候被运行,runlevel和action缺一不可

  • 格式:

    • id:runlevel:action:process

  • 例如:设定默认运行级别

    • id:3:initdefault:

  • 例如:定义完成系统初始化的脚本

    • si::sysinit:/etc/rc.d/rc.sysinit

5. rc.sysinit

    init进程启动后,它首先会去读取/etc/inittab中的运行级别。接着执行/etc/rc.d/rc.sysinit脚本进行系统初始化:启动服务。服务的启动是通过脚本完成的,而服务的脚本存放路径为/etc/rc.d/inin/目录下

[root@localhost ~]# ls /etc/rc.d/init.d/
abrt-ccpp         cpuspeed      httpd         messagebus      portreserve  rpcidmapd       sysstat
abrtd             crond         ip6tables     netconsole      postfix      rpcsvcgssd      udev-post
abrt-oops         cups          iptables      netfs           psacct       rsyslog         wdaemon
acpid             dnsmasq       irqbalance    network         quota_nld    sandbox         winbind
atd               firstboot     kdump         NetworkManager  rdisc        saslauthd       wpa_supplicant
auditd            functions     killall       nfs             restorecond  single
autofs            haldaemon     lvm2-lvmetad  nfslock         rngd         smartd
blk-availability  halt          lvm2-monitor  ntpd            rpcbind      spice-vdagentd
bluetooth         htcacheclean  mdmonitor     ntpdate         rpcgssd      sshd

    但是还有一个脚本目录:

[root@localhost ~]# ll /etc/init.d -d
lrwxrwxrwx. 1 root root 11 Apr 18 08:13 /etc/init.d -> rc.d/init.d

    显然两个目录都一样

    这些脚本遵循LSB服务脚本的定义规范,都接受至少四个最基本的参数{start|stop|status|restart}

    这些脚本可直接被调用:/etc/init.d/SVC_SCRIPTS {start|stop|status|restart}

    也可以使用service命令调用:service SVC_SCRIPTS {start|stop|status|restart}

    但脚本并不是直接在此目录下执行,而是执行/etc/rc.d/目录下与启动级别对应目录下的脚本,这也就是为什么init会先读取系统的启动级别了

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

    如果启动级别为3,就会执行rc3.d目录下的脚本

[root@localhost ~]# ll /etc/rc.d/rc3.d/
total 0
lrwxrwxrwx. 1 root root 16 Apr 18 08:23 K01smartd -> ../init.d/smartd
lrwxrwxrwx. 1 root root 17 Apr 18 08:26 K05wdaemon -> ../init.d/wdaemon
lrwxrwxrwx. 1 root root 16 Apr 18 08:24 K10psacct -> ../init.d/psacct
lrwxrwxrwx. 1 root root 19 Apr 18 08:20 K10saslauthd -> ../init.d/saslauthd
lrwxrwxrwx. 1 root root 22 Apr 18 08:20 K15htcacheclean -> ../init.d/htcacheclean
lrwxrwxrwx. 1 root root 15 Apr 18 08:20 K15httpd -> ../init.d/httpd
lrwxrwxrwx. 1 root root 24 Apr 18 08:23 K30spice-vdagentd -> ../init.d/spice-vdagentd
lrwxrwxrwx. 1 root root 17 Apr 18 08:20 K50dnsmasq -> ../init.d/dnsmasq
lrwxrwxrwx. 1 root root 20 Apr 18 08:18 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 13 Apr 18 08:20 K60nfs -> ../init.d/nfs
lrwxrwxrwx. 1 root root 20 Apr 18 08:20 K69rpcsvcgssd -> ../init.d/rpcsvcgssd
lrwxrwxrwx. 1 root root 17 Apr 18 08:18 K73winbind -> ../init.d/winbind
lrwxrwxrwx. 1 root root 14 Apr 18 08:20 K74ntpd -> ../init.d/ntpd
lrwxrwxrwx. 1 root root 17 Apr 18 08:20 K75ntpdate -> ../init.d/ntpdate
lrwxrwxrwx. 1 root root 19 Apr 18 08:23 K75quota_nld -> ../init.d/quota_nld
lrwxrwxrwx. 1 root root 24 Apr 18 08:24 K84wpa_supplicant -> ../init.d/wpa_supplicant
lrwxrwxrwx. 1 root root 21 Apr 18 08:18 K87restorecond -> ../init.d/restorecond
lrwxrwxrwx. 1 root root 15 Apr 18 08:18 K89rdisc -> ../init.d/rdisc
lrwxrwxrwx. 1 root root 14 Apr 18 08:23 K99rngd -> ../init.d/rngd
lrwxrwxrwx. 1 root root 17 Apr 18 08:22 S01sysstat -> ../init.d/sysstat
lrwxrwxrwx. 1 root root 22 Apr 18 08:23 S02lvm2-monitor -> ../init.d/lvm2-monitor
lrwxrwxrwx. 1 root root 19 Apr 18 08:20 S08ip6tables -> ../init.d/ip6tables
lrwxrwxrwx. 1 root root 18 Apr 18 08:18 S08iptables -> ../init.d/iptables
lrwxrwxrwx. 1 root root 17 Apr 18 08:18 S10network -> ../init.d/network
lrwxrwxrwx. 1 root root 16 Apr 18 08:24 S11auditd -> ../init.d/auditd
lrwxrwxrwx. 1 root root 21 Apr 18 08:14 S11portreserve -> ../init.d/portreserve
lrwxrwxrwx. 1 root root 17 Apr 18 08:20 S12rsyslog -> ../init.d/rsyslog
lrwxrwxrwx. 1 root root 18 Apr 18 08:23 S13cpuspeed -> ../init.d/cpuspeed
lrwxrwxrwx. 1 root root 20 Apr 18 08:21 S13irqbalance -> ../init.d/irqbalance
lrwxrwxrwx. 1 root root 17 Apr 18 08:15 S13rpcbind -> ../init.d/rpcbind
lrwxrwxrwx. 1 root root 19 Apr 18 08:18 S15mdmonitor -> ../init.d/mdmonitor
lrwxrwxrwx. 1 root root 15 Apr 18 08:19 S20kdump -> ../init.d/kdump
lrwxrwxrwx. 1 root root 20 Apr 18 08:14 S22messagebus -> ../init.d/messagebus
lrwxrwxrwx. 1 root root 24 Apr 18 08:20 S23NetworkManager -> ../init.d/NetworkManager
lrwxrwxrwx. 1 root root 17 Apr 18 08:24 S24nfslock -> ../init.d/nfslock
lrwxrwxrwx. 1 root root 17 Apr 18 08:24 S24rpcgssd -> ../init.d/rpcgssd
lrwxrwxrwx. 1 root root 26 Apr 18 08:23 S25blk-availability -> ../init.d/blk-availability
lrwxrwxrwx. 1 root root 14 Apr 18 08:18 S25cups -> ../init.d/cups
lrwxrwxrwx. 1 root root 15 Apr 18 08:18 S25netfs -> ../init.d/netfs
lrwxrwxrwx. 1 root root 15 Apr 18 08:23 S26acpid -> ../init.d/acpid
lrwxrwxrwx. 1 root root 19 Apr 18 08:20 S26haldaemon -> ../init.d/haldaemon
lrwxrwxrwx. 1 root root 19 Apr 18 08:18 S26udev-post -> ../init.d/udev-post
lrwxrwxrwx. 1 root root 16 Apr 18 08:21 S28autofs -> ../init.d/autofs
lrwxrwxrwx. 1 root root 19 Apr 18 08:21 S50bluetooth -> ../init.d/bluetooth
lrwxrwxrwx. 1 root root 14 Apr 18 08:23 S55sshd -> ../init.d/sshd
lrwxrwxrwx. 1 root root 17 Apr 18 08:20 S80postfix -> ../init.d/postfix
lrwxrwxrwx. 1 root root 19 Apr 18 08:16 S82abrt-ccpp -> ../init.d/abrt-ccpp
lrwxrwxrwx. 1 root root 15 Apr 18 08:16 S82abrtd -> ../init.d/abrtd
lrwxrwxrwx. 1 root root 15 Apr 18 08:20 S90crond -> ../init.d/crond
lrwxrwxrwx. 1 root root 13 Apr 18 08:15 S95atd -> ../init.d/atd
lrwxrwxrwx. 1 root root 19 Apr 18 08:22 S99firstboot -> ../init.d/firstboot
lrwxrwxrwx. 1 root root 11 Apr 18 08:18 S99local -> ../rc.local

    但是ls该目录就会发现这里面全是链接文件,指向的路径还是/etc/rc.d/init.d/目录下的脚本。其实脚本只有一份,都是通过链接来进行管理。包括其他级别目录下也是一样。这样的好处也是显而易见的。

    这些链接都是以S和K开头,所有以S开头的,都被传递start参数以启动;所有以K开头的,都被传递stop参数以停止。后面的数字表示启动或关闭的顺序。数字越小表示顺序越靠前。

6. chkconfig命令

    设定开机启动的服务,脚本符号链接的创建可通过chkconfig命令来实现

  • 语法:

    • chkconfig [--level LEVELS] SVC_SCRIPTS on|off

  • 选项:

    • chkconfig --level选项明确指定的级别为on或off, 余下的级别保存原有。默认为2345级别

    • chkconfig --list [SVC_SCRIPTS]:查看服务在对应级别的状态

    • chkconfig --add|--del SVC_SCRIPTS

      • --add: 为某存放在/etc/init.d的服务在对应的/etc/rc.d/rc0-6.d目录添加符号链接

      • --del: 把指定SVC_SCRIPTS的在7个级别符号链接统统删除

7. 启动完成

    服务启动完成后,会启动6个虚拟终端。每个虚拟终端启动之后,会立即通过此终端附加一个应用程序--login,如果默认级别为5,还会启动一个图形虚拟终端,会附加X应用程序。最终便是用户登录了


    END

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。