一、内核

linux系统的组成:内核(kernel)+根文件系统(rootfs)

1、内核的功能

进程管理:task_struct,scheduler(调度)

内存管理:

I/O管理:中断及中断处理

文件系统:

驱动程序

安全相关功能:SElinux,各种加密库


2、内核设计流派

单内核:单一体系

  将所有功能都作成一个整体,都作在内核中

  linux:

    模块化设计:核心 + 外围功能性模块组成

    内核支持动态装卸载模块  .ko文件:kernel object

微内核:内核子系统

  windows,solaris

    每种各功能使用一个单独的子系统实现


3、内核的组成

核心文件:/boot/vmlinuz-VERSION-release

ramdisk:辅助的伪根系统

   CentOS 5:/booot/initrd-VERSION-release       #initrd是用内存模拟磁盘设备

   CentOS 6,7:/boot/initramfs-VERSION-release.img  #initramfs是用内存模拟文件系统

模块文件:/lib/modules/VERSION-release       

   #不区分是否64位系统,模块文件都是在这个位置,模块文件和模块文件版本必须严格一致


二、POST

  Power On Self Test 上电自检

   接通电源,系统将执行一个自我检查的例行程序(cpu执行ROM中的指令),这是BIOS功能的一部分,通常称为POST

   主板在接通电源后,系统首先由POST程序来对CPU、主板、内存、硬盘子系统、显示子系统串并行接口、键盘、CD-ROm光驱等硬件进行检测

当自检完成后,系统转入BIOS的下一步骤:从A驱、C驱或CD-ROM以及网络服务器上寻找操作系统进行启动,然后将控制权交给操作系统。


三、Boot Sequence

   按照bios中的启动次序查找各引导设备,第一个有引导程序的设备即为本次启动要用的设备  

   BIOS "Basic Input Output System",直译过来后中文名称就是"基本输入输出系统"。其实,它是一组固化到计算机内主板上一个ROM芯片上的程序,它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息。 

其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。


四、bootloader

1、MBR

Master Boot Record:主引导记录

  是存在于硬盘的0柱面,0磁头,1扇区里,占512字节的空间(扇区编号从0开始而不是1)

它由三个部分组成:

   Bootloader ( 446 bytes ):引导加载器,程序             446B

   Disk Partition Table ( 64 bytes ):硬盘分区表           64B

   硬盘有效标志(55AA):MBR有效标志位(标识此MBR是否有效,55AA表示有效)  2B


2、bootloader   

   引导加载器,引导程序,安装操作系统时安装在硬盘的MBR中

bootloader的实现:

   Windows :

      NTloader

   Linux:

      LILO:LInux LOader  不能引导位于1024 Cylinder以后的分区中的OS

      GRUB:GRand Uniform Bootloader  

         配置文件:/etc/grub.conf

      GRUB 0.x:Grub Legace

      GRUB 1.x:Grub2


3、GRUB功能

   提供一个菜单,允许用户选择要启动的系统或不同的内核版本,把用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权转交给内核

[root@Node4 boot]# ls grub/
device.map     grub.conf         minix_stage1_5     stage2
e2fs_stage1_5  iso9660_stage1_5  reiserfs_stage1_5  ufs2_stage1_5
fat_stage1_5   jfs_stage1_5      splash.xpm.gz      vstafs_stage1_5
ffs_stage1_5   menu.lst          stage1             xfs_stage1_5

1)选择要启动的内核或系统

    可以隐藏选择界面

2)交互式接口

grub接口:(与grub.conf中定义的一致)

  title:操作系统或内核的版本

     root: 设定内核文件所在的分区为grub的根(把boot目录当作根

            #方便grub查找stage2及kernel文件所在设备分区

     kernel:定义内核文件,后面可附加传递给内核的启动参数,如:root=“真正的根所在的分区” queit 静默模式  不输出内核初始化的信息  

     initrd:指定为内核提供额外驱动等功能的ram disk或ram fs文件

e:进入编辑模式,修改/etc/grub.conf文件

init的级别1的表示方式:1,s,S,single

   单用户模式几乎不会启动任何服务,且不需要用户登录(默认不需要密码使用root登录),但是会执行/etc/rc.d/rc.sysinit文件,如果连/etc/rc.d/rc.sysinit文件也不加载,则需传递emergency(紧急模式)

运行级别的切换:init [0-6]

查看运行级别:

   runlevel

   who -r

3)基于密码保护

   启用内核映像

       编辑/etc/grub.conf文件,将passwd --md5 密码经过md5加密后的字符串,添加至title行之后

   传递参数(进入编辑模式)  

       编辑/etc/grub.conf文件,将passwd --md5 密码经过md5加密后的字符串,添加至title行之前

[root@Note3 ~]# grub-md5-crypt      #使用这个命令生成密码串
Password: 
Retype password: 
$1$va4p5/$6v3ki5EMhiIW4ViPGVk1j/

4、grub.conf配置文件语法

[root@Note3 ~]# 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                       #指定默认启动的内核或0S
timeout=5                   #等待用户选择要启动的内核或OS的时长
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz     #指定背景图片
hiddenmenu                   #隐藏菜单
title CentOS (2.6.32-431.el6.x86_64)     #标题
	root (hd0,0)             #(Device,Part)
	kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=e0c0bc25-62e5-4896-8749-fce761bc3af7 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-431.el6.x86_64.img

Device表示方式:在grub中,统统以hd开头,并紧跟一个数字做各磁盘设备的标记,从0开始编号

Part表示方式:代表分区,从0开始编号

kernel:

   指定内核文件及传递给内核的参数

   参数:ro root=/path/to/DEVICE  quiet  

      #把真正的根只读挂载到这个分区上,放置根文件系统在挂载中因为内核bug而损坏,在挂载完成后,初始化脚本/etc/rc.d/rc.sysinit会以读写方式重新挂载根

initrd:

   文件,通常为cpio归档,并使用gzip压缩,通常以.img作为文件名后缀


5、grub损坏后修复

1)grub配置文件损坏

系统重启后将直接进入grub命令行grub程序是好的,只是配置文件损坏,找不到内核文件,)

在grub命令行下手动指定root,kerner,initrd然后输入boot命令启动即可

wKioL1hYpNTCBfCkAAAwgw8QWdo742.png

kernel这行,后面一定要指定真正的根文件系统在哪个分区上,只有凭借记忆试了


2)当grub程序被损坏

没重启的话可以直接安装grub:

[root@Node4 ~]# dd if=/dev/zero of=/dev/sda bs=150 count=1    #模拟损坏grub
1+0 records in
1+0 records out
150 bytes (150 B) copied, 0.000443918 s, 338 kB/s
[root@Node4 ~]# sync
[root@Node4 ~]# sync

[root@Node4 ~]# grub-install --root-directory=/ /dev/sda     #安装grub
Installation finished. No error reported.
This is the contents of the device map //boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)	/dev/fd0
(hd0)	/dev/sda

重启正常,修复了grub。


重启后就只能使用救援模式下:启动光盘上的微型Linux然后安装grub   #版本要相同

   微型linux会查找磁盘上的/文件系统,找到后会自动挂载到/mnt/sysp_w_picpath、

第一种方式:  

#chroot /mnt/sysp_w_picpath/    #不切换也可以

#grub

grub> root(hd#,#)      #指定根

grub> setup (hd#)      #将grub安装在指定分区上

grub> quit            #退出,系统将会重启,grub就修复完成了


第二种方式:

# chroot /mnt/sysp_w_picpath   #不切换也可以
# grub-install --root-directory=/ /dev/sda  

    --root-diectory指定grub目录要安装的位置和设备,应该要在boot目录的父目录就是/下,它会生成boot/grub目录,但不会生成配置文件grub.conf,需要自己手动添加,此时没有grub的菜单


步骤:

重启后找不到操作系统:

wKiom1hY2XmQXj3WAABDnQxM3Kg388.png

使用系统安装关盘进入救援模式:

找到根后进入shell:

wKioL1hY3drwdL6cAAAk0OpjYPA536.png

进入grub:

wKioL1hY3dqy8f9VAABWBUtAY-4981.png

重启完成。

第二种方式不演示了



五、kernel装载

1、bootloader装载boot所在分区中的内核到内存中

   bootloader只有基本磁盘分区文件系统驱动,只能识别基本分区,所以kernel文件必须放在基本磁盘分区中(因Boot loader大小有限,不能驱动高级文件系统)    #内核和/不在同一个分区

2、initrd (centos5) /initramfs (centos6 ):将内存模拟成根文件系统,读取并装载真正根文件系统所需要的驱动

3、真正根文件系统成功识别后,替换掉临时根文件系统


六、init 

真正根文件系统挂载成功后,init将开始运行初始化用户空间的程序与服务

执行/etc/rc.d/rc.sysinit初始化脚本

SysV风格:Centos5 的init脚本

   串行化初始化:需按照依赖关系顺序初始化进程,A–B–C,前一个进程初始化完成后,才能初始化后一个

Upstart :由ubuntu研发,加速初始化速度

       dbus:可以在前一个进程启动一部分时就开始下一个进程启动

       速度比SysV快

SystemD :Centos7 的init脚本,参考so x的并行初始化初始化过程,速度更快,兼容SysV


2、系统运行级别

linux系统包含 0-6 共7个运行级别

0:关机

1:单用户模式,直接以root用户登陆,不需要密码   #常用于破解root密码

2:多用户模式,不支持NFS文件系统

3:完全多用户模式,文本模式      #不启动图形界面

4:预留级别

5:完全多用户模式,图形shell

6:重启


3、SysV风格的/sbin/init的配置文件 

 /etc/inittab  每一行指定一种操作   

id:3:initdefault: 

id:操作的ID

runlevels:设置在哪些运行级别下执行此操作,不写为所有级别

action:[ACTION_CMD] 动作,指定如何进行操作

   initdefault:设置默认运行级别,无需定义操作

   sysinit:指定系统初始化脚本例如:si::sysinit:/etc/rc.d/rc.sysinit

   wait:等到系统切换到此级别时运行一次

   ctrlaltdel:指定组合键所执行的命令

   respawn:当制定操作进程被关闭后立即再从启一次

process:操作,具体运行的程序


4、init命令的主要任务

[root@Note3 ~]# ls /etc/init/
control-alt-delete.conf  rc.conf              start-ttys.conf
init-system-dbus.conf    rcS.conf             tty.conf
kexec-disable.conf       rcS-emergency.conf   vmware-tools.conf
plymouth-shutdown.conf   rcS-sulogin.conf     vmware-tools-thinprint.conf
prefdm.conf              serial.conf
quit-plymouth.conf       splash-manager.conf

设定默认运行级别

   /etc/inittab,/etc/init/*.conf

指定系统运行的初始化脚本

   /etc/rc.d/rc.sysinit

启动指定级别下要启动的服务,开关闭需要停止的服务

   /etc/rc.d/rcN.d (0-6)    

            #都是链接文件,指向/etc/rc.d/init.d/目录下的同名文件前面加上优先级

      S##    #启动

      K##    #停止

##:表示优先级(0-99),数字越小,优先级越高,先启动的程序应该后关闭


定义组合键CtrlAltDel的动作

初始化字符终端:

   终端:对应的是设备

      /dev/tty#,/dev/ttyS#,/dev/console,/dev/pts/#

      调用:login-->/etc/issue

启动图形终端:

   X-Window,桌面管理器


5、系统初始化脚本

/etc/rc.d/rc.sysinit

设置主机名

打印文本欢迎信息

激活SELinux和udev

激活swap

挂载/etc/fstab定义的本地文件系统

检测根文件系统并对其以读写方式重新挂载

设置系统时钟

装载键盘映射

根据/etc/sysctl.conf设置内核参数

激活RAID和LVM设备

清理操作


七、总结一下系统的初始化流程

wKioL1hY3s-y5psOAADvdatjsB0868.jpg

wKiom1hY3tDyyneOAACM4Jdgvs8091.jpg

  了解操作系统的详细启动流程之后,我们可以实验做一个小型的Linux。


八、

1、chkconfig的使用方法

chkconfig 或 chkconfig --list  #显示所有服务在所有运行级别是否开机启动

chkconfig --add SERVICE_NAME   #将服务添加进chkconfig管理

chkconfig --del SERVICE_NAME    #删除

chkconfig [--level LEVEL] SERVICE_NAME on|off   

                         #指定运行级别下卡机启动或关闭,默认2345级别


只要把脚本放在/etc/rc.d/init.d/目录下并给上执行权限就能狗被service管理:

root@Node5 ~]# cd /etc/rc.d/init.d/
[root@Node5 init.d]# ls
abrt-ccpp         crond           lvm2-monitor  oddjobd      rsyslog
abrtd             cups            mcelogd       portreserve  sandbox
abrt-oops         functions       mdmonitor     postfix      saslauthd
acpid             haldaemon       messagebus    psacct       single
atd               halt            netconsole    quota_nld    smartd
auditd            ip6tables       netfs         rdisc        sshd
autofs            iptables        network       restorecond  sssd
blk-availability  irqbalance      nfs           rngd         svnserve
certmonger        kdump           nfslock       rpcbind      sysstat
cgconfig          killall         ntpd          rpcgssd      udev-post
cgred             libvirt-guests  ntpdate       rpcidmapd    winbind
cpuspeed          lvm2-lvmetad    numad         rpcsvcgssd   ypbind
[root@Node5 init.d]# vim testserver

[root@Node5 init.d]# cat testserver
#!/bin/bash
#
#

start(){
    echo "start success!"
}

stop(){
    echo "stop success!"
}

case $1 in 
start)
    start
    ;;
stop)
    stop
    ;;
*)
    echo "Useage:testserver start|stop"
esac

[root@Node5 init.d]# service testserver start
env: /etc/init.d/testserver: Permission denied
[root@Node5 init.d]# chmod +x testserver 
[root@Node5 init.d]# service testserver start
start success!
[root@Node5 init.d]# service testserver stop
stop success!

需要在服务脚本里添加标记才能被chkconfig命令管理:

#description:          #这行可省略

#chkconfig: 345 88 77

 前一个数字表示启动在345运行级别下,“-”表示所有级别都开机不启动,第二个数字表示优先级,最后一个数字表示关闭优先级

[root@Node5 init.d]# chkconfig --list|grep testserver
[root@Node5 init.d]# chkconfig --add testserver
service testserver does not support chkconfig

[root@Node5 init.d]# vim testserver  
 
[root@Node5 init.d]# cat testserver    #添加表示的desciption和chkconfig 2行
#!/bin/bash
#
# description: Test Server
# chkconfig: 345 88 77


start(){
    echo "start success!"
}

stop(){
    echo "stop success!"
}

case $1 in 
start)
    start
    ;;
stop)
    stop
    ;;
*)
    echo "Useage:testserver start|stop"
esac
[root@Node5 init.d]# chkconfig --add testserver
[root@Node5 init.d]# chkcofig --list|grep testserver
-bash: chkcofig: command not found
[root@Node5 init.d]# chkconfig --list testserver
testserver     	0:off	1:off	2:off	3:on	4:on	5:on	6:off